X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Favidec.c;h=659bfa7b6d60e557d5457d069009db65532e04b4;hb=ce70f28a1732c74a9cd7fec2d56178750bd6e457;hp=e7202de8d4d2ec1881864a7ef4a2527df4366995;hpb=90411b333d6b6bb69d8937117b9250785730dc53;p=ffmpeg diff --git a/libavformat/avidec.c b/libavformat/avidec.c index e7202de8d4d..659bfa7b6d6 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -31,6 +31,7 @@ #include "avi.h" #include "dv.h" #include "internal.h" +#include "isom.h" #include "riff.h" #undef NDEBUG @@ -42,6 +43,7 @@ typedef struct AVIStream { int remaining; int packet_size; + uint32_t handler; uint32_t scale; uint32_t rate; int sample_size; /* size of one sample (or packet) @@ -60,7 +62,7 @@ typedef struct AVIStream { uint8_t *sub_buffer; } AVIStream; -typedef struct { +typedef struct AVIContext { int64_t riff_end; int64_t movi_end; int64_t fsize; @@ -93,7 +95,7 @@ static int avi_load_index(AVFormatContext *s); static int guess_ni_flag(AVFormatContext *s); #define print_tag(str, tag, size) \ - av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \ + av_log(NULL, AV_LOG_TRACE, "%s: tag=%c%c%c%c size=0x%x\n", \ str, tag & 0xff, \ (tag >> 8) & 0xff, \ (tag >> 16) & 0xff, \ @@ -153,7 +155,7 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num) int64_t last_pos = -1; int64_t filesize = avi->fsize; - av_dlog(s, + av_log(s, AV_LOG_TRACE, "longs_pre_entry:%d index_type:%d entries_in_use:%d " "chunk_id:%X base:%16"PRIX64"\n", longs_pre_entry, @@ -194,7 +196,7 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num) int key = len >= 0; len &= 0x7FFFFFFF; - av_dlog(s, "pos:%"PRId64", len:%X\n", pos, len); + av_log(s, AV_LOG_TRACE, "pos:%"PRId64", len:%X\n", pos, len); if (pb->eof_reached) return AVERROR_INVALIDDATA; @@ -403,7 +405,7 @@ static int avi_read_header(AVFormatContext *s) avi->movi_end = avi->movi_list + size + (size & 1); else avi->movi_end = avi->fsize; - av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end); + av_log(NULL, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end); goto end_of_header; } else if (tag1 == MKTAG('I', 'N', 'F', 'O')) ff_read_riff_info(s, size - 4); @@ -515,7 +517,7 @@ static int avi_read_header(AVFormatContext *s) } assert(stream_index < s->nb_streams); - st->codec->stream_codec_tag = handler; + ast->handler = handler; avio_rl32(pb); /* flags */ avio_rl16(pb); /* priority */ @@ -547,7 +549,7 @@ static int avi_read_header(AVFormatContext *s) avio_rl32(pb); /* quality */ ast->sample_size = avio_rl32(pb); /* sample ssize */ ast->cum_len *= FFMAX(1, ast->sample_size); - av_dlog(s, "%"PRIu32" %"PRIu32" %d\n", + av_log(s, AV_LOG_TRACE, "%"PRIu32" %"PRIu32" %d\n", ast->rate, ast->scale, ast->sample_size); switch (tag1) { @@ -569,6 +571,23 @@ static int avi_read_header(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1); goto fail; } + + if (ast->sample_size < 0) { + if (s->error_recognition & AV_EF_EXPLODE) { + av_log(s, AV_LOG_ERROR, + "Invalid sample_size %d at stream %d\n", + ast->sample_size, + stream_index); + goto fail; + } + av_log(s, AV_LOG_WARNING, + "Invalid sample_size %d at stream %d " + "setting it to 0\n", + ast->sample_size, + stream_index); + ast->sample_size = 0; + } + if (ast->sample_size == 0) st->duration = st->nb_frames; ast->frame_offset = ast->cum_len; @@ -606,7 +625,7 @@ static int avi_read_header(AVFormatContext *s) if (size > 10 * 4 && size < (1 << 30)) { st->codec->extradata_size = size - 10 * 4; st->codec->extradata = av_malloc(st->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); + AV_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { st->codec->extradata_size = 0; return AVERROR(ENOMEM); @@ -647,9 +666,25 @@ static int avi_read_header(AVFormatContext *s) st->codec->codec_tag = tag1; st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); + /* If codec is not found yet, try with the mov tags. */ + if (!st->codec->codec_id) { + char tag_buf[32]; + av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag1); + st->codec->codec_id = + ff_codec_get_id(ff_codec_movvideo_tags, tag1); + if (st->codec->codec_id) + av_log(s, AV_LOG_WARNING, + "mov tag found in avi (fourcc %s)\n", + tag_buf); + } /* This is needed to get the pict type which is necessary * for generating correct pts. */ st->need_parsing = AVSTREAM_PARSE_HEADERS; + + if (st->codec->codec_id == AV_CODEC_ID_MPEG4 && + ast->handler == MKTAG('X', 'V', 'I', 'D')) + st->codec->codec_tag = MKTAG('X', 'V', 'I', 'D'); + // Support "Resolution 1:1" for Avid AVI Codec if (tag1 == MKTAG('A', 'V', 'R', 'n') && st->codec->extradata_size >= 31 && @@ -661,7 +696,7 @@ static int avi_read_header(AVFormatContext *s) st->codec->extradata_size += 9; if ((ret = av_reallocp(&st->codec->extradata, st->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE)) < 0) { + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) { st->codec->extradata_size = 0; return ret; } else @@ -673,7 +708,7 @@ static int avi_read_header(AVFormatContext *s) // avio_skip(pb, size - 5 * 4); break; case AVMEDIA_TYPE_AUDIO: - ret = ff_get_wav_header(pb, st->codec, size); + ret = ff_get_wav_header(s, pb, st->codec, size); if (ret < 0) return ret; ast->dshow_block_align = st->codec->block_align; @@ -701,7 +736,7 @@ static int avi_read_header(AVFormatContext *s) st->need_parsing = AVSTREAM_PARSE_NONE; /* AVI files with Xan DPCM audio (wrongly) declare PCM * audio in the header but have Axan as stream_code_tag. */ - if (st->codec->stream_codec_tag == AV_RL32("Axan")) { + if (ast->handler == AV_RL32("Axan")) { st->codec->codec_id = AV_CODEC_ID_XAN_DPCM; st->codec->codec_tag = 0; } @@ -751,7 +786,7 @@ static int avi_read_header(AVFormatContext *s) if (active_aspect.num && active_aspect.den && active.num && active.den) { st->sample_aspect_ratio = av_div_q(active_aspect, active); - av_dlog(s, "vprp %d/%d %d/%d\n", + av_log(s, AV_LOG_TRACE, "vprp %d/%d %d/%d\n", active_aspect.num, active_aspect.den, active.num, active.den); } @@ -939,7 +974,7 @@ start_sync: size = d[4] + (d[5] << 8) + (d[6] << 16) + (d[7] << 24); n = get_stream_idx(d + 2); - av_dlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n", + av_log(s, AV_LOG_TRACE, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n); if (i + (uint64_t)size > avi->fsize || d[0] > 127) continue; @@ -1060,9 +1095,6 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) AVIContext *avi = s->priv_data; AVIOContext *pb = s->pb; int err; -#if FF_API_DESTRUCT_PACKET - void *dstr; -#endif if (CONFIG_DV_DEMUXER && avi->dv_demux) { int size = avpriv_dv_get_packet(avi->dv_demux, pkt); @@ -1096,7 +1128,7 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) (AVRational) { FFMAX(1, ast->sample_size), AV_TIME_BASE }); - av_dlog(s, "%"PRId64" %d/%d %"PRId64"\n", ts, + av_log(s, AV_LOG_TRACE, "%"PRId64" %d/%d %"PRId64"\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset); if (ts < best_ts) { best_ts = ts; @@ -1178,22 +1210,12 @@ resync: if (CONFIG_DV_DEMUXER && avi->dv_demux) { AVBufferRef *avbuf = pkt->buf; -#if FF_API_DESTRUCT_PACKET -FF_DISABLE_DEPRECATION_WARNINGS - dstr = pkt->destruct; -FF_ENABLE_DEPRECATION_WARNINGS -#endif size = avpriv_dv_produce_packet(avi->dv_demux, pkt, pkt->data, pkt->size); -#if FF_API_DESTRUCT_PACKET -FF_DISABLE_DEPRECATION_WARNINGS - pkt->destruct = dstr; -FF_ENABLE_DEPRECATION_WARNINGS -#endif pkt->buf = avbuf; pkt->flags |= AV_PKT_FLAG_KEY; if (size < 0) - av_free_packet(pkt); + av_packet_unref(pkt); } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && !st->codec->codec_tag && read_gab2_sub(st, pkt)) { ast->frame_offset++; @@ -1206,7 +1228,7 @@ FF_ENABLE_DEPRECATION_WARNINGS // pkt->dts += ast->start; if (ast->sample_size) pkt->dts /= ast->sample_size; - av_dlog(s, + av_log(s, AV_LOG_TRACE, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d " "base:%d st:%d size:%d\n", pkt->dts, @@ -1279,7 +1301,7 @@ static int avi_read_idx1(AVFormatContext *s, int size) flags = avio_rl32(pb); pos = avio_rl32(pb); len = avio_rl32(pb); - av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/", + av_log(s, AV_LOG_TRACE, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/", i, tag, flags, pos, len); index = ((tag & 0xff) - '0') * 10; @@ -1295,7 +1317,7 @@ static int avi_read_idx1(AVFormatContext *s, int size) } pos += data_offset; - av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len); + av_log(s, AV_LOG_TRACE, "%d cum_len=%"PRId64"\n", len, ast->cum_len); if (pb->eof_reached) return AVERROR_INVALIDDATA; @@ -1415,13 +1437,13 @@ static int avi_load_index(AVFormatContext *s) if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0) goto the_end; // maybe truncated file - av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end); + av_log(s, AV_LOG_TRACE, "movi_end=0x%"PRIx64"\n", avi->movi_end); for (;;) { if (pb->eof_reached) break; tag = avio_rl32(pb); size = avio_rl32(pb); - av_dlog(s, "tag=%c%c%c%c size=0x%x\n", + av_log(s, AV_LOG_TRACE, "tag=%c%c%c%c size=0x%x\n", tag & 0xff, (tag >> 8) & 0xff, (tag >> 16) & 0xff, @@ -1448,7 +1470,7 @@ static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp) { AVIStream *ast2 = st2->priv_data; int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base); - av_free_packet(&ast2->sub_pkt); + av_packet_unref(&ast2->sub_pkt); if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 || avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0) ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt); @@ -1487,7 +1509,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, pos = st->index_entries[index].pos; timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); - av_dlog(s, "XX %"PRId64" %d %"PRId64"\n", + av_log(s, AV_LOG_TRACE, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp); if (CONFIG_DV_DEMUXER && avi->dv_demux) { @@ -1539,7 +1561,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, index++; } - av_dlog(s, "%"PRId64" %d %"PRId64"\n", + av_log(s, AV_LOG_TRACE, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp); /* extract the current frame number */ ast2->frame_offset = st2->index_entries[index].timestamp; @@ -1565,7 +1587,7 @@ static int avi_read_close(AVFormatContext *s) avformat_close_input(&ast->sub_ctx); } av_free(ast->sub_buffer); - av_free_packet(&ast->sub_pkt); + av_packet_unref(&ast->sub_pkt); } }