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
29 typedef struct AVIStream
{
30 int64_t frame_offset
; /* current frame (video) or byte (audio) counter
31 (used to compute the pts) */
37 int sample_size
; /* audio only data */
40 int cum_len
; /* temporary storage (used during seek) */
42 int prefix
; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
54 DVDemuxContext
* dv_demux
;
57 static int avi_load_index(AVFormatContext
*s
);
60 static void print_tag(const char *str
, unsigned int tag
, int size
)
62 printf("%s: tag=%c%c%c%c size=0x%x\n",
71 static int get_riff(AVIContext
*avi
, ByteIOContext
*pb
)
74 /* check RIFF header */
77 if (tag
!= MKTAG('R', 'I', 'F', 'F'))
79 avi
->riff_end
= get_le32(pb
); /* RIFF chunk size */
80 avi
->riff_end
+= url_ftell(pb
); /* RIFF chunk end */
82 if (tag
!= MKTAG('A', 'V', 'I', ' ') && tag
!= MKTAG('A', 'V', 'I', 'X'))
88 static int avi_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
90 AVIContext
*avi
= s
->priv_data
;
91 ByteIOContext
*pb
= &s
->pb
;
92 uint32_t tag
, tag1
, handler
;
93 int codec_type
, stream_index
, frame_period
, bit_rate
;
94 unsigned int size
, nb_frames
;
98 int xan_video
= 0; /* hack to support Xan A/V */
100 avi
->stream_index
= -1;
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);
167 if(tag1
== MKTAG('i', 'a', 'v', 's') || tag1
== MKTAG('i', 'v', 'a', 's')){
169 * After some consideration -- I don't think we
170 * have to support anything but DV in a type1 AVIs.
172 if (s
->nb_streams
!= 1)
175 if (handler
!= MKTAG('d', 'v', 's', 'd') &&
176 handler
!= MKTAG('d', 'v', 'h', 'd') &&
177 handler
!= MKTAG('d', 'v', 's', 'l'))
180 ast
= s
->streams
[0]->priv_data
;
181 av_freep(&s
->streams
[0]->codec
.extradata
);
182 av_freep(&s
->streams
[0]);
184 avi
->dv_demux
= dv_init_demux(s
);
187 s
->streams
[0]->priv_data
= ast
;
188 url_fskip(pb
, 3 * 4);
189 ast
->scale
= get_le32(pb
);
190 ast
->rate
= get_le32(pb
);
191 stream_index
= s
->nb_streams
- 1;
192 url_fskip(pb
, size
- 7*4);
196 if (stream_index
>= s
->nb_streams
) {
197 url_fskip(pb
, size
- 8);
200 st
= s
->streams
[stream_index
];
202 st
->codec
.stream_codec_tag
= handler
;
204 get_le32(pb
); /* flags */
205 get_le16(pb
); /* priority */
206 get_le16(pb
); /* language */
207 get_le32(pb
); /* initial frame */
208 ast
->scale
= get_le32(pb
);
209 ast
->rate
= get_le32(pb
);
210 if(ast
->scale
&& ast
->rate
){
211 }else if(frame_period
){
213 ast
->scale
= frame_period
;
218 av_set_pts_info(st
, 64, ast
->scale
, ast
->rate
);
220 ast
->start
= get_le32(pb
); /* start */
221 nb_frames
= get_le32(pb
);
224 st
->duration
= av_rescale(nb_frames
, ast
->scale
*(int64_t)AV_TIME_BASE
, ast
->rate
);
225 get_le32(pb
); /* buffer size */
226 get_le32(pb
); /* quality */
227 ast
->sample_size
= get_le32(pb
); /* sample ssize */
228 // av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d\n", ast->rate, ast->scale, ast->start, ast->sample_size);
231 case MKTAG('v', 'i', 'd', 's'):
232 codec_type
= CODEC_TYPE_VIDEO
;
234 ast
->sample_size
= 0;
235 st
->codec
.frame_rate
= ast
->rate
;
236 st
->codec
.frame_rate_base
= ast
->scale
;
238 case MKTAG('a', 'u', 'd', 's'):
239 codec_type
= CODEC_TYPE_AUDIO
;
241 case MKTAG('t', 'x', 't', 's'):
243 codec_type
= CODEC_TYPE_DATA
; //CODEC_TYPE_SUB ? FIXME
245 case MKTAG('p', 'a', 'd', 's'):
246 codec_type
= CODEC_TYPE_UNKNOWN
;
250 av_log(s
, AV_LOG_ERROR
, "unknown stream type %X\n", tag1
);
253 url_fskip(pb
, size
- 12 * 4);
255 case MKTAG('s', 't', 'r', 'f'):
257 if (stream_index
>= s
->nb_streams
|| avi
->dv_demux
) {
260 st
= s
->streams
[stream_index
];
262 case CODEC_TYPE_VIDEO
:
263 get_le32(pb
); /* size */
264 st
->codec
.width
= get_le32(pb
);
265 st
->codec
.height
= get_le32(pb
);
266 get_le16(pb
); /* panes */
267 st
->codec
.bits_per_sample
= get_le16(pb
); /* depth */
269 get_le32(pb
); /* ImageSize */
270 get_le32(pb
); /* XPelsPerMeter */
271 get_le32(pb
); /* YPelsPerMeter */
272 get_le32(pb
); /* ClrUsed */
273 get_le32(pb
); /* ClrImportant */
275 if(size
> 10*4 && size
<(1<<30)){
276 st
->codec
.extradata_size
= size
- 10*4;
277 st
->codec
.extradata
= av_malloc(st
->codec
.extradata_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
278 get_buffer(pb
, st
->codec
.extradata
, st
->codec
.extradata_size
);
281 if(st
->codec
.extradata_size
& 1) //FIXME check if the encoder really did this correctly
284 /* Extract palette from extradata if bpp <= 8 */
285 /* This code assumes that extradata contains only palette */
286 /* This is true for all paletted codecs implemented in ffmpeg */
287 if (st
->codec
.extradata_size
&& (st
->codec
.bits_per_sample
<= 8)) {
288 st
->codec
.palctrl
= av_mallocz(sizeof(AVPaletteControl
));
289 #ifdef WORDS_BIGENDIAN
290 for (i
= 0; i
< FFMIN(st
->codec
.extradata_size
, AVPALETTE_SIZE
)/4; i
++)
291 st
->codec
.palctrl
->palette
[i
] = bswap_32(((uint32_t*)st
->codec
.extradata
)[i
]);
293 memcpy(st
->codec
.palctrl
->palette
, st
->codec
.extradata
,
294 FFMIN(st
->codec
.extradata_size
, AVPALETTE_SIZE
));
296 st
->codec
.palctrl
->palette_changed
= 1;
300 print_tag("video", tag1
, 0);
302 st
->codec
.codec_type
= CODEC_TYPE_VIDEO
;
303 st
->codec
.codec_tag
= tag1
;
304 st
->codec
.codec_id
= codec_get_id(codec_bmp_tags
, tag1
);
305 if (st
->codec
.codec_id
== CODEC_ID_XAN_WC4
)
307 // url_fskip(pb, size - 5 * 4);
309 case CODEC_TYPE_AUDIO
:
310 get_wav_header(pb
, &st
->codec
, size
);
311 if (size
%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
313 /* special case time: To support Xan DPCM, hardcode
314 * the format if Xxan is the video codec */
315 st
->need_parsing
= 1;
316 /* force parsing as several audio frames can be in
319 st
->codec
.codec_id
= CODEC_ID_XAN_DPCM
;
322 st
->codec
.codec_type
= CODEC_TYPE_DATA
;
323 st
->codec
.codec_id
= CODEC_ID_NONE
;
324 st
->codec
.codec_tag
= 0;
338 /* check stream number */
339 if (stream_index
!= s
->nb_streams
- 1) {
341 for(i
=0;i
<s
->nb_streams
;i
++) {
342 av_freep(&s
->streams
[i
]->codec
.extradata
);
343 av_freep(&s
->streams
[i
]);
348 assert(!avi
->index_loaded
);
350 avi
->index_loaded
= 1;
355 static int avi_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
357 AVIContext
*avi
= s
->priv_data
;
358 ByteIOContext
*pb
= &s
->pb
;
364 size
= dv_get_packet(avi
->dv_demux
, pkt
);
369 if(avi
->non_interleaved
){
370 int best_stream_index
;
371 AVStream
*best_st
= NULL
;
373 int64_t best_ts
= INT64_MAX
;
376 for(i
=0; i
<s
->nb_streams
; i
++){
377 AVStream
*st
= s
->streams
[i
];
378 AVIStream
*ast
= st
->priv_data
;
379 int64_t ts
= ast
->frame_offset
;
382 ts
/= ast
->sample_size
;
383 ts
= av_rescale(ts
, AV_TIME_BASE
* (int64_t)st
->time_base
.num
, st
->time_base
.den
);
385 // av_log(NULL, AV_LOG_DEBUG, "%Ld %d/%d %Ld\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset);
389 best_stream_index
= i
;
392 best_ast
= best_st
->priv_data
;
393 best_ts
= av_rescale(best_ts
, best_st
->time_base
.den
, AV_TIME_BASE
* (int64_t)best_st
->time_base
.num
); //FIXME a little ugly
394 if(best_ast
->remaining
)
395 i
= av_index_search_timestamp(best_st
, best_ts
, AVSEEK_FLAG_ANY
| AVSEEK_FLAG_BACKWARD
);
397 i
= av_index_search_timestamp(best_st
, best_ts
, AVSEEK_FLAG_ANY
);
399 // av_log(NULL, AV_LOG_DEBUG, "%d\n", i);
401 int64_t pos
= best_st
->index_entries
[i
].pos
;
402 pos
+= avi
->movi_list
+ best_ast
->packet_size
- best_ast
->remaining
;
403 url_fseek(&s
->pb
, pos
, SEEK_SET
);
404 // av_log(NULL, AV_LOG_DEBUG, "pos=%Ld\n", pos);
406 if(best_ast
->remaining
)
407 avi
->stream_index
= best_stream_index
;
409 avi
->stream_index
= -1;
414 if(avi
->stream_index
>= 0){
415 AVStream
*st
= s
->streams
[ avi
->stream_index
];
416 AVIStream
*ast
= st
->priv_data
;
419 if(ast
->sample_size
== 0)
421 else if(ast
->sample_size
< 32)
422 size
= 64*ast
->sample_size
;
424 size
= ast
->sample_size
;
426 if(size
> ast
->remaining
)
427 size
= ast
->remaining
;
428 av_new_packet(pkt
, size
);
429 get_buffer(pb
, pkt
->data
, size
);
432 dstr
= pkt
->destruct
;
433 size
= dv_produce_packet(avi
->dv_demux
, pkt
,
434 pkt
->data
, pkt
->size
);
435 pkt
->destruct
= dstr
;
436 pkt
->flags
|= PKT_FLAG_KEY
;
438 /* XXX: how to handle B frames in avi ? */
439 pkt
->dts
= ast
->frame_offset
;
440 // pkt->dts += ast->start;
442 pkt
->dts
/= ast
->sample_size
;
443 //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);
444 pkt
->stream_index
= avi
->stream_index
;
446 if (st
->codec
.codec_type
== CODEC_TYPE_VIDEO
) {
447 if(st
->index_entries
){
451 index
= av_index_search_timestamp(st
, pkt
->dts
, 0);
452 e
= &st
->index_entries
[index
];
454 if(e
->timestamp
== ast
->frame_offset
){
455 if (e
->flags
& AVINDEX_KEYFRAME
)
456 pkt
->flags
|= PKT_FLAG_KEY
;
459 /* if no index, better to say that all frames
461 pkt
->flags
|= PKT_FLAG_KEY
;
464 pkt
->flags
|= PKT_FLAG_KEY
;
467 ast
->frame_offset
+= pkt
->size
;
471 ast
->remaining
-= size
;
473 avi
->stream_index
= -1;
484 memset(d
, -1, sizeof(int)*8);
485 for(i
=sync
=url_ftell(pb
); !url_feof(pb
); i
++) {
488 if (i
>= avi
->movi_end
) {
490 url_fskip(pb
, avi
->riff_end
- i
);
491 avi
->riff_end
= avi
->movi_end
= url_filesize(url_fileno(pb
));
500 size
= d
[4] + (d
[5]<<8) + (d
[6]<<16) + (d
[7]<<24);
502 if( d
[2] >= '0' && d
[2] <= '9'
503 && d
[3] >= '0' && d
[3] <= '9'){
504 n
= (d
[2] - '0') * 10 + (d
[3] - '0');
506 n
= 100; //invalid stream id
508 //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);
509 if(i
+ size
> avi
->movi_end
|| d
[0]<0)
513 if( (d
[0] == 'i' && d
[1] == 'x' && n
< s
->nb_streams
)
515 ||(d
[0] == 'J' && d
[1] == 'U' && d
[2] == 'N' && d
[3] == 'K')){
517 //av_log(NULL, AV_LOG_DEBUG, "SKIP\n");
521 if( d
[0] >= '0' && d
[0] <= '9'
522 && d
[1] >= '0' && d
[1] <= '9'){
523 n
= (d
[0] - '0') * 10 + (d
[1] - '0');
525 n
= 100; //invalid stream id
529 if(n
< s
->nb_streams
){
540 if( ((ast
->prefix_count
<5 || sync
+9 > i
) && d
[2]<128 && d
[3]<128) ||
541 d
[2]*256+d
[3] == ast
->prefix
/*||
542 (d[2] == 'd' && d[3] == 'c') ||
543 (d[2] == 'w' && d[3] == 'b')*/) {
545 //av_log(NULL, AV_LOG_DEBUG, "OK\n");
546 if(d
[2]*256+d
[3] == ast
->prefix
)
549 ast
->prefix
= d
[2]*256+d
[3];
550 ast
->prefix_count
= 0;
553 avi
->stream_index
= n
;
554 ast
->packet_size
= size
+ 8;
555 ast
->remaining
= size
;
560 /* palette changed chunk */
561 if ( d
[0] >= '0' && d
[0] <= '9'
562 && d
[1] >= '0' && d
[1] <= '9'
563 && ((d
[2] == 'p' && d
[3] == 'c'))
564 && n
< s
->nb_streams
&& i
+ size
<= avi
->movi_end
) {
567 int first
, clr
, flags
, k
, p
;
571 first
= get_byte(pb
);
573 if(!clr
) /* all 256 colors used */
575 flags
= get_le16(pb
);
577 for (k
= first
; k
< clr
+ first
; k
++) {
583 st
->codec
.palctrl
->palette
[k
] = b
+ (g
<< 8) + (r
<< 16);
585 st
->codec
.palctrl
->palette_changed
= 1;
594 /* XXX: we make the implicit supposition that the position are sorted
596 static int avi_read_idx1(AVFormatContext
*s
, int size
)
598 AVIContext
*avi
= s
->priv_data
;
599 ByteIOContext
*pb
= &s
->pb
;
600 int nb_index_entries
, i
;
603 unsigned int index
, tag
, flags
, pos
, len
;
604 unsigned last_pos
= -1;
606 nb_index_entries
= size
/ 16;
607 if (nb_index_entries
<= 0)
610 /* read the entries and sort them in each stream component */
611 for(i
= 0; i
< nb_index_entries
; i
++) {
613 flags
= get_le32(pb
);
616 #if defined(DEBUG_SEEK)
617 av_log(NULL
, AV_LOG_DEBUG
, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
618 i
, tag
, flags
, pos
, len
);
620 if(i
==0 && pos
> avi
->movi_list
)
621 avi
->movi_list
= 0; //FIXME better check
623 index
= ((tag
& 0xff) - '0') * 10;
624 index
+= ((tag
>> 8) & 0xff) - '0';
625 if (index
>= s
->nb_streams
)
627 st
= s
->streams
[index
];
630 #if defined(DEBUG_SEEK)
631 av_log(NULL
, AV_LOG_DEBUG
, "%d cum_len=%d\n", len
, ast
->cum_len
);
634 avi
->non_interleaved
= 1;
636 av_add_index_entry(st
, pos
, ast
->cum_len
, 0, (flags
&AVIIF_INDEX
) ? AVINDEX_KEYFRAME
: 0);
638 ast
->cum_len
+= len
/ ast
->sample_size
;
646 static int guess_ni_flag(AVFormatContext
*s
){
647 AVIContext
*avi
= s
->priv_data
;
649 int64_t last_start
=0;
650 int64_t first_end
= INT64_MAX
;
652 for(i
=0; i
<s
->nb_streams
; i
++){
653 AVStream
*st
= s
->streams
[i
];
654 AVIStream
*ast
= st
->priv_data
;
655 int n
= st
->nb_index_entries
;
660 if(st
->index_entries
[0].pos
> last_start
)
661 last_start
= st
->index_entries
[0].pos
;
662 if(st
->index_entries
[n
-1].pos
< first_end
)
663 first_end
= st
->index_entries
[n
-1].pos
;
665 return last_start
> first_end
;
668 static int avi_load_index(AVFormatContext
*s
)
670 AVIContext
*avi
= s
->priv_data
;
671 ByteIOContext
*pb
= &s
->pb
;
673 offset_t pos
= url_ftell(pb
);
675 url_fseek(pb
, avi
->movi_end
, SEEK_SET
);
677 printf("movi_end=0x%llx\n", avi
->movi_end
);
685 printf("tag=%c%c%c%c size=0x%x\n",
693 case MKTAG('i', 'd', 'x', '1'):
694 if (avi_read_idx1(s
, size
) < 0)
707 avi
->non_interleaved
|= guess_ni_flag(s
);
708 url_fseek(pb
, pos
, SEEK_SET
);
712 static int avi_read_seek(AVFormatContext
*s
, int stream_index
, int64_t timestamp
, int flags
)
714 AVIContext
*avi
= s
->priv_data
;
719 if (!avi
->index_loaded
) {
720 /* we only load the index on demand */
722 avi
->index_loaded
= 1;
724 assert(stream_index
>= 0);
726 st
= s
->streams
[stream_index
];
727 index
= av_index_search_timestamp(st
, timestamp
, flags
);
731 /* find the position */
732 pos
= st
->index_entries
[index
].pos
;
733 timestamp
= st
->index_entries
[index
].timestamp
;
735 // av_log(NULL, AV_LOG_DEBUG, "XX %Ld %d %Ld\n", timestamp, index, st->index_entries[index].timestamp);
737 for(i
= 0; i
< s
->nb_streams
; i
++) {
738 AVStream
*st2
= s
->streams
[i
];
739 AVIStream
*ast2
= st2
->priv_data
;
744 if (st2
->nb_index_entries
<= 0)
747 // assert(st2->codec.block_align);
748 assert(st2
->time_base
.den
== ast2
->rate
);
749 assert(st2
->time_base
.num
== ast2
->scale
);
750 index
= av_index_search_timestamp(
752 av_rescale(timestamp
, st2
->time_base
.den
*(int64_t)st
->time_base
.num
, st
->time_base
.den
* (int64_t)st2
->time_base
.num
),
753 flags
| AVSEEK_FLAG_BACKWARD
);
757 if(!avi
->non_interleaved
){
758 while(index
>0 && st2
->index_entries
[index
].pos
> pos
)
760 while(index
+1 < st2
->nb_index_entries
&& st2
->index_entries
[index
].pos
< pos
)
764 // av_log(NULL, AV_LOG_DEBUG, "%Ld %d %Ld\n", timestamp, index, st2->index_entries[index].timestamp);
765 /* extract the current frame number */
766 ast2
->frame_offset
= st2
->index_entries
[index
].timestamp
;
767 if(ast2
->sample_size
)
768 ast2
->frame_offset
*=ast2
->sample_size
;
772 dv_flush_audio_packets(avi
->dv_demux
);
774 pos
+= avi
->movi_list
;
775 url_fseek(&s
->pb
, pos
, SEEK_SET
);
776 avi
->stream_index
= -1;
780 static int avi_read_close(AVFormatContext
*s
)
783 AVIContext
*avi
= s
->priv_data
;
785 for(i
=0;i
<s
->nb_streams
;i
++) {
786 AVStream
*st
= s
->streams
[i
];
787 AVIStream
*ast
= st
->priv_data
;
789 av_free(st
->codec
.extradata
);
790 av_free(st
->codec
.palctrl
);
794 av_free(avi
->dv_demux
);
799 static int avi_probe(AVProbeData
*p
)
801 /* check file header */
802 if (p
->buf_size
<= 32)
804 if (p
->buf
[0] == 'R' && p
->buf
[1] == 'I' &&
805 p
->buf
[2] == 'F' && p
->buf
[3] == 'F' &&
806 p
->buf
[8] == 'A' && p
->buf
[9] == 'V' &&
807 p
->buf
[10] == 'I' && p
->buf
[11] == ' ')
808 return AVPROBE_SCORE_MAX
;
813 static AVInputFormat avi_iformat
= {
824 int avidec_init(void)
826 av_register_input_format(&avi_iformat
);