|
|
|
@ -1,6 +1,6 @@ |
|
|
|
|
/*
|
|
|
|
|
* AVI demuxer |
|
|
|
|
* Copyright (c) 2001 Fabrice Bellard. |
|
|
|
|
* Copyright (c) 2001 Fabrice Bellard |
|
|
|
|
* |
|
|
|
|
* This file is part of FFmpeg. |
|
|
|
|
* |
|
|
|
@ -101,7 +101,7 @@ static int get_riff(AVIContext *avi, ByteIOContext *pb) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if(header[7] == 0x19) |
|
|
|
|
av_log(NULL, AV_LOG_INFO, "file has been generated with a totally broken muxer\n"); |
|
|
|
|
av_log(NULL, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n"); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -262,7 +262,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
|
|
|
|
|
switch(tag) { |
|
|
|
|
case MKTAG('L', 'I', 'S', 'T'): |
|
|
|
|
/* ignored, except when start of video packets */ |
|
|
|
|
/* Ignored, except at start of video packets. */ |
|
|
|
|
tag1 = get_le32(pb); |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
print_tag("list", tag1, 0); |
|
|
|
@ -284,7 +284,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
case MKTAG('a', 'm', 'v', 'h'): |
|
|
|
|
amv_file_format=1; |
|
|
|
|
case MKTAG('a', 'v', 'i', 'h'): |
|
|
|
|
/* avi header */ |
|
|
|
|
/* AVI header */ |
|
|
|
|
/* using frame_period is bad idea */ |
|
|
|
|
frame_period = get_le32(pb); |
|
|
|
|
bit_rate = get_le32(pb) * 8; |
|
|
|
@ -330,7 +330,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* After some consideration -- I don't think we |
|
|
|
|
* have to support anything but DV in a type1 AVIs. |
|
|
|
|
* have to support anything but DV in type1 AVIs. |
|
|
|
|
*/ |
|
|
|
|
if (s->nb_streams != 1) |
|
|
|
|
goto fail; |
|
|
|
@ -362,7 +362,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
* else, leave duration alone; timing estimation in utils.c |
|
|
|
|
* will make a guess based on bit rate. |
|
|
|
|
* will make a guess based on bitrate. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
stream_index = s->nb_streams - 1; |
|
|
|
@ -380,7 +380,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
ast->scale = get_le32(pb); |
|
|
|
|
ast->rate = get_le32(pb); |
|
|
|
|
if(!(ast->scale && ast->rate)){ |
|
|
|
|
av_log(s, AV_LOG_WARNING, "Scale/Rate is %u/%u which is invalid. (This file has been generated by broken software)\n", ast->scale, ast->rate); |
|
|
|
|
av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate); |
|
|
|
|
if(frame_period){ |
|
|
|
|
ast->rate = 1000000; |
|
|
|
|
ast->scale = frame_period; |
|
|
|
@ -469,9 +469,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
|
|
|
|
|
get_byte(pb); |
|
|
|
|
|
|
|
|
|
/* Extract palette from extradata if bpp <= 8 */ |
|
|
|
|
/* This code assumes that extradata contains only palette */ |
|
|
|
|
/* This is true for all paletted codecs implemented in ffmpeg */ |
|
|
|
|
/* Extract palette from extradata if bpp <= 8. */ |
|
|
|
|
/* This code assumes that extradata contains only palette. */ |
|
|
|
|
/* This is true for all paletted codecs implemented in FFmpeg. */ |
|
|
|
|
if (st->codec->extradata_size && (st->codec->bits_per_sample <= 8)) { |
|
|
|
|
st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); |
|
|
|
|
#ifdef WORDS_BIGENDIAN |
|
|
|
@ -490,7 +490,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
st->codec->codec_type = CODEC_TYPE_VIDEO; |
|
|
|
|
st->codec->codec_tag = tag1; |
|
|
|
|
st->codec->codec_id = codec_get_id(codec_bmp_tags, tag1); |
|
|
|
|
st->need_parsing = AVSTREAM_PARSE_HEADERS; // this is needed to get the pict type which is needed for generating correct pts
|
|
|
|
|
st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
|
|
|
|
|
// url_fskip(pb, size - 5 * 4);
|
|
|
|
|
break; |
|
|
|
|
case CODEC_TYPE_AUDIO: |
|
|
|
@ -502,9 +502,11 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
if (size%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */ |
|
|
|
|
url_fskip(pb, 1); |
|
|
|
|
/* Force parsing as several audio frames can be in
|
|
|
|
|
* one packet and timestamps refer to packet start*/ |
|
|
|
|
* one packet and timestamps refer to packet start. */ |
|
|
|
|
st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; |
|
|
|
|
/* ADTS header is in extradata, AAC without header must be stored as exact frames, parser not needed and it will fail */ |
|
|
|
|
/* ADTS header is in extradata, AAC without header must be
|
|
|
|
|
* stored as exact frames. Parser not needed and it will |
|
|
|
|
* fail. */ |
|
|
|
|
if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size) |
|
|
|
|
st->need_parsing = AVSTREAM_PARSE_NONE; |
|
|
|
|
/* AVI files with Xan DPCM audio (wrongly) declare PCM
|
|
|
|
@ -581,8 +583,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
if(size > 1000000){ |
|
|
|
|
av_log(s, AV_LOG_ERROR, "well something went wrong during header parsing, " |
|
|
|
|
"ill ignore it and try to continue anyway\n"); |
|
|
|
|
av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, " |
|
|
|
|
"I will ignore it and try to continue anyway.\n"); |
|
|
|
|
avi->movi_list = url_ftell(pb) - 4; |
|
|
|
|
avi->movi_end = url_fsize(pb); |
|
|
|
|
goto end_of_header; |
|
|
|
@ -605,7 +607,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
avi->index_loaded = 1; |
|
|
|
|
avi->non_interleaved |= guess_ni_flag(s); |
|
|
|
|
if(avi->non_interleaved) { |
|
|
|
|
av_log(s, AV_LOG_INFO, "Non interleaved AVI\n"); |
|
|
|
|
av_log(s, AV_LOG_INFO, "non-interleaved AVI\n"); |
|
|
|
|
clean_index(s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -707,7 +709,7 @@ resync: |
|
|
|
|
pkt->destruct = dstr; |
|
|
|
|
pkt->flags |= PKT_FLAG_KEY; |
|
|
|
|
} else { |
|
|
|
|
/* XXX: how to handle B frames in avi ? */ |
|
|
|
|
/* XXX: How to handle B-frames in AVI? */ |
|
|
|
|
pkt->dts = ast->frame_offset; |
|
|
|
|
// pkt->dts += ast->start;
|
|
|
|
|
if(ast->sample_size) |
|
|
|
@ -778,7 +780,7 @@ resync: |
|
|
|
|
&& d[1] >= '0' && d[1] <= '9'){ |
|
|
|
|
n= (d[0] - '0') * 10 + (d[1] - '0'); |
|
|
|
|
}else{ |
|
|
|
|
n= 100; //invalid stream id
|
|
|
|
|
n= 100; //invalid stream ID
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//parse ##dc/##wb
|
|
|
|
@ -802,7 +804,7 @@ resync: |
|
|
|
|
n=1; |
|
|
|
|
st = st1; |
|
|
|
|
ast = ast1; |
|
|
|
|
av_log(s, AV_LOG_WARNING, "Invalid stream+prefix combination, assuming audio\n"); |
|
|
|
|
av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -857,8 +859,8 @@ resync: |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* XXX: we make the implicit supposition that the position are sorted
|
|
|
|
|
for each stream */ |
|
|
|
|
/* XXX: We make the implicit supposition that the positions are sorted
|
|
|
|
|
for each stream. */ |
|
|
|
|
static int avi_read_idx1(AVFormatContext *s, int size) |
|
|
|
|
{ |
|
|
|
|
AVIContext *avi = s->priv_data; |
|
|
|
@ -873,7 +875,7 @@ static int avi_read_idx1(AVFormatContext *s, int size) |
|
|
|
|
if (nb_index_entries <= 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
/* read the entries and sort them in each stream component */ |
|
|
|
|
/* Read the entries and sort them in each stream component. */ |
|
|
|
|
for(i = 0; i < nb_index_entries; i++) { |
|
|
|
|
tag = get_le32(pb); |
|
|
|
|
flags = get_le32(pb); |
|
|
|
@ -1005,7 +1007,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp |
|
|
|
|
assert(stream_index == 0); |
|
|
|
|
|
|
|
|
|
/* Feed the DV video stream version of the timestamp to the */ |
|
|
|
|
/* DV demux so it can synth correct timestamps */ |
|
|
|
|
/* DV demux so it can synthesize correct timestamps. */ |
|
|
|
|
dv_offset_reset(avi->dv_demux, timestamp); |
|
|
|
|
|
|
|
|
|
url_fseek(s->pb, pos, SEEK_SET); |
|
|
|
|