X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Favidec.c;h=ac020109c67511727924c97ae2e78f0c151c65c4;hb=56450a0ee4fdda160f4039fc2ae33edfd27765c9;hp=3f074795a75ebf1fc4fd1bef247b468daa9102bc;hpb=f32d2939555706365ad1d39aadd5ee7ce1d9fa4f;p=ffmpeg diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 3f074795a75..ac020109c67 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -23,7 +23,6 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" -#include "libavutil/bswap.h" #include "libavutil/opt.h" #include "libavutil/dict.h" #include "libavutil/internal.h" @@ -60,8 +59,8 @@ typedef struct AVIStream { * the MS dshow demuxer */ AVFormatContext *sub_ctx; - AVPacket sub_pkt; - uint8_t *sub_buffer; + AVPacket *sub_pkt; + AVBufferRef *sub_buffer; int64_t seek_pos; } AVIStream; @@ -111,14 +110,24 @@ static const char avi_headers[][8] = { static const AVMetadataConv avi_metadata_conv[] = { { "strn", "title" }, + { "isbj", "subject" }, + { "inam", "title" }, + { "iart", "artist" }, + { "icop", "copyright" }, + { "icmt", "comment" }, + { "ignr", "genre" }, + { "iprd", "product" }, + { "isft", "software" }, + { 0 }, }; +static int avi_read_close(AVFormatContext *s); static int avi_load_index(AVFormatContext *s); static int guess_ni_flag(AVFormatContext *s); -#define print_tag(str, tag, size) \ - av_log(NULL, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%s size=0x%x\n", \ +#define print_tag(s, str, tag, size) \ + av_log(s, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%s size=0x%x\n", \ avio_tell(pb), str, av_fourcc2str(tag), size) \ static inline int get_duration(AVIStream *ast, int len) @@ -126,7 +135,7 @@ static inline int get_duration(AVIStream *ast, int len) if (ast->sample_size) return len; else if (ast->dshow_block_align) - return (len + ast->dshow_block_align - 1) / ast->dshow_block_align; + return (len + (int64_t)ast->dshow_block_align - 1) / ast->dshow_block_align; else return 1; } @@ -272,7 +281,7 @@ static void clean_index(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; AVIStream *ast = st->priv_data; - int n = st->nb_index_entries; + int n = st->internal->nb_index_entries; int max = ast->sample_size; int64_t pos, size, ts; @@ -282,9 +291,9 @@ static void clean_index(AVFormatContext *s) while (max < 1024) max += max; - pos = st->index_entries[0].pos; - size = st->index_entries[0].size; - ts = st->index_entries[0].timestamp; + pos = st->internal->index_entries[0].pos; + size = st->internal->index_entries[0].size; + ts = st->internal->index_entries[0].timestamp; for (j = 0; j < size; j += max) av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0, @@ -306,8 +315,10 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, value = av_malloc(size + 1); if (!value) return AVERROR(ENOMEM); - if (avio_read(pb, value, size) != size) + if (avio_read(pb, value, size) != size) { + av_freep(&value); return AVERROR_INVALIDDATA; + } value[size] = 0; AV_WL32(key, tag); @@ -430,15 +441,15 @@ static int calculate_bitrate(AVFormatContext *s) int64_t len = 0; AVStream *st = s->streams[i]; - if (!st->nb_index_entries) + if (!st->internal->nb_index_entries) continue; - for (j = 0; j < st->nb_index_entries; j++) - len += st->index_entries[j].size; - maxpos = FFMAX(maxpos, st->index_entries[j-1].pos); + for (j = 0; j < st->internal->nb_index_entries; j++) + len += st->internal->index_entries[j].size; + maxpos = FFMAX(maxpos, st->internal->index_entries[j-1].pos); lensum += len; } - if (maxpos < avi->io_fsize*9/10) // index does not cover the whole file + if (maxpos < av_rescale(avi->io_fsize, 9, 10)) // index does not cover the whole file return 0; if (lensum*9/10 > maxpos || lensum < maxpos*9/10) // frame sum and filesize mismatch return 0; @@ -449,20 +460,21 @@ static int calculate_bitrate(AVFormatContext *s) int64_t duration; int64_t bitrate; - for (j = 0; j < st->nb_index_entries; j++) - len += st->index_entries[j].size; + for (j = 0; j < st->internal->nb_index_entries; j++) + len += st->internal->index_entries[j].size; - if (st->nb_index_entries < 2 || st->codecpar->bit_rate > 0) + if (st->internal->nb_index_entries < 2 || st->codecpar->bit_rate > 0) continue; - duration = st->index_entries[j-1].timestamp - st->index_entries[0].timestamp; + duration = st->internal->index_entries[j-1].timestamp - st->internal->index_entries[0].timestamp; bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num); - if (bitrate <= INT_MAX && bitrate > 0) { + if (bitrate > 0) { st->codecpar->bit_rate = bitrate; } } return 1; } +#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0) static int avi_read_header(AVFormatContext *s) { AVIContext *avi = s->priv_data; @@ -498,11 +510,11 @@ static int avi_read_header(AVFormatContext *s) frame_period = 0; for (;;) { if (avio_feof(pb)) - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); tag = avio_rl32(pb); size = avio_rl32(pb); - print_tag("tag", tag, size); + print_tag(s, "tag", tag, size); switch (tag) { case MKTAG('L', 'I', 'S', 'T'): @@ -510,7 +522,7 @@ static int avi_read_header(AVFormatContext *s) /* Ignored, except at start of video packets. */ tag1 = avio_rl32(pb); - print_tag("list", tag1, 0); + print_tag(s, "list", tag1, 0); if (tag1 == MKTAG('m', 'o', 'v', 'i')) { avi->movi_list = avio_tell(pb) - 4; @@ -518,7 +530,7 @@ static int avi_read_header(AVFormatContext *s) avi->movi_end = avi->movi_list + size + (size & 1); else avi->movi_end = avi->fsize; - av_log(NULL, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end); + av_log(s, 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); @@ -570,19 +582,19 @@ static int avi_read_header(AVFormatContext *s) stream_index++; st = avformat_new_stream(s, NULL); if (!st) - goto fail; + RETURN_ERROR(AVERROR(ENOMEM)); st->id = stream_index; ast = av_mallocz(sizeof(AVIStream)); if (!ast) - goto fail; + RETURN_ERROR(AVERROR(ENOMEM)); st->priv_data = ast; } if (amv_file_format) tag1 = stream_index ? MKTAG('a', 'u', 'd', 's') : MKTAG('v', 'i', 'd', 's'); - print_tag("strh", tag1, -1); + print_tag(s, "strh", tag1, -1); if (tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')) { @@ -591,35 +603,26 @@ static int avi_read_header(AVFormatContext *s) /* After some consideration -- I don't think we * have to support anything but DV in type1 AVIs. */ if (s->nb_streams != 1) - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); if (handler != MKTAG('d', 'v', 's', 'd') && handler != MKTAG('d', 'v', 'h', 'd') && handler != MKTAG('d', 'v', 's', 'l')) - goto fail; + return AVERROR_INVALIDDATA; + + if (!CONFIG_DV_DEMUXER) + return AVERROR_DEMUXER_NOT_FOUND; ast = s->streams[0]->priv_data; - av_freep(&s->streams[0]->codecpar->extradata); - av_freep(&s->streams[0]->codecpar); -#if FF_API_LAVF_AVCTX -FF_DISABLE_DEPRECATION_WARNINGS - av_freep(&s->streams[0]->codec); -FF_ENABLE_DEPRECATION_WARNINGS -#endif - if (s->streams[0]->info) - av_freep(&s->streams[0]->info->duration_error); - av_freep(&s->streams[0]->info); - if (s->streams[0]->internal) - av_freep(&s->streams[0]->internal->avctx); - av_freep(&s->streams[0]->internal); - av_freep(&s->streams[0]); - s->nb_streams = 0; - if (CONFIG_DV_DEMUXER) { - avi->dv_demux = avpriv_dv_init_demux(s); - if (!avi->dv_demux) - goto fail; - } else - goto fail; + st->priv_data = NULL; + ff_free_stream(s, st); + + avi->dv_demux = avpriv_dv_init_demux(s); + if (!avi->dv_demux) { + av_free(ast); + return AVERROR(ENOMEM); + } + s->streams[0]->priv_data = ast; avio_skip(pb, 3 * 4); ast->scale = avio_rl32(pb); @@ -705,7 +708,7 @@ FF_ENABLE_DEPRECATION_WARNINGS "Invalid sample_size %d at stream %d\n", ast->sample_size, stream_index); - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); } av_log(s, AV_LOG_WARNING, "Invalid sample_size %d at stream %d " @@ -769,10 +772,11 @@ FF_ENABLE_DEPRECATION_WARNINGS st->codecpar->extradata_size = size - 10 * 4; if (st->codecpar->extradata) { av_log(s, AV_LOG_WARNING, "New extradata in strf chunk, freeing previous one.\n"); - av_freep(&st->codecpar->extradata); } - if (ff_get_extradata(s, st->codecpar, pb, st->codecpar->extradata_size) < 0) - return AVERROR(ENOMEM); + ret = ff_get_extradata(s, st->codecpar, pb, + st->codecpar->extradata_size); + if (ret < 0) + return ret; } // FIXME: check if the encoder really did this correctly @@ -800,7 +804,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ast->has_pal = 1; } - print_tag("video", tag1, 0); + print_tag(s, "video", tag1, 0); st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_tag = tag1; @@ -815,6 +819,9 @@ FF_ENABLE_DEPRECATION_WARNINGS "mov tag found in avi (fourcc %s)\n", av_fourcc2str(tag1)); } + if (!st->codecpar->codec_id) + st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags_unofficial, tag1); + /* This is needed to get the pict type which is necessary * for generating correct pts. */ st->need_parsing = AVSTREAM_PARSE_HEADERS; @@ -827,6 +834,15 @@ FF_ENABLE_DEPRECATION_WARNINGS st->need_parsing = AVSTREAM_PARSE_FULL; if (st->codecpar->codec_id == AV_CODEC_ID_RV40) st->need_parsing = AVSTREAM_PARSE_NONE; + if (st->codecpar->codec_id == AV_CODEC_ID_HEVC && + st->codecpar->codec_tag == MKTAG('H', '2', '6', '5')) + st->need_parsing = AVSTREAM_PARSE_FULL; + + if (st->codecpar->codec_id == AV_CODEC_ID_AVRN && + st->codecpar->codec_tag == MKTAG('A', 'V', 'R', 'n') && + (st->codecpar->extradata_size < 31 || + memcmp(&st->codecpar->extradata[28], "1:1", 3))) + st->codecpar->codec_id = AV_CODEC_ID_MJPEG; if (st->codecpar->codec_tag == 0 && st->codecpar->height > 0 && st->codecpar->extradata_size < 1U << 30) { @@ -900,7 +916,7 @@ FF_ENABLE_DEPRECATION_WARNINGS break; case AVMEDIA_TYPE_SUBTITLE: st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->request_probe= 1; + st->internal->request_probe= 1; avio_skip(pb, size); break; default: @@ -926,10 +942,9 @@ FF_ENABLE_DEPRECATION_WARNINGS if (size<(1<<30)) { if (st->codecpar->extradata) { av_log(s, AV_LOG_WARNING, "New extradata in strd chunk, freeing previous one.\n"); - av_freep(&st->codecpar->extradata); } - if (ff_get_extradata(s, st->codecpar, pb, size) < 0) - return AVERROR(ENOMEM); + if ((ret = ff_get_extradata(s, st->codecpar, pb, size)) < 0) + goto fail; } if (st->codecpar->extradata_size & 1) //FIXME check if the encoder really did this correctly @@ -947,7 +962,7 @@ FF_ENABLE_DEPRECATION_WARNINGS avi->use_odml && read_odml_index(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE)) - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); avio_seek(pb, pos + size, SEEK_SET); break; case MKTAG('v', 'p', 'r', 'p'): @@ -979,10 +994,18 @@ FF_ENABLE_DEPRECATION_WARNINGS avio_skip(pb, size); break; case MKTAG('s', 't', 'r', 'n'): + case MKTAG('i', 's', 'b', 'j'): + case MKTAG('i', 'n', 'a', 'm'): + case MKTAG('i', 'a', 'r', 't'): + case MKTAG('i', 'c', 'o', 'p'): + case MKTAG('i', 'c', 'm', 't'): + case MKTAG('i', 'g', 'n', 'r'): + case MKTAG('i', 'p', 'o', 'd'): + case MKTAG('i', 's', 'o', 'f'): if (s->nb_streams) { ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size); if (ret < 0) - return ret; + goto fail; break; } default: @@ -993,7 +1016,7 @@ FF_ENABLE_DEPRECATION_WARNINGS "I will ignore it and try to continue anyway.\n", av_fourcc2str(tag), size); if (s->error_recognition & AV_EF_EXPLODE) - goto fail; + RETURN_ERROR(AVERROR_INVALIDDATA); avi->movi_list = avio_tell(pb) - 4; avi->movi_end = avi->fsize; goto end_of_header; @@ -1010,9 +1033,7 @@ FF_ENABLE_DEPRECATION_WARNINGS end_of_header: /* check stream number */ if (stream_index != s->nb_streams - 1) { - -fail: - return AVERROR_INVALIDDATA; + RETURN_ERROR(AVERROR_INVALIDDATA); } if (!avi->index_loaded && (pb->seekable & AVIO_SEEKABLE_NORMAL)) @@ -1021,7 +1042,7 @@ fail: avi->index_loaded |= 1; if ((ret = guess_ni_flag(s)) < 0) - return ret; + goto fail; avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS); @@ -1036,7 +1057,7 @@ fail: for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - if (st->nb_index_entries) + if (st->internal->nb_index_entries) break; } // DV-in-AVI cannot be non-interleaved, if set this must be @@ -1058,6 +1079,9 @@ fail: ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); return 0; +fail: + avi_read_close(s); + return ret; } static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) @@ -1068,14 +1092,18 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) uint8_t desc[256]; int score = AVPROBE_SCORE_EXTENSION, ret; AVIStream *ast = st->priv_data; - AVInputFormat *sub_demuxer; + const AVInputFormat *sub_demuxer; AVRational time_base; int size; + AVProbeData pd; + unsigned int desc_len; AVIOContext *pb = avio_alloc_context(pkt->data + 7, pkt->size - 7, 0, NULL, NULL, NULL, NULL); - AVProbeData pd; - unsigned int desc_len = avio_rl32(pb); + if (!pb) + goto error; + + desc_len = avio_rl32(pb); if (desc_len > pb->buf_end - pb->buf_ptr) goto error; @@ -1102,6 +1130,9 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) if (strcmp(sub_demuxer->name, "srt") && strcmp(sub_demuxer->name, "ass")) goto error; + if (!(ast->sub_pkt = av_packet_alloc())) + goto error; + if (!(ast->sub_ctx = avformat_alloc_context())) goto error; @@ -1113,16 +1144,18 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) { if (ast->sub_ctx->nb_streams != 1) goto error; - ff_read_packet(ast->sub_ctx, &ast->sub_pkt); + ff_read_packet(ast->sub_ctx, ast->sub_pkt); avcodec_parameters_copy(st->codecpar, ast->sub_ctx->streams[0]->codecpar); time_base = ast->sub_ctx->streams[0]->time_base; avpriv_set_pts_info(st, 64, time_base.num, time_base.den); } - ast->sub_buffer = pkt->data; - memset(pkt, 0, sizeof(*pkt)); + ast->sub_buffer = pkt->buf; + pkt->buf = NULL; + av_packet_unref(pkt); return 1; error: + av_packet_free(&ast->sub_pkt); av_freep(&ast->sub_ctx); avio_context_free(&pb); } @@ -1143,8 +1176,8 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st, for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; ast = st->priv_data; - if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) { - ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q); + if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt && ast->sub_pkt->data) { + ts = av_rescale_q(ast->sub_pkt->dts, st->time_base, AV_TIME_BASE_Q); if (ts <= next_ts && ts < ts_min) { ts_min = ts; sub_st = st; @@ -1154,11 +1187,11 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st, if (sub_st) { ast = sub_st->priv_data; - *pkt = ast->sub_pkt; + av_packet_move_ref(pkt, ast->sub_pkt); pkt->stream_index = sub_st->index; - if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0) - ast->sub_pkt.data = NULL; + if (ff_read_packet(ast->sub_ctx, ast->sub_pkt) < 0) + ast->sub_pkt->data = NULL; } return sub_st; } @@ -1255,7 +1288,7 @@ start_sync: AVStream *st1 = s->streams[1]; AVIStream *ast1 = st1->priv_data; // workaround for broken small-file-bug402.avi - if ( d[2] == 'w' && d[3] == 'b' + if (ast1 && d[2] == 'w' && d[3] == 'b' && n == 0 && st ->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st1->codecpar->codec_type == AVMEDIA_TYPE_AUDIO @@ -1314,8 +1347,8 @@ start_sync: if (size) { uint64_t pos = avio_tell(pb) - 8; - if (!st->index_entries || !st->nb_index_entries || - st->index_entries[st->nb_index_entries - 1].pos < pos) { + if (!st->internal->index_entries || !st->internal->nb_index_entries || + st->internal->index_entries[st->internal->nb_index_entries - 1].pos < pos) { av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME); } @@ -1345,10 +1378,10 @@ static int ni_prepare_read(AVFormatContext *s) int64_t ts = ast->frame_offset; int64_t last_ts; - if (!st->nb_index_entries) + if (!st->internal->nb_index_entries) continue; - last_ts = st->index_entries[st->nb_index_entries - 1].timestamp; + last_ts = st->internal->index_entries[st->internal->nb_index_entries - 1].timestamp; if (!ast->remaining && ts > last_ts) continue; @@ -1377,11 +1410,11 @@ static int ni_prepare_read(AVFormatContext *s) } else { i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY); if (i >= 0) - best_ast->frame_offset = best_st->index_entries[i].timestamp; + best_ast->frame_offset = best_st->internal->index_entries[i].timestamp; } if (i >= 0) { - int64_t pos = best_st->index_entries[i].pos; + int64_t pos = best_st->internal->index_entries[i].pos; pos += best_ast->packet_size - best_ast->remaining; if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0) return AVERROR_EOF; @@ -1391,7 +1424,7 @@ static int ni_prepare_read(AVFormatContext *s) avi->stream_index = best_stream_index; if (!best_ast->remaining) best_ast->packet_size = - best_ast->remaining = best_st->index_entries[i].size; + best_ast->remaining = best_st->internal->index_entries[i].size; } else return AVERROR_EOF; @@ -1423,6 +1456,7 @@ resync: if (avi->stream_index >= 0) { AVStream *st = s->streams[avi->stream_index]; AVIStream *ast = st->priv_data; + int dv_demux = CONFIG_DV_DEMUXER && avi->dv_demux; int size, err; if (get_subtitle_pkt(s, st, pkt)) @@ -1445,7 +1479,7 @@ resync: return err; size = err; - if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) { + if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2 && !dv_demux) { uint8_t *pal; pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, @@ -1459,7 +1493,7 @@ resync: } } - if (CONFIG_DV_DEMUXER && avi->dv_demux) { + if (CONFIG_DV_DEMUXER && dv_demux) { AVBufferRef *avbuf = pkt->buf; size = avpriv_dv_produce_packet(avi->dv_demux, pkt, pkt->data, pkt->size, pkt->pos); @@ -1481,15 +1515,15 @@ resync: pkt->dts /= ast->sample_size; pkt->stream_index = avi->stream_index; - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) { + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->index_entries) { AVIndexEntry *e; int index; index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY); - e = &st->index_entries[index]; + e = &st->internal->index_entries[index]; if (index >= 0 && e->timestamp == ast->frame_offset) { - if (index == st->nb_index_entries-1) { + if (index == st->internal->nb_index_entries-1) { int key=1; uint32_t state=-1; if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { @@ -1525,14 +1559,15 @@ resync: } ast->seek_pos= 0; - if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) { + if (!avi->non_interleaved && st->internal->nb_index_entries>1 && avi->index_loaded>1) { int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q); - if (avi->dts_max - dts > 2*AV_TIME_BASE) { + if (avi->dts_max < dts) { + avi->dts_max = dts; + } else if (avi->dts_max - (uint64_t)dts > 2*AV_TIME_BASE) { avi->non_interleaved= 1; av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n"); - }else if (avi->dts_max < dts) - avi->dts_max = dts; + } } return 0; @@ -1624,8 +1659,8 @@ static int avi_read_idx1(AVFormatContext *s, int size) if (!anykey) { for (index = 0; index < s->nb_streams; index++) { st = s->streams[index]; - if (st->nb_index_entries) - st->index_entries[0].flags |= AVINDEX_KEYFRAME; + if (st->internal->nb_index_entries) + st->internal->index_entries[0].flags |= AVINDEX_KEYFRAME; } } return 0; @@ -1650,16 +1685,16 @@ static int check_stream_max_drift(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; AVIStream *ast = st->priv_data; - int n = st->nb_index_entries; - while (idx[i] < n && st->index_entries[idx[i]].pos < pos) + int n = st->internal->nb_index_entries; + while (idx[i] < n && st->internal->index_entries[idx[i]].pos < pos) idx[i]++; if (idx[i] < n) { int64_t dts; - dts = av_rescale_q(st->index_entries[idx[i]].timestamp / + dts = av_rescale_q(st->internal->index_entries[idx[i]].timestamp / FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q); min_dts = FFMIN(min_dts, dts); - min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos); + min_pos = FFMIN(min_pos, st->internal->index_entries[idx[i]].pos); } } for (i = 0; i < s->nb_streams; i++) { @@ -1667,18 +1702,19 @@ static int check_stream_max_drift(AVFormatContext *s) AVIStream *ast = st->priv_data; if (idx[i] && min_dts != INT64_MAX / 2) { - int64_t dts; - dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp / + int64_t dts, delta_dts; + dts = av_rescale_q(st->internal->index_entries[idx[i] - 1].timestamp / FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q); + delta_dts = av_sat_sub64(dts, min_dts); max_dts = FFMAX(max_dts, dts); max_buffer = FFMAX(max_buffer, - av_rescale(dts - min_dts, + av_rescale(delta_dts, st->codecpar->bit_rate, AV_TIME_BASE)); } } - if (max_dts - min_dts > 2 * AV_TIME_BASE || + if (av_sat_sub64(max_dts, min_dts) > 2 * AV_TIME_BASE || max_buffer > 1024 * 1024 * 8 * 8) { av_free(idx); return 1; @@ -1697,30 +1733,30 @@ static int guess_ni_flag(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - int n = st->nb_index_entries; + int n = st->internal->nb_index_entries; unsigned int size; if (n <= 0) continue; if (n >= 2) { - int64_t pos = st->index_entries[0].pos; + int64_t pos = st->internal->index_entries[0].pos; unsigned tag[2]; avio_seek(s->pb, pos, SEEK_SET); tag[0] = avio_r8(s->pb); tag[1] = avio_r8(s->pb); avio_rl16(s->pb); size = avio_rl32(s->pb); - if (get_stream_idx(tag) == i && pos + size > st->index_entries[1].pos) + if (get_stream_idx(tag) == i && pos + size > st->internal->index_entries[1].pos) last_start = INT64_MAX; - if (get_stream_idx(tag) == i && size == st->index_entries[0].size + 8) + if (get_stream_idx(tag) == i && size == st->internal->index_entries[0].size + 8) last_start = INT64_MAX; } - if (st->index_entries[0].pos > last_start) - last_start = st->index_entries[0].pos; - if (st->index_entries[n - 1].pos < first_end) - first_end = st->index_entries[n - 1].pos; + if (st->internal->index_entries[0].pos > last_start) + last_start = st->internal->index_entries[0].pos; + if (st->internal->index_entries[n - 1].pos < first_end) + first_end = st->internal->index_entries[n - 1].pos; } avio_seek(s->pb, oldpos, SEEK_SET); @@ -1774,10 +1810,10 @@ 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_packet_unref(&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); + ff_read_packet(ast2->sub_ctx, ast2->sub_pkt); } static int avi_read_seek(AVFormatContext *s, int stream_index, @@ -1808,20 +1844,20 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, timestamp * FFMAX(ast->sample_size, 1), flags); if (index < 0) { - if (st->nb_index_entries > 0) + if (st->internal->nb_index_entries > 0) av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n", timestamp * FFMAX(ast->sample_size, 1), - st->index_entries[0].timestamp, - st->index_entries[st->nb_index_entries - 1].timestamp); + st->internal->index_entries[0].timestamp, + st->internal->index_entries[st->internal->nb_index_entries - 1].timestamp); return AVERROR_INVALIDDATA; } /* find the position */ - pos = st->index_entries[index].pos; - timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); + pos = st->internal->index_entries[index].pos; + timestamp = st->internal->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); av_log(s, AV_LOG_TRACE, "XX %"PRId64" %d %"PRId64"\n", - timestamp, index, st->index_entries[index].timestamp); + timestamp, index, st->internal->index_entries[index].timestamp); if (CONFIG_DV_DEMUXER && avi->dv_demux) { /* One and only one real stream for DV in AVI, and it has video */ @@ -1852,7 +1888,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, continue; } - if (st2->nb_index_entries <= 0) + if (st2->internal->nb_index_entries <= 0) continue; // av_assert1(st2->codecpar->block_align); @@ -1866,14 +1902,14 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0)); if (index < 0) index = 0; - ast2->seek_pos = st2->index_entries[index].pos; + ast2->seek_pos = st2->internal->index_entries[index].pos; pos_min = FFMIN(pos_min,ast2->seek_pos); } for (i = 0; i < s->nb_streams; i++) { AVStream *st2 = s->streams[i]; AVIStream *ast2 = st2->priv_data; - if (ast2->sub_ctx || st2->nb_index_entries <= 0) + if (ast2->sub_ctx || st2->internal->nb_index_entries <= 0) continue; index = av_index_search_timestamp( @@ -1882,9 +1918,9 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, flags | AVSEEK_FLAG_BACKWARD | (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0)); if (index < 0) index = 0; - while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min) + while (!avi->non_interleaved && index>0 && st2->internal->index_entries[index-1].pos >= pos_min) index--; - ast2->frame_offset = st2->index_entries[index].timestamp; + ast2->frame_offset = st2->internal->index_entries[index].timestamp; } /* do the seek */ @@ -1910,8 +1946,8 @@ static int avi_read_close(AVFormatContext *s) av_freep(&ast->sub_ctx->pb); avformat_close_input(&ast->sub_ctx); } - av_freep(&ast->sub_buffer); - av_packet_unref(&ast->sub_pkt); + av_buffer_unref(&ast->sub_buffer); + av_packet_free(&ast->sub_pkt); } } @@ -1920,7 +1956,7 @@ static int avi_read_close(AVFormatContext *s) return 0; } -static int avi_probe(AVProbeData *p) +static int avi_probe(const AVProbeData *p) { int i;