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
(
avio_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 Sep 14 2014 18:56:12 for FFmpeg by
1.8.2