Mercurial > libavformat.hg
comparison avidec.c @ 262:f174d9c00bce libavformat
* DV handling was streamlined for both muxing/demuxing and
decoding. All muxing/demuxing functionality is now available
in libavformat/dv.[ch].
* dv1394.c and avidec.c were hooked up with general DV demuxer.
* DVAUDIO is dead! Long live pcm_s16le!
* DV audio is now always recognized -- which means we can
now hear all those ducks quaking in pond.dv.
author | romansh |
---|---|
date | Mon, 29 Sep 2003 17:54:07 +0000 |
parents | b0d2d719ae41 |
children | 252946de6d3f |
comparison
equal
deleted
inserted
replaced
261:5f27f90ed496 | 262:f174d9c00bce |
---|---|
16 * License along with this library; if not, write to the Free Software | 16 * License along with this library; if not, write to the Free Software |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 */ | 18 */ |
19 #include "avformat.h" | 19 #include "avformat.h" |
20 #include "avi.h" | 20 #include "avi.h" |
21 #include "dv.h" | |
21 | 22 |
22 //#define DEBUG | 23 //#define DEBUG |
23 | |
24 static const struct AVI1Handler { | |
25 enum CodecID vcid; | |
26 enum CodecID acid; | |
27 uint32_t tag; | |
28 } AVI1Handlers[] = { | |
29 { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 's', 'd') }, | |
30 { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'h', 'd') }, | |
31 { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 's', 'l') }, | |
32 /* This is supposed to be the last one */ | |
33 { CODEC_ID_NONE, CODEC_ID_NONE, 0 }, | |
34 }; | |
35 | 24 |
36 typedef struct AVIIndex { | 25 typedef struct AVIIndex { |
37 unsigned char tag[4]; | 26 unsigned char tag[4]; |
38 unsigned int flags, pos, len; | 27 unsigned int flags, pos, len; |
39 struct AVIIndex *next; | 28 struct AVIIndex *next; |
40 } AVIIndex; | 29 } AVIIndex; |
41 | 30 |
42 typedef struct { | 31 typedef struct { |
43 int64_t riff_end; | 32 int64_t riff_end; |
44 int64_t movi_end; | 33 int64_t movi_end; |
45 int type; | |
46 uint8_t *buf; | |
47 int buf_size; | |
48 int stream_index; | |
49 offset_t movi_list; | 34 offset_t movi_list; |
50 AVIIndex *first, *last; | 35 AVIIndex *first, *last; |
36 void* dv_demux; | |
51 } AVIContext; | 37 } AVIContext; |
52 | 38 |
53 #ifdef DEBUG | 39 #ifdef DEBUG |
54 static void print_tag(const char *str, unsigned int tag, int size) | 40 static void print_tag(const char *str, unsigned int tag, int size) |
55 { | 41 { |
95 | 81 |
96 /* first list tag */ | 82 /* first list tag */ |
97 stream_index = -1; | 83 stream_index = -1; |
98 codec_type = -1; | 84 codec_type = -1; |
99 frame_period = 0; | 85 frame_period = 0; |
100 avi->type = 2; | |
101 avi->buf = av_malloc(1); | |
102 if (!avi->buf) | |
103 return -1; | |
104 avi->buf_size = 1; | |
105 for(;;) { | 86 for(;;) { |
106 if (url_feof(pb)) | 87 if (url_feof(pb)) |
107 goto fail; | 88 goto fail; |
108 tag = get_le32(pb); | 89 tag = get_le32(pb); |
109 size = get_le32(pb); | 90 size = get_le32(pb); |
132 frame_period = get_le32(pb); | 113 frame_period = get_le32(pb); |
133 bit_rate = get_le32(pb) * 8; | 114 bit_rate = get_le32(pb) * 8; |
134 url_fskip(pb, 4 * 4); | 115 url_fskip(pb, 4 * 4); |
135 n = get_le32(pb); | 116 n = get_le32(pb); |
136 for(i=0;i<n;i++) { | 117 for(i=0;i<n;i++) { |
137 st = av_new_stream(s, 0); | 118 st = av_new_stream(s, i); |
138 if (!st) | 119 if (!st) |
139 goto fail; | 120 goto fail; |
140 } | 121 } |
141 url_fskip(pb, size - 7 * 4); | 122 url_fskip(pb, size - 7 * 4); |
142 break; | 123 break; |
143 case MKTAG('s', 't', 'r', 'h'): | 124 case MKTAG('s', 't', 'r', 'h'): |
144 /* stream header */ | 125 /* stream header */ |
145 stream_index++; | 126 stream_index++; |
146 tag1 = get_le32(pb); | 127 tag1 = get_le32(pb); |
128 handler = get_le32(pb); /* codec tag */ | |
147 switch(tag1) { | 129 switch(tag1) { |
148 case MKTAG('i', 'a', 'v', 's'): | 130 case MKTAG('i', 'a', 'v', 's'): |
149 case MKTAG('i', 'v', 'a', 's'): | 131 case MKTAG('i', 'v', 'a', 's'): |
132 /* | |
133 * After some consideration -- I don't think we | |
134 * have to support anything but DV in a type1 AVIs. | |
135 */ | |
150 if (s->nb_streams != 1) | 136 if (s->nb_streams != 1) |
151 goto fail; | 137 goto fail; |
152 avi->type = 1; | 138 |
153 avi->stream_index = 0; | 139 if (handler != MKTAG('d', 'v', 's', 'd') && |
140 handler != MKTAG('d', 'v', 'h', 'd') && | |
141 handler != MKTAG('d', 'v', 's', 'l')) | |
142 goto fail; | |
143 | |
144 avi->dv_demux = dv_init_demux(s, stream_index, stream_index + 1); | |
145 if (!avi->dv_demux) | |
146 goto fail; | |
147 stream_index++; | |
154 case MKTAG('v', 'i', 'd', 's'): | 148 case MKTAG('v', 'i', 'd', 's'): |
155 codec_type = CODEC_TYPE_VIDEO; | 149 codec_type = CODEC_TYPE_VIDEO; |
156 | 150 |
157 if (stream_index >= s->nb_streams) { | 151 if (stream_index >= s->nb_streams) { |
158 url_fskip(pb, size - 4); | 152 url_fskip(pb, size - 8); |
159 break; | 153 break; |
160 } | 154 } |
161 | 155 |
162 st = s->streams[stream_index]; | 156 st = s->streams[stream_index]; |
163 | 157 |
164 handler = get_le32(pb); /* codec tag */ | |
165 get_le32(pb); /* flags */ | 158 get_le32(pb); /* flags */ |
166 get_le16(pb); /* priority */ | 159 get_le16(pb); /* priority */ |
167 get_le16(pb); /* language */ | 160 get_le16(pb); /* language */ |
168 get_le32(pb); /* XXX: initial frame ? */ | 161 get_le32(pb); /* XXX: initial frame ? */ |
169 scale = get_le32(pb); /* scale */ | 162 scale = get_le32(pb); /* scale */ |
184 st->start_time = 0; | 177 st->start_time = 0; |
185 st->duration = (double)nb_frames * | 178 st->duration = (double)nb_frames * |
186 st->codec.frame_rate_base * AV_TIME_BASE / | 179 st->codec.frame_rate_base * AV_TIME_BASE / |
187 st->codec.frame_rate; | 180 st->codec.frame_rate; |
188 | 181 |
189 if (avi->type == 1) { | |
190 AVStream *st; | |
191 | |
192 st = av_new_stream(s, 0); | |
193 if (!st) | |
194 goto fail; | |
195 | |
196 stream_index++; | |
197 | |
198 for (i=0; AVI1Handlers[i].tag != 0; ++i) | |
199 if (AVI1Handlers[i].tag == handler) | |
200 break; | |
201 | |
202 if (AVI1Handlers[i].tag != 0) { | |
203 s->streams[0]->codec.codec_type = CODEC_TYPE_VIDEO; | |
204 s->streams[0]->codec.codec_id = AVI1Handlers[i].vcid; | |
205 s->streams[1]->codec.codec_type = CODEC_TYPE_AUDIO; | |
206 s->streams[1]->codec.codec_id = AVI1Handlers[i].acid; | |
207 } else { | |
208 goto fail; | |
209 } | |
210 } | |
211 | |
212 url_fskip(pb, size - 9 * 4); | 182 url_fskip(pb, size - 9 * 4); |
213 break; | 183 break; |
214 case MKTAG('a', 'u', 'd', 's'): | 184 case MKTAG('a', 'u', 'd', 's'): |
215 { | 185 { |
216 unsigned int length, rate; | 186 unsigned int length, rate; |
217 | 187 |
218 codec_type = CODEC_TYPE_AUDIO; | 188 codec_type = CODEC_TYPE_AUDIO; |
219 | 189 |
220 if (stream_index >= s->nb_streams) { | 190 if (stream_index >= s->nb_streams) { |
221 url_fskip(pb, size - 4); | 191 url_fskip(pb, size - 8); |
222 break; | 192 break; |
223 } | 193 } |
224 st = s->streams[stream_index]; | 194 st = s->streams[stream_index]; |
225 | 195 |
226 get_le32(pb); /* tag */ | |
227 get_le32(pb); /* flags */ | 196 get_le32(pb); /* flags */ |
228 get_le16(pb); /* priority */ | 197 get_le16(pb); /* priority */ |
229 get_le16(pb); /* language */ | 198 get_le16(pb); /* language */ |
230 get_le32(pb); /* initial frame */ | 199 get_le32(pb); /* initial frame */ |
231 get_le32(pb); /* scale */ | 200 get_le32(pb); /* scale */ |
242 goto fail; | 211 goto fail; |
243 } | 212 } |
244 break; | 213 break; |
245 case MKTAG('s', 't', 'r', 'f'): | 214 case MKTAG('s', 't', 'r', 'f'): |
246 /* stream header */ | 215 /* stream header */ |
247 if (stream_index >= s->nb_streams || avi->type == 1) { | 216 if (stream_index >= s->nb_streams || avi->dv_demux) { |
248 url_fskip(pb, size); | 217 url_fskip(pb, size); |
249 } else { | 218 } else { |
250 st = s->streams[stream_index]; | 219 st = s->streams[stream_index]; |
251 switch(codec_type) { | 220 switch(codec_type) { |
252 case CODEC_TYPE_VIDEO: | 221 case CODEC_TYPE_VIDEO: |
303 } | 272 } |
304 end_of_header: | 273 end_of_header: |
305 /* check stream number */ | 274 /* check stream number */ |
306 if (stream_index != s->nb_streams - 1) { | 275 if (stream_index != s->nb_streams - 1) { |
307 fail: | 276 fail: |
308 av_free(avi->buf); | |
309 for(i=0;i<s->nb_streams;i++) { | 277 for(i=0;i<s->nb_streams;i++) { |
310 av_freep(&s->streams[i]->codec.extradata); | 278 av_freep(&s->streams[i]->codec.extradata); |
311 av_freep(&s->streams[i]); | 279 av_freep(&s->streams[i]); |
312 } | 280 } |
313 return -1; | 281 return -1; |
314 } | 282 } |
315 | 283 |
316 return 0; | 284 return 0; |
317 } | 285 } |
318 | 286 |
319 static void __destruct_pkt(struct AVPacket *pkt) | |
320 { | |
321 pkt->data = NULL; pkt->size = 0; | |
322 return; | |
323 } | |
324 | |
325 static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) | 287 static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) |
326 { | 288 { |
327 AVIContext *avi = s->priv_data; | 289 AVIContext *avi = s->priv_data; |
328 ByteIOContext *pb = &s->pb; | 290 ByteIOContext *pb = &s->pb; |
329 int n, d[8], size, i; | 291 int n, d[8], size, i; |
292 void* dstr; | |
330 | 293 |
331 memset(d, -1, sizeof(int)*8); | 294 memset(d, -1, sizeof(int)*8); |
332 | 295 |
333 if (avi->type == 1 && avi->stream_index) { | 296 if (avi->dv_demux) { |
334 /* duplicate DV packet */ | 297 size = dv_get_packet(avi->dv_demux, pkt); |
335 av_init_packet(pkt); | 298 if (size >= 0) |
336 pkt->data = avi->buf; | 299 return size; |
337 pkt->size = avi->buf_size; | |
338 pkt->destruct = __destruct_pkt; | |
339 pkt->stream_index = avi->stream_index; | |
340 avi->stream_index = !avi->stream_index; | |
341 return 0; | |
342 } | 300 } |
343 | 301 |
344 for(i=url_ftell(pb); !url_feof(pb); i++) { | 302 for(i=url_ftell(pb); !url_feof(pb); i++) { |
345 int j; | 303 int j; |
346 | 304 |
347 if (i >= avi->movi_end) { /* Let's see if it's an OpenDML AVI */ | 305 if (i >= avi->movi_end) { /* Let's see if it's an OpenDML AVI */ |
348 uint32_t tag, size, tag2; | 306 uint32_t tag, size, tag2; |
385 (d[2] == 'd' && d[3] == 'b') || | 343 (d[2] == 'd' && d[3] == 'b') || |
386 (d[2] == '_' && d[3] == '_')) | 344 (d[2] == '_' && d[3] == '_')) |
387 && n < s->nb_streams | 345 && n < s->nb_streams |
388 && i + size <= avi->movi_end) { | 346 && i + size <= avi->movi_end) { |
389 | 347 |
390 if (avi->type == 1) { | 348 av_new_packet(pkt, size); |
391 uint8_t *tbuf = av_realloc(avi->buf, size + FF_INPUT_BUFFER_PADDING_SIZE); | |
392 if (!tbuf) | |
393 return -1; | |
394 avi->buf = tbuf; | |
395 avi->buf_size = size; | |
396 av_init_packet(pkt); | |
397 pkt->data = avi->buf; | |
398 pkt->size = avi->buf_size; | |
399 pkt->destruct = __destruct_pkt; | |
400 avi->stream_index = n; | |
401 } else { | |
402 av_new_packet(pkt, size); | |
403 } | |
404 get_buffer(pb, pkt->data, size); | 349 get_buffer(pb, pkt->data, size); |
405 if (size & 1) | 350 if (size & 1) { |
406 get_byte(pb); | 351 get_byte(pb); |
407 pkt->stream_index = n; | 352 size++; |
408 pkt->flags |= PKT_FLAG_KEY; // FIXME: We really should read index for that | 353 } |
409 return 0; | 354 |
355 if (avi->dv_demux) { | |
356 dstr = pkt->destruct; | |
357 size = dv_produce_packet(avi->dv_demux, pkt, | |
358 pkt->data, pkt->size); | |
359 pkt->destruct = dstr; | |
360 } else { | |
361 pkt->stream_index = n; | |
362 pkt->flags |= PKT_FLAG_KEY; // FIXME: We really should read | |
363 // index for that | |
364 } | |
365 return size; | |
410 } | 366 } |
411 } | 367 } |
412 return -1; | 368 return -1; |
413 } | 369 } |
414 | 370 |
415 static int avi_read_close(AVFormatContext *s) | 371 static int avi_read_close(AVFormatContext *s) |
416 { | 372 { |
417 int i; | 373 int i; |
418 AVIContext *avi = s->priv_data; | 374 AVIContext *avi = s->priv_data; |
419 av_free(avi->buf); | |
420 | 375 |
421 for(i=0;i<s->nb_streams;i++) { | 376 for(i=0;i<s->nb_streams;i++) { |
422 AVStream *st = s->streams[i]; | 377 AVStream *st = s->streams[i]; |
423 // av_free(st->priv_data); | 378 // av_free(st->priv_data); |
424 av_free(st->codec.extradata); | 379 av_free(st->codec.extradata); |
425 } | 380 } |
381 | |
382 if (avi->dv_demux) | |
383 av_free(avi->dv_demux); | |
426 | 384 |
427 return 0; | 385 return 0; |
428 } | 386 } |
429 | 387 |
430 static int avi_probe(AVProbeData *p) | 388 static int avi_probe(AVProbeData *p) |