diff options
Diffstat (limited to 'libavformat/matroskadec.c')
-rw-r--r-- | libavformat/matroskadec.c | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index b38b1b418b..500c83ac3a 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2338,7 +2338,6 @@ static int matroska_parse_tracks(AVFormatContext *s) { MatroskaDemuxContext *matroska = s->priv_data; MatroskaTrack *tracks = matroska->tracks.elem; - AVStream *st; int i, j, ret; int k; @@ -2352,6 +2351,8 @@ static int matroska_parse_tracks(AVFormatContext *s) int extradata_offset = 0; uint32_t fourcc = 0; FFIOContext b; + AVStream *st; + FFStream *sti; char* key_id_base64 = NULL; int bit_depth = -1; @@ -2486,6 +2487,7 @@ static int matroska_parse_tracks(AVFormatContext *s) av_free(key_id_base64); return AVERROR(ENOMEM); } + sti = ffstream(st); if (key_id_base64) { /* export encryption key id as base64 metadata tag */ @@ -2802,7 +2804,7 @@ static int matroska_parse_tracks(AVFormatContext *s) 255); } if (st->codecpar->codec_id != AV_CODEC_ID_HEVC) - st->internal->need_parsing = AVSTREAM_PARSE_HEADERS; + sti->need_parsing = AVSTREAM_PARSE_HEADERS; if (track->default_duration) { int div = track->default_duration <= INT64_MAX ? 1 : 2; @@ -2861,9 +2863,9 @@ static int matroska_parse_tracks(AVFormatContext *s) if (st->codecpar->codec_id == AV_CODEC_ID_MP3 || st->codecpar->codec_id == AV_CODEC_ID_MLP || st->codecpar->codec_id == AV_CODEC_ID_TRUEHD) - st->internal->need_parsing = AVSTREAM_PARSE_FULL; + sti->need_parsing = AVSTREAM_PARSE_FULL; else if (st->codecpar->codec_id != AV_CODEC_ID_AAC) - st->internal->need_parsing = AVSTREAM_PARSE_HEADERS; + sti->need_parsing = AVSTREAM_PARSE_HEADERS; if (track->codec_delay > 0) { st->codecpar->initial_padding = av_rescale_q(track->codec_delay, (AVRational){1, 1000000000}, @@ -3652,7 +3654,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf return res; if (is_keyframe) matroska->skip_to_keyframe = 0; - else if (!st->internal->skip_to_keyframe) { + else if (!ffstream(st)->skip_to_keyframe) { av_log(matroska->ctx, AV_LOG_ERROR, "File is broken, keyframes not correctly marked!\n"); matroska->skip_to_keyframe = 0; } @@ -3814,6 +3816,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, MatroskaDemuxContext *matroska = s->priv_data; MatroskaTrack *tracks = NULL; AVStream *st = s->streams[stream_index]; + FFStream *const sti = ffstream(st); int i, index; /* Parse the CUES now since we need the index data to seek. */ @@ -3822,13 +3825,15 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, matroska_parse_cues(matroska); } - if (!st->internal->nb_index_entries) + if (!sti->nb_index_entries) goto err; - timestamp = FFMAX(timestamp, st->internal->index_entries[0].timestamp); + timestamp = FFMAX(timestamp, sti->index_entries[0].timestamp); - if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->internal->nb_index_entries - 1) { - matroska_reset_status(matroska, 0, st->internal->index_entries[st->internal->nb_index_entries - 1].pos); - while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->internal->nb_index_entries - 1) { + if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || + index == sti->nb_index_entries - 1) { + matroska_reset_status(matroska, 0, sti->index_entries[sti->nb_index_entries - 1].pos); + while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || + index == sti->nb_index_entries - 1) { matroska_clear_queue(matroska); if (matroska_parse_cluster(matroska) < 0) break; @@ -3836,7 +3841,8 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, } matroska_clear_queue(matroska); - if (index < 0 || (matroska->cues_parsing_deferred < 0 && index == st->internal->nb_index_entries - 1)) + if (index < 0 || (matroska->cues_parsing_deferred < 0 && + index == sti->nb_index_entries - 1)) goto err; tracks = matroska->tracks.elem; @@ -3848,17 +3854,17 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, } /* We seek to a level 1 element, so set the appropriate status. */ - matroska_reset_status(matroska, 0, st->internal->index_entries[index].pos); + matroska_reset_status(matroska, 0, sti->index_entries[index].pos); if (flags & AVSEEK_FLAG_ANY) { - st->internal->skip_to_keyframe = 0; + sti->skip_to_keyframe = 0; matroska->skip_to_timecode = timestamp; } else { - st->internal->skip_to_keyframe = 1; - matroska->skip_to_timecode = st->internal->index_entries[index].timestamp; + sti->skip_to_keyframe = 1; + matroska->skip_to_timecode = sti->index_entries[index].timestamp; } matroska->skip_to_keyframe = 1; matroska->done = 0; - avpriv_update_cur_dts(s, st, st->internal->index_entries[index].timestamp); + avpriv_update_cur_dts(s, st, sti->index_entries[index].timestamp); return 0; err: // slightly hackish but allows proper fallback to @@ -3866,7 +3872,7 @@ err: matroska_reset_status(matroska, 0, -1); matroska->resync_pos = -1; matroska_clear_queue(matroska); - st->internal->skip_to_keyframe = + sti->skip_to_keyframe = matroska->skip_to_keyframe = 0; matroska->done = 0; return -1; @@ -3902,10 +3908,12 @@ typedef struct { */ static CueDesc get_cue_desc(AVFormatContext *s, int64_t ts, int64_t cues_start) { MatroskaDemuxContext *matroska = s->priv_data; + FFStream *const sti = ffstream(s->streams[0]); + AVIndexEntry *const index_entries = sti->index_entries; + int nb_index_entries = sti->nb_index_entries; CueDesc cue_desc; int i; - int nb_index_entries = s->streams[0]->internal->nb_index_entries; - AVIndexEntry *index_entries = s->streams[0]->internal->index_entries; + if (ts >= matroska->duration * matroska->time_scale) return (CueDesc) {-1, -1, -1, -1}; for (i = 1; i < nb_index_entries; i++) { if (index_entries[i - 1].timestamp * matroska->time_scale <= ts && @@ -3932,14 +3940,20 @@ static CueDesc get_cue_desc(AVFormatContext *s, int64_t ts, int64_t cues_start) static int webm_clusters_start_with_keyframe(AVFormatContext *s) { MatroskaDemuxContext *matroska = s->priv_data; + AVStream *const st = s->streams[0]; + FFStream *const sti = ffstream(st); uint32_t id = matroska->current_id; int64_t cluster_pos, before_pos; int index, rv = 1; - if (s->streams[0]->internal->nb_index_entries <= 0) return 0; + + if (sti->nb_index_entries <= 0) + return 0; + // seek to the first cluster using cues. - index = av_index_search_timestamp(s->streams[0], 0, 0); - if (index < 0) return 0; - cluster_pos = s->streams[0]->internal->index_entries[index].pos; + index = av_index_search_timestamp(st, 0, 0); + if (index < 0) + return 0; + cluster_pos = sti->index_entries[index].pos; before_pos = avio_tell(s->pb); while (1) { uint64_t cluster_id, cluster_length; @@ -4060,12 +4074,12 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t { MatroskaDemuxContext *matroska = s->priv_data; AVStream *st = s->streams[0]; + FFStream *const sti = ffstream(st); double bandwidth = 0.0; - int i; - for (i = 0; i < st->internal->nb_index_entries; i++) { + for (int i = 0; i < sti->nb_index_entries; i++) { int64_t prebuffer_ns = 1000000000; - int64_t time_ns = st->internal->index_entries[i].timestamp * matroska->time_scale; + int64_t time_ns = sti->index_entries[i].timestamp * matroska->time_scale; double nano_seconds_per_second = 1000000000.0; int64_t prebuffered_ns = time_ns + prebuffer_ns; double prebuffer_bytes = 0.0; @@ -4149,6 +4163,7 @@ static int webm_dash_manifest_cues(AVFormatContext *s, int64_t init_range) EbmlList *seekhead_list = &matroska->seekhead; MatroskaSeekhead *seekhead = seekhead_list->elem; AVStream *const st = s->streams[0]; + FFStream *const sti = ffstream(st); AVBPrint bprint; char *buf; int64_t cues_start = -1, cues_end = -1, before_pos, bandwidth; @@ -4184,7 +4199,7 @@ static int webm_dash_manifest_cues(AVFormatContext *s, int64_t init_range) // parse the cues matroska_parse_cues(matroska); - if (!st->internal->nb_index_entries) + if (!sti->nb_index_entries) return AVERROR_INVALIDDATA; // cues start @@ -4209,8 +4224,8 @@ static int webm_dash_manifest_cues(AVFormatContext *s, int64_t init_range) // Store cue point timestamps as a comma separated list // for checking subsegment alignment in the muxer. av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED); - for (int i = 0; i < st->internal->nb_index_entries; i++) - av_bprintf(&bprint, "%" PRId64",", st->internal->index_entries[i].timestamp); + for (int i = 0; i < sti->nb_index_entries; i++) + av_bprintf(&bprint, "%" PRId64",", sti->index_entries[i].timestamp); if (!av_bprint_is_complete(&bprint)) { av_bprint_finalize(&bprint, NULL); return AVERROR(ENOMEM); |