summaryrefslogtreecommitdiff
path: root/libavformat/avidec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/avidec.c')
-rw-r--r--libavformat/avidec.c138
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 */