FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
idroqdec.c
Go to the documentation of this file.
1
/*
2
* id RoQ (.roq) File Demuxer
3
* Copyright (c) 2003 The ffmpeg Project
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
/**
23
* @file
24
* id RoQ format file demuxer
25
* by Mike Melanson (melanson@pcisys.net)
26
* for more information on the .roq file format, visit:
27
* http://www.csse.monash.edu.au/~timf/
28
*/
29
30
#include "
libavutil/channel_layout.h
"
31
#include "
libavutil/intreadwrite.h
"
32
#include "
avformat.h
"
33
#include "
internal.h
"
34
#include "
avio_internal.h
"
35
36
#define RoQ_MAGIC_NUMBER 0x1084
37
#define RoQ_CHUNK_PREAMBLE_SIZE 8
38
#define RoQ_AUDIO_SAMPLE_RATE 22050
39
#define RoQ_CHUNKS_TO_SCAN 30
40
41
#define RoQ_INFO 0x1001
42
#define RoQ_QUAD_CODEBOOK 0x1002
43
#define RoQ_QUAD_VQ 0x1011
44
#define RoQ_SOUND_MONO 0x1020
45
#define RoQ_SOUND_STEREO 0x1021
46
47
typedef
struct
RoqDemuxContext
{
48
49
int
frame_rate
;
50
int
width
;
51
int
height
;
52
int
audio_channels
;
53
54
int
video_stream_index
;
55
int
audio_stream_index
;
56
57
int64_t
video_pts
;
58
unsigned
int
audio_frame_count
;
59
60
}
RoqDemuxContext
;
61
62
static
int
roq_probe
(
AVProbeData
*p)
63
{
64
if
((
AV_RL16
(&p->
buf
[0]) !=
RoQ_MAGIC_NUMBER
) ||
65
(
AV_RL32
(&p->
buf
[2]) != 0xFFFFFFFF))
66
return
0;
67
68
return
AVPROBE_SCORE_MAX
;
69
}
70
71
static
int
roq_read_header
(
AVFormatContext
*
s
)
72
{
73
RoqDemuxContext
*roq = s->
priv_data
;
74
AVIOContext
*pb = s->
pb
;
75
unsigned
char
preamble[
RoQ_CHUNK_PREAMBLE_SIZE
];
76
77
/* get the main header */
78
if
(
avio_read
(pb, preamble,
RoQ_CHUNK_PREAMBLE_SIZE
) !=
79
RoQ_CHUNK_PREAMBLE_SIZE
)
80
return
AVERROR
(EIO);
81
roq->
frame_rate
=
AV_RL16
(&preamble[6]);
82
83
/* init private context parameters */
84
roq->
width
= roq->
height
= roq->
audio_channels
= roq->
video_pts
=
85
roq->
audio_frame_count
= 0;
86
roq->
audio_stream_index
= -1;
87
roq->
video_stream_index
= -1;
88
89
s->
ctx_flags
|=
AVFMTCTX_NOHEADER
;
90
91
return
0;
92
}
93
94
static
int
roq_read_packet
(
AVFormatContext
*
s
,
95
AVPacket
*
pkt
)
96
{
97
RoqDemuxContext
*roq = s->
priv_data
;
98
AVIOContext
*pb = s->
pb
;
99
int
ret
= 0;
100
unsigned
int
chunk_size;
101
unsigned
int
chunk_type;
102
unsigned
int
codebook_size;
103
unsigned
char
preamble[
RoQ_CHUNK_PREAMBLE_SIZE
];
104
int
packet_read = 0;
105
int64_t codebook_offset;
106
107
while
(!packet_read) {
108
109
if
(
url_feof
(s->
pb
))
110
return
AVERROR
(EIO);
111
112
/* get the next chunk preamble */
113
if
((ret =
avio_read
(pb, preamble,
RoQ_CHUNK_PREAMBLE_SIZE
)) !=
114
RoQ_CHUNK_PREAMBLE_SIZE
)
115
return
AVERROR
(EIO);
116
117
chunk_type =
AV_RL16
(&preamble[0]);
118
chunk_size =
AV_RL32
(&preamble[2]);
119
if
(chunk_size > INT_MAX)
120
return
AVERROR_INVALIDDATA
;
121
122
chunk_size =
ffio_limit
(pb, chunk_size);
123
124
switch
(chunk_type) {
125
126
case
RoQ_INFO
:
127
if
(roq->
video_stream_index
== -1) {
128
AVStream
*st =
avformat_new_stream
(s, NULL);
129
if
(!st)
130
return
AVERROR
(ENOMEM);
131
avpriv_set_pts_info
(st, 63, 1, roq->
frame_rate
);
132
roq->
video_stream_index
= st->
index
;
133
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
134
st->
codec
->
codec_id
=
AV_CODEC_ID_ROQ
;
135
st->
codec
->
codec_tag
= 0;
/* no fourcc */
136
137
if
(
avio_read
(pb, preamble,
RoQ_CHUNK_PREAMBLE_SIZE
) !=
RoQ_CHUNK_PREAMBLE_SIZE
)
138
return
AVERROR
(EIO);
139
st->
codec
->
width
= roq->
width
=
AV_RL16
(preamble);
140
st->
codec
->
height
= roq->
height
=
AV_RL16
(preamble + 2);
141
break
;
142
}
143
/* don't care about this chunk anymore */
144
avio_skip
(pb,
RoQ_CHUNK_PREAMBLE_SIZE
);
145
break
;
146
147
case
RoQ_QUAD_CODEBOOK
:
148
/* packet needs to contain both this codebook and next VQ chunk */
149
codebook_offset =
avio_tell
(pb) -
RoQ_CHUNK_PREAMBLE_SIZE
;
150
codebook_size = chunk_size;
151
avio_skip
(pb, codebook_size);
152
if
(
avio_read
(pb, preamble,
RoQ_CHUNK_PREAMBLE_SIZE
) !=
153
RoQ_CHUNK_PREAMBLE_SIZE
)
154
return
AVERROR
(EIO);
155
chunk_size =
AV_RL32
(&preamble[2]) +
RoQ_CHUNK_PREAMBLE_SIZE
* 2 +
156
codebook_size;
157
158
/* rewind */
159
avio_seek
(pb, codebook_offset, SEEK_SET);
160
161
/* load up the packet */
162
ret=
av_get_packet
(pb, pkt, chunk_size);
163
if
(ret != chunk_size)
164
return
AVERROR
(EIO);
165
pkt->
stream_index
= roq->
video_stream_index
;
166
pkt->
pts
= roq->
video_pts
++;
167
168
packet_read = 1;
169
break
;
170
171
case
RoQ_SOUND_MONO
:
172
case
RoQ_SOUND_STEREO
:
173
if
(roq->
audio_stream_index
== -1) {
174
AVStream
*st =
avformat_new_stream
(s, NULL);
175
if
(!st)
176
return
AVERROR
(ENOMEM);
177
avpriv_set_pts_info
(st, 32, 1,
RoQ_AUDIO_SAMPLE_RATE
);
178
roq->
audio_stream_index
= st->
index
;
179
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
180
st->
codec
->
codec_id
=
AV_CODEC_ID_ROQ_DPCM
;
181
st->
codec
->
codec_tag
= 0;
/* no tag */
182
if
(chunk_type ==
RoQ_SOUND_STEREO
) {
183
st->
codec
->
channels
= 2;
184
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_STEREO
;
185
}
else
{
186
st->
codec
->
channels
= 1;
187
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
188
}
189
roq->
audio_channels
= st->
codec
->
channels
;
190
st->
codec
->
sample_rate
=
RoQ_AUDIO_SAMPLE_RATE
;
191
st->
codec
->
bits_per_coded_sample
= 16;
192
st->
codec
->
bit_rate
= st->
codec
->
channels
* st->
codec
->
sample_rate
*
193
st->
codec
->
bits_per_coded_sample
;
194
st->
codec
->
block_align
= st->
codec
->
channels
* st->
codec
->
bits_per_coded_sample
;
195
}
196
case
RoQ_QUAD_VQ
:
197
/* load up the packet */
198
if
(
av_new_packet
(pkt, chunk_size +
RoQ_CHUNK_PREAMBLE_SIZE
))
199
return
AVERROR
(EIO);
200
/* copy over preamble */
201
memcpy(pkt->
data
, preamble,
RoQ_CHUNK_PREAMBLE_SIZE
);
202
203
if
(chunk_type ==
RoQ_QUAD_VQ
) {
204
pkt->
stream_index
= roq->
video_stream_index
;
205
pkt->
pts
= roq->
video_pts
++;
206
}
else
{
207
pkt->
stream_index
= roq->
audio_stream_index
;
208
pkt->
pts
= roq->
audio_frame_count
;
209
roq->
audio_frame_count
+= (chunk_size / roq->
audio_channels
);
210
}
211
212
pkt->
pos
=
avio_tell
(pb);
213
ret =
avio_read
(pb, pkt->
data
+
RoQ_CHUNK_PREAMBLE_SIZE
,
214
chunk_size);
215
if
(ret != chunk_size)
216
ret =
AVERROR
(EIO);
217
218
packet_read = 1;
219
break
;
220
221
default
:
222
av_log
(s,
AV_LOG_ERROR
,
" unknown RoQ chunk (%04X)\n"
, chunk_type);
223
return
AVERROR_INVALIDDATA
;
224
}
225
}
226
227
return
ret
;
228
}
229
230
AVInputFormat
ff_roq_demuxer
= {
231
.
name
=
"roq"
,
232
.long_name =
NULL_IF_CONFIG_SMALL
(
"id RoQ"
),
233
.priv_data_size =
sizeof
(
RoqDemuxContext
),
234
.
read_probe
=
roq_probe
,
235
.
read_header
=
roq_read_header
,
236
.
read_packet
=
roq_read_packet
,
237
};
Generated on Wed Jul 10 2013 23:48:12 for FFmpeg by
1.8.2