diff --git a/libavformat/demux.c b/libavformat/demux.c index 4fd22c4934..2796209239 100644 --- a/libavformat/demux.c +++ b/libavformat/demux.c @@ -1159,7 +1159,10 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, AVPacket *out_pkt = si->parse_pkt; AVStream *st = s->streams[stream_index]; FFStream *const sti = ffstream(st); + const AVPacketSideData *sd = NULL; const uint8_t *data = pkt->data; + uint8_t *extradata = sti->avctx->extradata; + int extradata_size = sti->avctx->extradata_size; int size = pkt->size; int ret = 0, got_output = flush; @@ -1168,6 +1171,16 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, compute_pkt_fields(s, st, sti->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE); } + if (pkt->side_data_elems) + sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, + AV_PKT_DATA_NEW_EXTRADATA); + if (sd) { + av_assert1(size && !flush); + + sti->avctx->extradata = sd->data; + sti->avctx->extradata_size = sd->size; + } + while (size > 0 || (flush && got_output)) { int64_t next_pts = pkt->pts; int64_t next_dts = pkt->dts; @@ -1261,6 +1274,11 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, } fail: + if (sd) { + sti->avctx->extradata = extradata; + sti->avctx->extradata_size = extradata_size; + } + if (ret < 0) av_packet_unref(out_pkt); av_packet_unref(pkt); @@ -1353,6 +1371,11 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) st->event_flags |= AVSTREAM_EVENT_FLAG_NEW_PACKETS; + int new_extradata = !!av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, + AV_PKT_DATA_NEW_EXTRADATA); + if (new_extradata) + sti->need_context_update = 1; + /* update context if required */ if (sti->need_context_update) { if (avcodec_is_open(sti->avctx)) { @@ -1363,8 +1386,9 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) return ret; } - /* close parser, because it depends on the codec */ - if (sti->parser && sti->avctx->codec_id != st->codecpar->codec_id) { + /* close parser, because it depends on the codec and extradata */ + if (sti->parser && + (sti->avctx->codec_id != st->codecpar->codec_id || new_extradata)) { av_parser_close(sti->parser); sti->parser = NULL; }