diff options
Diffstat (limited to 'libavformat/avidec.c')
-rw-r--r-- | libavformat/avidec.c | 138 |
1 files changed, 77 insertions, 61 deletions
diff --git a/libavformat/avidec.c b/libavformat/avidec.c index b1dea1362e..3eb5d4dff5 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -279,8 +279,9 @@ static void clean_index(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; + FFStream *const sti = ffstream(st); AVIStream *ast = st->priv_data; - int n = st->internal->nb_index_entries; + int n = sti->nb_index_entries; int max = ast->sample_size; int64_t pos, size, ts; @@ -290,9 +291,9 @@ static void clean_index(AVFormatContext *s) while (max < 1024) max += max; - pos = st->internal->index_entries[0].pos; - size = st->internal->index_entries[0].size; - ts = st->internal->index_entries[0].timestamp; + pos = sti->index_entries[0].pos; + size = sti->index_entries[0].size; + ts = sti->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, @@ -439,14 +440,14 @@ static int calculate_bitrate(AVFormatContext *s) for (i = 0; i<s->nb_streams; i++) { int64_t len = 0; - AVStream *st = s->streams[i]; + FFStream *const sti = ffstream(s->streams[i]); - if (!st->internal->nb_index_entries) + if (!sti->nb_index_entries) continue; - 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); + for (j = 0; j < sti->nb_index_entries; j++) + len += sti->index_entries[j].size; + maxpos = FFMAX(maxpos, sti->index_entries[j-1].pos); lensum += len; } if (maxpos < av_rescale(avi->io_fsize, 9, 10)) // index does not cover the whole file @@ -457,15 +458,16 @@ static int calculate_bitrate(AVFormatContext *s) for (i = 0; i<s->nb_streams; i++) { int64_t len = 0; AVStream *st = s->streams[i]; + FFStream *const sti = ffstream(st); int64_t duration; int64_t bitrate; - for (j = 0; j < st->internal->nb_index_entries; j++) - len += st->internal->index_entries[j].size; + for (j = 0; j < sti->nb_index_entries; j++) + len += sti->index_entries[j].size; - if (st->internal->nb_index_entries < 2 || st->codecpar->bit_rate > 0) + if (sti->nb_index_entries < 2 || st->codecpar->bit_rate > 0) continue; - duration = st->internal->index_entries[j-1].timestamp - st->internal->index_entries[0].timestamp; + duration = sti->index_entries[j-1].timestamp - sti->index_entries[0].timestamp; bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num); if (bitrate > 0) { st->codecpar->bit_rate = bitrate; @@ -736,10 +738,12 @@ static int avi_read_header(AVFormatContext *s) avio_skip(pb, size); } else { uint64_t cur_pos = avio_tell(pb); + FFStream *sti; unsigned esize; if (cur_pos < list_end) size = FFMIN(size, list_end - cur_pos); st = s->streams[stream_index]; + sti = ffstream(st); if (st->codecpar->codec_type != AVMEDIA_TYPE_UNKNOWN) { avio_skip(pb, size); break; @@ -823,19 +827,19 @@ static int avi_read_header(AVFormatContext *s) /* This is needed to get the pict type which is necessary * for generating correct pts. */ - st->internal->need_parsing = AVSTREAM_PARSE_HEADERS; + sti->need_parsing = AVSTREAM_PARSE_HEADERS; if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4 && ast->handler == MKTAG('X', 'V', 'I', 'D')) st->codecpar->codec_tag = MKTAG('X', 'V', 'I', 'D'); if (st->codecpar->codec_tag == MKTAG('V', 'S', 'S', 'H')) - st->internal->need_parsing = AVSTREAM_PARSE_FULL; + sti->need_parsing = AVSTREAM_PARSE_FULL; if (st->codecpar->codec_id == AV_CODEC_ID_RV40) - st->internal->need_parsing = AVSTREAM_PARSE_NONE; + sti->need_parsing = AVSTREAM_PARSE_NONE; if (st->codecpar->codec_id == AV_CODEC_ID_HEVC && st->codecpar->codec_tag == MKTAG('H', '2', '6', '5')) - st->internal->need_parsing = AVSTREAM_PARSE_FULL; + sti->need_parsing = AVSTREAM_PARSE_FULL; if (st->codecpar->codec_id == AV_CODEC_ID_AVRN && st->codecpar->codec_tag == MKTAG('A', 'V', 'R', 'n') && @@ -879,16 +883,16 @@ static int avi_read_header(AVFormatContext *s) avio_skip(pb, 1); /* Force parsing as several audio frames can be in * one packet and timestamps refer to packet start. */ - st->internal->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; + sti->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. */ if (st->codecpar->codec_id == AV_CODEC_ID_AAC && st->codecpar->extradata_size) - st->internal->need_parsing = AVSTREAM_PARSE_NONE; + sti->need_parsing = AVSTREAM_PARSE_NONE; // The flac parser does not work with AVSTREAM_PARSE_TIMESTAMPS if (st->codecpar->codec_id == AV_CODEC_ID_FLAC) - st->internal->need_parsing = AVSTREAM_PARSE_NONE; + sti->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 (ast->handler == AV_RL32("Axan")) { @@ -915,7 +919,7 @@ static int avi_read_header(AVFormatContext *s) break; case AVMEDIA_TYPE_SUBTITLE: st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->internal->request_probe= 1; + sti->request_probe = 1; avio_skip(pb, size); break; default: @@ -1050,12 +1054,12 @@ end_of_header: AVStream *st = s->streams[i]; if ( st->codecpar->codec_id == AV_CODEC_ID_MPEG1VIDEO || st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO) - st->internal->need_parsing = AVSTREAM_PARSE_FULL; + ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL; } for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - if (st->internal->nb_index_entries) + if (ffstream(st)->nb_index_entries) break; } // DV-in-AVI cannot be non-interleaved, if set this must be @@ -1341,9 +1345,10 @@ start_sync: ast->remaining = size; if (size) { + FFStream *const sti = ffstream(st); uint64_t pos = avio_tell(pb) - 8; - if (!st->internal->index_entries || !st->internal->nb_index_entries || - st->internal->index_entries[st->internal->nb_index_entries - 1].pos < pos) { + if (!sti->index_entries || !sti->nb_index_entries || + sti->index_entries[sti->nb_index_entries - 1].pos < pos) { av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME); } @@ -1363,20 +1368,22 @@ static int ni_prepare_read(AVFormatContext *s) AVIContext *avi = s->priv_data; int best_stream_index = 0; AVStream *best_st = NULL; + FFStream *best_sti; AVIStream *best_ast; int64_t best_ts = INT64_MAX; int i; for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; + FFStream *const sti = ffstream(st); AVIStream *ast = st->priv_data; int64_t ts = ast->frame_offset; int64_t last_ts; - if (!st->internal->nb_index_entries) + if (!sti->nb_index_entries) continue; - last_ts = st->internal->index_entries[st->internal->nb_index_entries - 1].timestamp; + last_ts = sti->index_entries[sti->nb_index_entries - 1].timestamp; if (!ast->remaining && ts > last_ts) continue; @@ -1395,6 +1402,7 @@ static int ni_prepare_read(AVFormatContext *s) if (!best_st) return AVERROR_EOF; + best_sti = ffstream(best_st); best_ast = best_st->priv_data; best_ts = best_ast->frame_offset; if (best_ast->remaining) { @@ -1405,11 +1413,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->internal->index_entries[i].timestamp; + best_ast->frame_offset = best_sti->index_entries[i].timestamp; } if (i >= 0) { - int64_t pos = best_st->internal->index_entries[i].pos; + int64_t pos = best_sti->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; @@ -1419,7 +1427,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->internal->index_entries[i].size; + best_ast->remaining = best_sti->index_entries[i].size; } else return AVERROR_EOF; @@ -1450,6 +1458,7 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) resync: if (avi->stream_index >= 0) { AVStream *st = s->streams[avi->stream_index]; + FFStream *const sti = ffstream(st); AVIStream *ast = st->priv_data; int dv_demux = CONFIG_DV_DEMUXER && avi->dv_demux; int size, err; @@ -1508,15 +1517,15 @@ resync: pkt->dts /= ast->sample_size; pkt->stream_index = avi->stream_index; - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->index_entries) { + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->index_entries) { AVIndexEntry *e; int index; index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY); - e = &st->internal->index_entries[index]; + e = &sti->index_entries[index]; if (index >= 0 && e->timestamp == ast->frame_offset) { - if (index == st->internal->nb_index_entries-1) { + if (index == sti->nb_index_entries-1) { int key=1; uint32_t state=-1; if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { @@ -1552,7 +1561,7 @@ resync: } ast->seek_pos= 0; - if (!avi->non_interleaved && st->internal->nb_index_entries>1 && avi->index_loaded>1) { + if (!avi->non_interleaved && sti->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) { @@ -1651,9 +1660,9 @@ 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->internal->nb_index_entries) - st->internal->index_entries[0].flags |= AVINDEX_KEYFRAME; + FFStream *const sti = ffstream(s->streams[index]); + if (sti->nb_index_entries) + sti->index_entries[0].flags |= AVINDEX_KEYFRAME; } } return 0; @@ -1678,25 +1687,27 @@ 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->internal->nb_index_entries; - while (idx[i] < n && st->internal->index_entries[idx[i]].pos < pos) + FFStream *const sti = ffstream(st); + int n = sti->nb_index_entries; + while (idx[i] < n && sti->index_entries[idx[i]].pos < pos) idx[i]++; if (idx[i] < n) { int64_t dts; - dts = av_rescale_q(st->internal->index_entries[idx[i]].timestamp / + dts = av_rescale_q(sti->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->internal->index_entries[idx[i]].pos); + min_pos = FFMIN(min_pos, sti->index_entries[idx[i]].pos); } } for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; + FFStream *const sti = ffstream(st); AVIStream *ast = st->priv_data; if (idx[i] && min_dts != INT64_MAX / 2) { int64_t dts, delta_dts; - dts = av_rescale_q(st->internal->index_entries[idx[i] - 1].timestamp / + dts = av_rescale_q(sti->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); @@ -1726,30 +1737,31 @@ static int guess_ni_flag(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - int n = st->internal->nb_index_entries; + FFStream *const sti = ffstream(st); + int n = sti->nb_index_entries; unsigned int size; if (n <= 0) continue; if (n >= 2) { - int64_t pos = st->internal->index_entries[0].pos; + int64_t pos = sti->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->internal->index_entries[1].pos) + if (get_stream_idx(tag) == i && pos + size > sti->index_entries[1].pos) last_start = INT64_MAX; - if (get_stream_idx(tag) == i && size == st->internal->index_entries[0].size + 8) + if (get_stream_idx(tag) == i && size == sti->index_entries[0].size + 8) last_start = INT64_MAX; } - 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; + if (sti->index_entries[0].pos > last_start) + last_start = sti->index_entries[0].pos; + if (sti->index_entries[n - 1].pos < first_end) + first_end = sti->index_entries[n - 1].pos; } avio_seek(s->pb, oldpos, SEEK_SET); @@ -1817,6 +1829,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, { AVIContext *avi = s->priv_data; AVStream *st; + FFStream *sti; int i, index; int64_t pos, pos_min; AVIStream *ast; @@ -1835,25 +1848,26 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, av_assert0(stream_index >= 0); st = s->streams[stream_index]; + sti = ffstream(st); ast = st->priv_data; index = av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags); if (index < 0) { - if (st->internal->nb_index_entries > 0) + if (sti->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->internal->index_entries[0].timestamp, - st->internal->index_entries[st->internal->nb_index_entries - 1].timestamp); + sti->index_entries[0].timestamp, + sti->index_entries[sti->nb_index_entries - 1].timestamp); return AVERROR_INVALIDDATA; } /* find the position */ - pos = st->internal->index_entries[index].pos; - timestamp = st->internal->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); + pos = sti->index_entries[index].pos; + timestamp = sti->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); av_log(s, AV_LOG_TRACE, "XX %"PRId64" %d %"PRId64"\n", - timestamp, index, st->internal->index_entries[index].timestamp); + timestamp, index, sti->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 */ @@ -1874,6 +1888,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, pos_min = pos; for (i = 0; i < s->nb_streams; i++) { AVStream *st2 = s->streams[i]; + FFStream *const sti2 = ffstream(st2); AVIStream *ast2 = st2->priv_data; ast2->packet_size = @@ -1884,7 +1899,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, continue; } - if (st2->internal->nb_index_entries <= 0) + if (sti2->nb_index_entries <= 0) continue; // av_assert1(st2->codecpar->block_align); @@ -1898,14 +1913,15 @@ 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->internal->index_entries[index].pos; + ast2->seek_pos = sti2->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]; + FFStream *const sti2 = ffstream(st2); AVIStream *ast2 = st2->priv_data; - if (ast2->sub_ctx || st2->internal->nb_index_entries <= 0) + if (ast2->sub_ctx || sti2->nb_index_entries <= 0) continue; index = av_index_search_timestamp( @@ -1914,9 +1930,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->internal->index_entries[index-1].pos >= pos_min) + while (!avi->non_interleaved && index > 0 && sti2->index_entries[index-1].pos >= pos_min) index--; - ast2->frame_offset = st2->internal->index_entries[index].timestamp; + ast2->frame_offset = sti2->index_entries[index].timestamp; } /* do the seek */ |