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
if
(roq->
video_stream_index
< 0)
149
return
AVERROR_INVALIDDATA
;
150
/* packet needs to contain both this codebook and next VQ chunk */
151
codebook_offset =
avio_tell
(pb) -
RoQ_CHUNK_PREAMBLE_SIZE
;
152
codebook_size = chunk_size;
153
avio_skip
(pb, codebook_size);
154
if
(
avio_read
(pb, preamble,
RoQ_CHUNK_PREAMBLE_SIZE
) !=
155
RoQ_CHUNK_PREAMBLE_SIZE
)
156
return
AVERROR
(EIO);
157
chunk_size =
AV_RL32
(&preamble[2]) +
RoQ_CHUNK_PREAMBLE_SIZE
* 2 +
158
codebook_size;
159
160
/* rewind */
161
avio_seek
(pb, codebook_offset, SEEK_SET);
162
163
/* load up the packet */
164
ret=
av_get_packet
(pb, pkt, chunk_size);
165
if
(ret != chunk_size)
166
return
AVERROR
(EIO);
167
pkt->
stream_index
= roq->
video_stream_index
;
168
pkt->
pts
= roq->
video_pts
++;
169
170
packet_read = 1;
171
break
;
172
173
case
RoQ_SOUND_MONO
:
174
case
RoQ_SOUND_STEREO
:
175
if
(roq->
audio_stream_index
== -1) {
176
AVStream
*st =
avformat_new_stream
(s, NULL);
177
if
(!st)
178
return
AVERROR
(ENOMEM);
179
avpriv_set_pts_info
(st, 32, 1,
RoQ_AUDIO_SAMPLE_RATE
);
180
roq->
audio_stream_index
= st->
index
;
181
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
182
st->
codec
->
codec_id
=
AV_CODEC_ID_ROQ_DPCM
;
183
st->
codec
->
codec_tag
= 0;
/* no tag */
184
if
(chunk_type ==
RoQ_SOUND_STEREO
) {
185
st->
codec
->
channels
= 2;
186
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_STEREO
;
187
}
else
{
188
st->
codec
->
channels
= 1;
189
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
190
}
191
roq->
audio_channels
= st->
codec
->
channels
;
192
st->
codec
->
sample_rate
=
RoQ_AUDIO_SAMPLE_RATE
;
193
st->
codec
->
bits_per_coded_sample
= 16;
194
st->
codec
->
bit_rate
= st->
codec
->
channels
* st->
codec
->
sample_rate
*
195
st->
codec
->
bits_per_coded_sample
;
196
st->
codec
->
block_align
= st->
codec
->
channels
* st->
codec
->
bits_per_coded_sample
;
197
}
198
case
RoQ_QUAD_VQ
:
199
if
(chunk_type ==
RoQ_QUAD_VQ
) {
200
if
(roq->
video_stream_index
< 0)
201
return
AVERROR_INVALIDDATA
;
202
}
203
204
/* load up the packet */
205
if
(
av_new_packet
(pkt, chunk_size +
RoQ_CHUNK_PREAMBLE_SIZE
))
206
return
AVERROR
(EIO);
207
/* copy over preamble */
208
memcpy(pkt->
data
, preamble,
RoQ_CHUNK_PREAMBLE_SIZE
);
209
210
if
(chunk_type ==
RoQ_QUAD_VQ
) {
211
pkt->
stream_index
= roq->
video_stream_index
;
212
pkt->
pts
= roq->
video_pts
++;
213
}
else
{
214
pkt->
stream_index
= roq->
audio_stream_index
;
215
pkt->
pts
= roq->
audio_frame_count
;
216
roq->
audio_frame_count
+= (chunk_size / roq->
audio_channels
);
217
}
218
219
pkt->
pos
=
avio_tell
(pb);
220
ret =
avio_read
(pb, pkt->
data
+
RoQ_CHUNK_PREAMBLE_SIZE
,
221
chunk_size);
222
if
(ret != chunk_size)
223
ret =
AVERROR
(EIO);
224
225
packet_read = 1;
226
break
;
227
228
default
:
229
av_log
(s,
AV_LOG_ERROR
,
" unknown RoQ chunk (%04X)\n"
, chunk_type);
230
return
AVERROR_INVALIDDATA
;
231
}
232
}
233
234
return
ret
;
235
}
236
237
AVInputFormat
ff_roq_demuxer
= {
238
.
name
=
"roq"
,
239
.long_name =
NULL_IF_CONFIG_SMALL
(
"id RoQ"
),
240
.priv_data_size =
sizeof
(
RoqDemuxContext
),
241
.
read_probe
=
roq_probe
,
242
.
read_header
=
roq_read_header
,
243
.
read_packet
=
roq_read_packet
,
244
};
Generated on Sun Mar 23 2014 23:50:11 for FFmpeg by
1.8.2