3 * Copyright (c) 2001 Fabrice Bellard.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
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
26 typedef struct AVIIndexEntry
{
29 unsigned int cum_len
; /* sum of all lengths before this packet */
32 typedef struct AVIStream
{
33 AVIIndexEntry
*index_entries
;
35 int index_entries_allocated_size
;
36 int frame_offset
; /* current frame (video) or byte (audio) counter
37 (used to compute the pts) */
40 int sample_size
; /* audio only data */
43 int new_frame_offset
; /* temporary storage (used during seek) */
44 int cum_len
; /* temporary storage (used during seek) */
46 int prefix
; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
56 DVDemuxContext
* dv_demux
;
59 static int avi_load_index(AVFormatContext
*s
);
62 static void print_tag(const char *str
, unsigned int tag
, int size
)
64 printf("%s: tag=%c%c%c%c size=0x%x\n",
73 static int get_riff(AVIContext
*avi
, ByteIOContext
*pb
)
76 /* check RIFF header */
79 if (tag
!= MKTAG('R', 'I', 'F', 'F'))
81 avi
->riff_end
= get_le32(pb
); /* RIFF chunk size */
82 avi
->riff_end
+= url_ftell(pb
); /* RIFF chunk end */
84 if (tag
!= MKTAG('A', 'V', 'I', ' ') && tag
!= MKTAG('A', 'V', 'I', 'X'))
90 static int avi_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
92 AVIContext
*avi
= s
->priv_data
;
93 ByteIOContext
*pb
= &s
->pb
;
94 uint32_t tag
, tag1
, handler
;
95 int codec_type
, stream_index
, frame_period
, bit_rate
, scale
, rate
;
96 unsigned int size
, nb_frames
;
100 int xan_video
= 0; /* hack to support Xan A/V */
102 if (get_riff(avi
, pb
) < 0)
115 print_tag("tag", tag
, size
);
119 case MKTAG('L', 'I', 'S', 'T'):
120 /* ignored, except when start of video packets */
123 print_tag("list", tag1
, 0);
125 if (tag1
== MKTAG('m', 'o', 'v', 'i')) {
126 avi
->movi_list
= url_ftell(pb
) - 4;
127 if(size
) avi
->movi_end
= avi
->movi_list
+ size
;
128 else avi
->movi_end
= url_filesize(url_fileno(pb
));
130 printf("movi end=%Lx\n", avi
->movi_end
);
135 case MKTAG('d', 'm', 'l', 'h'):
137 url_fskip(pb
, size
+ (size
& 1));
139 case MKTAG('a', 'v', 'i', 'h'):
141 /* using frame_period is bad idea */
142 frame_period
= get_le32(pb
);
143 bit_rate
= get_le32(pb
) * 8;
144 url_fskip(pb
, 4 * 4);
148 st
= av_new_stream(s
, i
);
152 ast
= av_mallocz(sizeof(AVIStream
));
157 url_fskip(pb
, size
- 7 * 4);
159 case MKTAG('s', 't', 'r', 'h'):
163 handler
= get_le32(pb
); /* codec tag */
165 print_tag("strh", tag1
, -1);
168 case MKTAG('i', 'a', 'v', 's'):
169 case MKTAG('i', 'v', 'a', 's'):
171 * After some consideration -- I don't think we
172 * have to support anything but DV in a type1 AVIs.
174 if (s
->nb_streams
!= 1)
177 if (handler
!= MKTAG('d', 'v', 's', 'd') &&
178 handler
!= MKTAG('d', 'v', 'h', 'd') &&
179 handler
!= MKTAG('d', 'v', 's', 'l'))
182 av_freep(&s
->streams
[0]->codec
.extradata
);
183 av_freep(&s
->streams
[0]);
185 avi
->dv_demux
= dv_init_demux(s
);
188 stream_index
= s
->nb_streams
- 1;
189 url_fskip(pb
, size
- 8);
191 case MKTAG('v', 'i', 'd', 's'):
192 codec_type
= CODEC_TYPE_VIDEO
;
194 if (stream_index
>= s
->nb_streams
) {
195 url_fskip(pb
, size
- 8);
199 st
= s
->streams
[stream_index
];
201 st
->codec
.stream_codec_tag
= handler
;
203 get_le32(pb
); /* flags */
204 get_le16(pb
); /* priority */
205 get_le16(pb
); /* language */
206 get_le32(pb
); /* XXX: initial frame ? */
207 scale
= get_le32(pb
); /* scale */
208 rate
= get_le32(pb
); /* rate */
211 }else if(frame_period
){
213 scale
= frame_period
;
220 av_set_pts_info(st
, 64, scale
, rate
);
221 st
->codec
.frame_rate
= rate
;
222 st
->codec
.frame_rate_base
= scale
;
223 get_le32(pb
); /* start */
224 nb_frames
= get_le32(pb
);
226 st
->duration
= av_rescale(nb_frames
,
227 st
->codec
.frame_rate_base
* AV_TIME_BASE
,
228 st
->codec
.frame_rate
);
229 url_fskip(pb
, size
- 9 * 4);
231 case MKTAG('a', 'u', 'd', 's'):
235 codec_type
= CODEC_TYPE_AUDIO
;
237 if (stream_index
>= s
->nb_streams
) {
238 url_fskip(pb
, size
- 8);
241 st
= s
->streams
[stream_index
];
244 get_le32(pb
); /* flags */
245 get_le16(pb
); /* priority */
246 get_le16(pb
); /* language */
247 get_le32(pb
); /* initial frame */
248 ast
->scale
= get_le32(pb
); /* scale */
249 ast
->rate
= get_le32(pb
);
250 av_set_pts_info(st
, 64, ast
->scale
, ast
->rate
);
251 ast
->start
= get_le32(pb
); /* start */
252 length
= get_le32(pb
); /* length, in samples or bytes */
253 get_le32(pb
); /* buffer size */
254 get_le32(pb
); /* quality */
255 ast
->sample_size
= get_le32(pb
); /* sample ssize */
256 //av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d\n", ast->scale, ast->rate, ast->sample_size, ast->start);
259 st
->duration
= (int64_t)length
* AV_TIME_BASE
/ ast
->rate
;
260 url_fskip(pb
, size
- 12 * 4);
263 case MKTAG('t', 'x', 't', 's'):
265 codec_type
= CODEC_TYPE_DATA
; //CODEC_TYPE_SUB ? FIXME
266 url_fskip(pb
, size
- 8);
272 case MKTAG('s', 't', 'r', 'f'):
274 if (stream_index
>= s
->nb_streams
|| avi
->dv_demux
) {
277 st
= s
->streams
[stream_index
];
279 case CODEC_TYPE_VIDEO
:
280 get_le32(pb
); /* size */
281 st
->codec
.width
= get_le32(pb
);
282 st
->codec
.height
= get_le32(pb
);
283 get_le16(pb
); /* panes */
284 st
->codec
.bits_per_sample
= get_le16(pb
); /* depth */
286 get_le32(pb
); /* ImageSize */
287 get_le32(pb
); /* XPelsPerMeter */
288 get_le32(pb
); /* YPelsPerMeter */
289 get_le32(pb
); /* ClrUsed */
290 get_le32(pb
); /* ClrImportant */
292 st
->codec
.extradata_size
= size
- 10*4;
293 st
->codec
.extradata
= av_malloc(st
->codec
.extradata_size
);
294 get_buffer(pb
, st
->codec
.extradata
, st
->codec
.extradata_size
);
296 if(st
->codec
.extradata_size
& 1) //FIXME check if the encoder really did this correctly
299 /* Extract palette from extradata if bpp <= 8 */
300 /* This code assumes that extradata contains only palette */
301 /* This is true for all paletted codecs implemented in ffmpeg */
302 if (st
->codec
.extradata_size
&& (st
->codec
.bits_per_sample
<= 8)) {
303 st
->codec
.palctrl
= av_mallocz(sizeof(AVPaletteControl
));
304 #ifdef WORDS_BIGENDIAN
305 for (i
= 0; i
< FFMIN(st
->codec
.extradata_size
, AVPALETTE_SIZE
)/4; i
++)
306 st
->codec
.palctrl
->palette
[i
] = bswap_32(((uint32_t*)st
->codec
.extradata
)[i
]);
308 memcpy(st
->codec
.palctrl
->palette
, st
->codec
.extradata
,
309 FFMIN(st
->codec
.extradata_size
, AVPALETTE_SIZE
));
311 st
->codec
.palctrl
->palette_changed
= 1;
315 print_tag("video", tag1
, 0);
317 st
->codec
.codec_type
= CODEC_TYPE_VIDEO
;
318 st
->codec
.codec_tag
= tag1
;
319 st
->codec
.codec_id
= codec_get_id(codec_bmp_tags
, tag1
);
320 if (st
->codec
.codec_id
== CODEC_ID_XAN_WC4
)
322 // url_fskip(pb, size - 5 * 4);
324 case CODEC_TYPE_AUDIO
:
325 get_wav_header(pb
, &st
->codec
, size
);
326 if (size
%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
328 /* special case time: To support Xan DPCM, hardcode
329 * the format if Xxan is the video codec */
330 st
->need_parsing
= 1;
331 /* force parsing as several audio frames can be in
334 st
->codec
.codec_id
= CODEC_ID_XAN_DPCM
;
337 st
->codec
.codec_type
= CODEC_TYPE_DATA
;
338 st
->codec
.codec_id
= CODEC_ID_NONE
;
339 st
->codec
.codec_tag
= 0;
353 /* check stream number */
354 if (stream_index
!= s
->nb_streams
- 1) {
356 for(i
=0;i
<s
->nb_streams
;i
++) {
357 av_freep(&s
->streams
[i
]->codec
.extradata
);
358 av_freep(&s
->streams
[i
]);
363 assert(!avi
->index_loaded
);
365 avi
->index_loaded
= 1;
370 static int avi_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
372 AVIContext
*avi
= s
->priv_data
;
373 ByteIOContext
*pb
= &s
->pb
;
378 memset(d
, -1, sizeof(int)*8);
381 size
= dv_get_packet(avi
->dv_demux
, pkt
);
386 for(i
=url_ftell(pb
); !url_feof(pb
); i
++) {
389 if (i
>= avi
->movi_end
) {
391 url_fskip(pb
, avi
->riff_end
- i
);
392 avi
->riff_end
= avi
->movi_end
= url_filesize(url_fileno(pb
));
401 size
= d
[4] + (d
[5]<<8) + (d
[6]<<16) + (d
[7]<<24);
403 if( d
[2] >= '0' && d
[2] <= '9'
404 && d
[3] >= '0' && d
[3] <= '9'){
405 n
= (d
[2] - '0') * 10 + (d
[3] - '0');
407 n
= 100; //invalid stream id
409 //av_log(NULL, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %lld %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
410 if(i
+ size
> avi
->movi_end
|| d
[0]<0)
414 if( (d
[0] == 'i' && d
[1] == 'x' && n
< s
->nb_streams
)
416 ||(d
[0] == 'J' && d
[1] == 'U' && d
[2] == 'N' && d
[3] == 'K')){
419 memset(d
, -1, sizeof(int)*8);
420 //av_log(NULL, AV_LOG_DEBUG, "SKIP\n");
424 if( d
[0] >= '0' && d
[0] <= '9'
425 && d
[1] >= '0' && d
[1] <= '9'){
426 n
= (d
[0] - '0') * 10 + (d
[1] - '0');
428 n
= 100; //invalid stream id
432 if(n
< s
->nb_streams
){
438 if( (ast
->prefix_count
<5 && d
[2]<128 && d
[3]<128) ||
439 d
[2]*256+d
[3] == ast
->prefix
/*||
440 (d[2] == 'd' && d[3] == 'c') ||
441 (d[2] == 'w' && d[3] == 'b')*/) {
443 //av_log(NULL, AV_LOG_DEBUG, "OK\n");
444 if(d
[2]*256+d
[3] == ast
->prefix
)
447 ast
->prefix
= d
[2]*256+d
[3];
448 ast
->prefix_count
= 0;
451 av_new_packet(pkt
, size
);
452 get_buffer(pb
, pkt
->data
, size
);
459 dstr
= pkt
->destruct
;
460 size
= dv_produce_packet(avi
->dv_demux
, pkt
,
461 pkt
->data
, pkt
->size
);
462 pkt
->destruct
= dstr
;
463 pkt
->flags
|= PKT_FLAG_KEY
;
465 /* XXX: how to handle B frames in avi ? */
466 pkt
->dts
= ast
->frame_offset
;
467 // pkt->dts += ast->start;
469 pkt
->dts
/= ast
->sample_size
;
470 //av_log(NULL, AV_LOG_DEBUG, "dts:%Ld offset:%d %d/%d smpl_siz:%d base:%d st:%d size:%d\n", pkt->dts, ast->frame_offset, ast->scale, ast->rate, ast->sample_size, AV_TIME_BASE, n, size);
471 pkt
->stream_index
= n
;
472 /* FIXME: We really should read index for that */
473 if (st
->codec
.codec_type
== CODEC_TYPE_VIDEO
) {
474 if (ast
->frame_offset
< ast
->nb_index_entries
) {
475 if (ast
->index_entries
[ast
->frame_offset
].flags
& AVIIF_INDEX
)
476 pkt
->flags
|= PKT_FLAG_KEY
;
478 /* if no index, better to say that all frames
480 pkt
->flags
|= PKT_FLAG_KEY
;
483 pkt
->flags
|= PKT_FLAG_KEY
;
486 ast
->frame_offset
+= pkt
->size
;
493 /* palette changed chunk */
494 if ( d
[0] >= '0' && d
[0] <= '9'
495 && d
[1] >= '0' && d
[1] <= '9'
496 && ((d
[2] == 'p' && d
[3] == 'c'))
497 && n
< s
->nb_streams
&& i
+ size
<= avi
->movi_end
) {
500 int first
, clr
, flags
, k
, p
;
504 first
= get_byte(pb
);
506 flags
= get_le16(pb
);
508 for (k
= first
; k
< clr
+ first
; k
++) {
514 st
->codec
.palctrl
->palette
[k
] = b
+ (g
<< 8) + (r
<< 16);
516 st
->codec
.palctrl
->palette_changed
= 1;
524 /* XXX: we make the implicit supposition that the position are sorted
526 static int avi_read_idx1(AVFormatContext
*s
, int size
)
528 ByteIOContext
*pb
= &s
->pb
;
529 int nb_index_entries
, i
;
532 AVIIndexEntry
*ie
, *entries
;
533 unsigned int index
, tag
, flags
, pos
, len
;
535 nb_index_entries
= size
/ 16;
536 if (nb_index_entries
<= 0)
539 /* read the entries and sort them in each stream component */
540 for(i
= 0; i
< nb_index_entries
; i
++) {
542 flags
= get_le32(pb
);
545 #if defined(DEBUG_SEEK) && 0
546 printf("%d: tag=0x%x flags=0x%x pos=0x%x len=%d\n",
547 i
, tag
, flags
, pos
, len
);
549 index
= ((tag
& 0xff) - '0') * 10;
550 index
+= ((tag
>> 8) & 0xff) - '0';
551 if (index
>= s
->nb_streams
)
553 st
= s
->streams
[index
];
556 entries
= av_fast_realloc(ast
->index_entries
,
557 &ast
->index_entries_allocated_size
,
558 (ast
->nb_index_entries
+ 1) *
559 sizeof(AVIIndexEntry
));
561 ast
->index_entries
= entries
;
562 ie
= &entries
[ast
->nb_index_entries
++];
565 ie
->cum_len
= ast
->cum_len
;
572 static int avi_load_index(AVFormatContext
*s
)
574 AVIContext
*avi
= s
->priv_data
;
575 ByteIOContext
*pb
= &s
->pb
;
577 offset_t pos
= url_ftell(pb
);
579 url_fseek(pb
, avi
->movi_end
, SEEK_SET
);
581 printf("movi_end=0x%llx\n", avi
->movi_end
);
589 printf("tag=%c%c%c%c size=0x%x\n",
597 case MKTAG('i', 'd', 'x', '1'):
598 if (avi_read_idx1(s
, size
) < 0)
611 url_fseek(pb
, pos
, SEEK_SET
);
615 /* return the index entry whose position is immediately >= 'wanted_pos' */
616 static int locate_frame_in_index(AVIIndexEntry
*entries
,
617 int nb_entries
, int wanted_pos
)
625 pos
= entries
[m
].pos
;
626 if (pos
== wanted_pos
)
628 else if (pos
> wanted_pos
) {
641 static int avi_read_seek(AVFormatContext
*s
, int stream_index
, int64_t timestamp
)
643 AVIContext
*avi
= s
->priv_data
;
649 if (!avi
->index_loaded
) {
650 /* we only load the index on demand */
652 avi
->index_loaded
= 1;
654 if (stream_index
< 0) {
655 for(i
= 0; i
< s
->nb_streams
; i
++) {
657 if (st
->codec
.codec_type
== CODEC_TYPE_VIDEO
)
665 st
= s
->streams
[stream_index
];
666 if (st
->codec
.codec_type
!= CODEC_TYPE_VIDEO
)
669 /* compute the frame number */
670 frame_number
= timestamp
;
672 printf("timestamp=%0.3f nb_indexes=%d frame_number=%d\n",
673 (double)timestamp
/ AV_TIME_BASE
,
674 ast
->nb_index_entries
, frame_number
);
676 /* find a closest key frame before */
677 if (frame_number
>= ast
->nb_index_entries
)
679 while (frame_number
>= 0 &&
680 !(ast
->index_entries
[frame_number
].flags
& AVIIF_INDEX
))
682 if (frame_number
< 0)
684 ast
->new_frame_offset
= frame_number
;
686 /* find the position */
687 pos
= ast
->index_entries
[frame_number
].pos
;
690 printf("key_frame_number=%d pos=0x%llx\n",
694 /* update the frame counters for all the other stream by looking
695 at the positions just after the one found */
696 for(i
= 0; i
< s
->nb_streams
; i
++) {
698 if (i
!= stream_index
) {
701 if (ast
->nb_index_entries
<= 0)
703 j
= locate_frame_in_index(ast
->index_entries
,
704 ast
->nb_index_entries
,
707 if ((j
+ 1) < ast
->nb_index_entries
)
709 /* extract the current frame number */
710 if (ast
->sample_size
==0)
711 ast
->new_frame_offset
= j
;
713 ast
->new_frame_offset
= ast
->index_entries
[j
].cum_len
;
717 /* everything is OK now. We can update the frame offsets */
718 for(i
= 0; i
< s
->nb_streams
; i
++) {
721 ast
->frame_offset
= ast
->new_frame_offset
;
723 printf("%d: frame_offset=%d\n", i
,
728 pos
+= avi
->movi_list
;
729 url_fseek(&s
->pb
, pos
, SEEK_SET
);
733 static int avi_read_close(AVFormatContext
*s
)
736 AVIContext
*avi
= s
->priv_data
;
738 for(i
=0;i
<s
->nb_streams
;i
++) {
739 AVStream
*st
= s
->streams
[i
];
740 AVIStream
*ast
= st
->priv_data
;
742 av_free(ast
->index_entries
);
745 av_free(st
->codec
.extradata
);
746 av_free(st
->codec
.palctrl
);
750 av_free(avi
->dv_demux
);
755 static int avi_probe(AVProbeData
*p
)
757 /* check file header */
758 if (p
->buf_size
<= 32)
760 if (p
->buf
[0] == 'R' && p
->buf
[1] == 'I' &&
761 p
->buf
[2] == 'F' && p
->buf
[3] == 'F' &&
762 p
->buf
[8] == 'A' && p
->buf
[9] == 'V' &&
763 p
->buf
[10] == 'I' && p
->buf
[11] == ' ')
764 return AVPROBE_SCORE_MAX
;
769 static AVInputFormat avi_iformat
= {
780 int avidec_init(void)
782 av_register_input_format(&avi_iformat
);