diff mbox series

[FFmpeg-devel,3/5,v2] avformat: move AVStream.{parser, need_parsing} to AVStreamInternal

Message ID 20210504014947.5115-1-jamrial@gmail.com
State Accepted
Commit b9c5fdf6027010d15ee90a43aa023e45a5189097
Headers show
Series Untitled series #3909
Related show

Commit Message

James Almer May 4, 2021, 1:49 a.m. UTC
Those are private fields, no reason to have them exposed in a public
header.

Signed-off-by: James Almer <jamrial@gmail.com>
---
Now also porting the v4l2 outdev, which unfortunately requires an accessor.
If anyone with a v4l2 capable machine wants to check if not setting
need_parsing at all for h264 streams is an option, that'd be better.

 libavdevice/v4l2.c           |   2 +-
 libavformat/aacdec.c         |   2 +-
 libavformat/aadec.c          |   6 +-
 libavformat/acm.c            |   2 +-
 libavformat/asfdec_f.c       |  10 +--
 libavformat/av1dec.c         |   2 +-
 libavformat/avformat.h       |   4 --
 libavformat/avidec.c         |  16 ++---
 libavformat/dtshddec.c       |   2 +-
 libavformat/electronicarts.c |   2 +-
 libavformat/flacdec.c        |   2 +-
 libavformat/flvdec.c         |   4 +-
 libavformat/gxf.c            |   6 +-
 libavformat/img2dec.c        |   4 +-
 libavformat/internal.h       |   6 ++
 libavformat/ipudec.c         |   2 +-
 libavformat/iv8.c            |   2 +-
 libavformat/ivfdec.c         |   2 +-
 libavformat/lmlm4.c          |   4 +-
 libavformat/loasdec.c        |   2 +-
 libavformat/lxfdec.c         |   2 +-
 libavformat/matroskadec.c    |   6 +-
 libavformat/mgsts.c          |   2 +-
 libavformat/mov.c            |  18 +++---
 libavformat/mp3dec.c         |   2 +-
 libavformat/mpeg.c           |   2 +-
 libavformat/mpegts.c         |  14 ++---
 libavformat/msf.c            |   2 +-
 libavformat/mtv.c            |   2 +-
 libavformat/mxfdec.c         |   8 +--
 libavformat/ncdec.c          |   2 +-
 libavformat/nsvdec.c         |   4 +-
 libavformat/nuv.c            |   2 +-
 libavformat/oggparseflac.c   |   2 +-
 libavformat/oggparseogm.c    |   4 +-
 libavformat/oggparsetheora.c |   2 +-
 libavformat/oggparsevp8.c    |   2 +-
 libavformat/omadec.c         |   2 +-
 libavformat/pva.c            |   4 +-
 libavformat/rawdec.c         |   4 +-
 libavformat/rmdec.c          |   8 +--
 libavformat/rtpdec_asf.c     |   4 +-
 libavformat/rtsp.c           |   2 +-
 libavformat/s337m.c          |   3 +-
 libavformat/sdr2.c           |   2 +-
 libavformat/segafilm.c       |   2 +-
 libavformat/swfdec.c         |   2 +-
 libavformat/takdec.c         |   2 +-
 libavformat/ty.c             |   4 +-
 libavformat/utils.c          | 118 ++++++++++++++++++-----------------
 libavformat/wavdec.c         |   6 +-
 libavformat/wtvdec.c         |   2 +-
 libavformat/xvag.c           |   2 +-
 libavformat/xwma.c           |   2 +-
 54 files changed, 168 insertions(+), 159 deletions(-)

Comments

Andreas Rheinhardt May 6, 2021, 6:31 p.m. UTC | #1
James Almer:
> Those are private fields, no reason to have them exposed in a public
> header.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> Now also porting the v4l2 outdev, which unfortunately requires an accessor.
> If anyone with a v4l2 capable machine wants to check if not setting
> need_parsing at all for h264 streams is an option, that'd be better.
> 

Alternatively one could just move needs_parsing to the beginning of
AVStreamInternal.

>  libavdevice/v4l2.c           |   2 +-
>  libavformat/aacdec.c         |   2 +-
>  libavformat/aadec.c          |   6 +-
>  libavformat/acm.c            |   2 +-
>  libavformat/asfdec_f.c       |  10 +--
>  libavformat/av1dec.c         |   2 +-
>  libavformat/avformat.h       |   4 --
>  libavformat/avidec.c         |  16 ++---
>  libavformat/dtshddec.c       |   2 +-
>  libavformat/electronicarts.c |   2 +-
>  libavformat/flacdec.c        |   2 +-
>  libavformat/flvdec.c         |   4 +-
>  libavformat/gxf.c            |   6 +-
>  libavformat/img2dec.c        |   4 +-
>  libavformat/internal.h       |   6 ++
>  libavformat/ipudec.c         |   2 +-
>  libavformat/iv8.c            |   2 +-
>  libavformat/ivfdec.c         |   2 +-
>  libavformat/lmlm4.c          |   4 +-
>  libavformat/loasdec.c        |   2 +-
>  libavformat/lxfdec.c         |   2 +-
>  libavformat/matroskadec.c    |   6 +-
>  libavformat/mgsts.c          |   2 +-
>  libavformat/mov.c            |  18 +++---
>  libavformat/mp3dec.c         |   2 +-
>  libavformat/mpeg.c           |   2 +-
>  libavformat/mpegts.c         |  14 ++---
>  libavformat/msf.c            |   2 +-
>  libavformat/mtv.c            |   2 +-
>  libavformat/mxfdec.c         |   8 +--
>  libavformat/ncdec.c          |   2 +-
>  libavformat/nsvdec.c         |   4 +-
>  libavformat/nuv.c            |   2 +-
>  libavformat/oggparseflac.c   |   2 +-
>  libavformat/oggparseogm.c    |   4 +-
>  libavformat/oggparsetheora.c |   2 +-
>  libavformat/oggparsevp8.c    |   2 +-
>  libavformat/omadec.c         |   2 +-
>  libavformat/pva.c            |   4 +-
>  libavformat/rawdec.c         |   4 +-
>  libavformat/rmdec.c          |   8 +--
>  libavformat/rtpdec_asf.c     |   4 +-
>  libavformat/rtsp.c           |   2 +-
>  libavformat/s337m.c          |   3 +-
>  libavformat/sdr2.c           |   2 +-
>  libavformat/segafilm.c       |   2 +-
>  libavformat/swfdec.c         |   2 +-
>  libavformat/takdec.c         |   2 +-
>  libavformat/ty.c             |   4 +-
>  libavformat/utils.c          | 118 ++++++++++++++++++-----------------
>  libavformat/wavdec.c         |   6 +-
>  libavformat/wtvdec.c         |   2 +-
>  libavformat/xvag.c           |   2 +-
>  libavformat/xwma.c           |   2 +-
>  54 files changed, 168 insertions(+), 159 deletions(-)
> 
> diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
> index a5149a9132..981b6207fb 100644
> --- a/libavdevice/v4l2.c
> +++ b/libavdevice/v4l2.c
> @@ -961,7 +961,7 @@ static int v4l2_read_header(AVFormatContext *ctx)
>          st->codecpar->codec_tag =
>              avcodec_pix_fmt_to_codec_tag(st->codecpar->format);
>      else if (codec_id == AV_CODEC_ID_H264) {
> -        st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
> +        avpriv_stream_set_need_parsing(st, AVSTREAM_PARSE_FULL_ONCE);
>      }
>      if (desired_format == V4L2_PIX_FMT_YVU420)
>          st->codecpar->codec_tag = MKTAG('Y', 'V', '1', '2');
> diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
> index ba468909e9..94e39f592f 100644
> --- a/libavformat/aacdec.c
> +++ b/libavformat/aacdec.c
> @@ -112,7 +112,7 @@ static int adts_aac_read_header(AVFormatContext *s)
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id   = s->iformat->raw_codec_id;
> -    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
>  
>      ff_id3v1_read(s);
>      if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
> diff --git a/libavformat/aadec.c b/libavformat/aadec.c
> index 21051d79b8..9fe24d5d53 100644
> --- a/libavformat/aadec.c
> +++ b/libavformat/aadec.c
> @@ -183,7 +183,7 @@ static int aa_read_header(AVFormatContext *s)
>      if (!strcmp(codec_name, "mp332")) {
>          st->codecpar->codec_id = AV_CODEC_ID_MP3;
>          st->codecpar->sample_rate = 22050;
> -        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +        st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>          avpriv_set_pts_info(st, 64, 8, 32000 * TIMEPREC);
>          // encoded audio frame is MP3_FRAME_SIZE bytes (+1 with padding, unlikely)
>      } else if (!strcmp(codec_name, "acelp85")) {
> @@ -192,7 +192,7 @@ static int aa_read_header(AVFormatContext *s)
>          st->codecpar->channels = 1;
>          st->codecpar->sample_rate = 8500;
>          st->codecpar->bit_rate = 8500;
> -        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +        st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>          avpriv_set_pts_info(st, 64, 8, 8500 * TIMEPREC);
>      } else if (!strcmp(codec_name, "acelp16")) {
>          st->codecpar->codec_id = AV_CODEC_ID_SIPR;
> @@ -200,7 +200,7 @@ static int aa_read_header(AVFormatContext *s)
>          st->codecpar->channels = 1;
>          st->codecpar->sample_rate = 16000;
>          st->codecpar->bit_rate = 16000;
> -        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +        st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>          avpriv_set_pts_info(st, 64, 8, 16000 * TIMEPREC);
>      }
>  
> diff --git a/libavformat/acm.c b/libavformat/acm.c
> index c78a408aa0..bc87b3fab9 100644
> --- a/libavformat/acm.c
> +++ b/libavformat/acm.c
> @@ -54,7 +54,7 @@ static int acm_read_header(AVFormatContext *s)
>          return AVERROR_INVALIDDATA;
>      st->start_time         = 0;
>      st->duration           = AV_RL32(st->codecpar->extradata +  4) / st->codecpar->channels;
> -    st->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
>      avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
>  
>      return 0;
> diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
> index 2e806dd452..053c815977 100644
> --- a/libavformat/asfdec_f.c
> +++ b/libavformat/asfdec_f.c
> @@ -382,9 +382,9 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
>              st->codecpar->codec_tag = 0;
>          }
>          if (st->codecpar->codec_id == AV_CODEC_ID_AAC)
> -            st->need_parsing = AVSTREAM_PARSE_NONE;
> +            st->internal->need_parsing = AVSTREAM_PARSE_NONE;
>          else
> -            st->need_parsing = AVSTREAM_PARSE_FULL;
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>          /* We have to init the frame size at some point .... */
>          pos2 = avio_tell(pb);
>          if (size >= (pos2 + 8 - pos1 + 24)) {
> @@ -443,7 +443,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
>          st->codecpar->codec_tag = tag1;
>          st->codecpar->codec_id  = ff_codec_get_id(ff_codec_bmp_tags, tag1);
>          if (tag1 == MKTAG('D', 'V', 'R', ' ')) {
> -            st->need_parsing = AVSTREAM_PARSE_FULL;
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>              /* issue658 contains wrong w/h and MS even puts a fake seq header
>               * with wrong w/h in extradata while a correct one is in the stream.
>               * maximum lameness */
> @@ -453,9 +453,9 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
>              st->codecpar->extradata_size = 0;
>          }
>          if (st->codecpar->codec_id == AV_CODEC_ID_H264)
> -            st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
>          if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4)
> -            st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
>      }
>      pos2 = avio_tell(pb);
>      avio_skip(pb, size - (pos2 - pos1 + 24));
> diff --git a/libavformat/av1dec.c b/libavformat/av1dec.c
> index b71d5d0e19..8ca804c2a3 100644
> --- a/libavformat/av1dec.c
> +++ b/libavformat/av1dec.c
> @@ -66,7 +66,7 @@ static int read_header(AVFormatContext *s, const AVRational *framerate, AVBSFCon
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>      st->codecpar->codec_id = AV_CODEC_ID_AV1;
> -    st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +    st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>  
>      st->internal->avctx->framerate = *framerate;
>      // taken from rawvideo demuxers
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index d796f02094..9ed6d333d3 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -1008,10 +1008,6 @@ typedef struct AVStream {
>       */
>      int codec_info_nb_frames;
>  
> -    /* av_read_frame() support */
> -    enum AVStreamParseType need_parsing;
> -    struct AVCodecParserContext *parser;
> -
>      /**
>       * Stream Identifier
>       * This is the MPEG-TS stream identifier +1
> diff --git a/libavformat/avidec.c b/libavformat/avidec.c
> index e0d868e074..14a2dd6cd7 100644
> --- a/libavformat/avidec.c
> +++ b/libavformat/avidec.c
> @@ -824,19 +824,19 @@ static int avi_read_header(AVFormatContext *s)
>  
>                      /* This is needed to get the pict type which is necessary
>                       * for generating correct pts. */
> -                    st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +                    st->internal->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->need_parsing = AVSTREAM_PARSE_FULL;
> +                        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>                      if (st->codecpar->codec_id == AV_CODEC_ID_RV40)
> -                        st->need_parsing = AVSTREAM_PARSE_NONE;
> +                        st->internal->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;
> +                        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>  
>                      if (st->codecpar->codec_id  == AV_CODEC_ID_AVRN &&
>                          st->codecpar->codec_tag == MKTAG('A', 'V', 'R', 'n') &&
> @@ -880,16 +880,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->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
> +                    st->internal->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->need_parsing = AVSTREAM_PARSE_NONE;
> +                        st->internal->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->need_parsing = AVSTREAM_PARSE_NONE;
> +                        st->internal->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")) {
> @@ -1052,7 +1052,7 @@ 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->need_parsing = AVSTREAM_PARSE_FULL;
> +                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>          }
>  
>      for (i = 0; i < s->nb_streams; i++) {
> diff --git a/libavformat/dtshddec.c b/libavformat/dtshddec.c
> index 48d3afbebd..2900623690 100644
> --- a/libavformat/dtshddec.c
> +++ b/libavformat/dtshddec.c
> @@ -65,7 +65,7 @@ static int dtshd_read_header(AVFormatContext *s)
>          return AVERROR(ENOMEM);
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id   = AV_CODEC_ID_DTS;
> -    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
>  
>      for (;;) {
>          chunk_type = avio_rb64(pb);
> diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
> index 8080ee7e41..4d0fddab3d 100644
> --- a/libavformat/electronicarts.c
> +++ b/libavformat/electronicarts.c
> @@ -503,7 +503,7 @@ static int init_video_stream(AVFormatContext *s, VideoProperties *video)
>      st->codecpar->codec_id    = video->codec;
>      // parsing is necessary to make FFmpeg generate correct timestamps
>      if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO)
> -        st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +        st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>      st->codecpar->codec_tag   = 0; /* no fourcc */
>      st->codecpar->width       = video->width;
>      st->codecpar->height      = video->height;
> diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
> index 4ed523f309..d4158032e4 100644
> --- a/libavformat/flacdec.c
> +++ b/libavformat/flacdec.c
> @@ -56,7 +56,7 @@ static int flac_read_header(AVFormatContext *s)
>          return AVERROR(ENOMEM);
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id = AV_CODEC_ID_FLAC;
> -    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>      /* the parameters will be extracted from the compressed bitstream */
>  
>      /* if fLaC marker is not found, assume there is no header */
> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
> index 718d690421..e6c2877a74 100644
> --- a/libavformat/flvdec.c
> +++ b/libavformat/flvdec.c
> @@ -271,7 +271,7 @@ static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
>          break;
>      case FLV_CODECID_MP3:
>          apar->codec_id      = AV_CODEC_ID_MP3;
> -        astream->need_parsing = AVSTREAM_PARSE_FULL;
> +        astream->internal->need_parsing = AVSTREAM_PARSE_FULL;
>          break;
>      case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
>          // in case metadata does not otherwise declare samplerate
> @@ -362,7 +362,7 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
>          break;
>      case FLV_CODECID_H264:
>          par->codec_id = AV_CODEC_ID_H264;
> -        vstream->need_parsing = AVSTREAM_PARSE_HEADERS;
> +        vstream->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>          ret = 3;     // not 4, reading packet type will consume one byte
>          break;
>      case FLV_CODECID_MPEG4:
> diff --git a/libavformat/gxf.c b/libavformat/gxf.c
> index 53fa302828..7d23cbd692 100644
> --- a/libavformat/gxf.c
> +++ b/libavformat/gxf.c
> @@ -130,13 +130,13 @@ static int get_sindex(AVFormatContext *s, int id, int format) {
>          case 20:
>              st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>              st->codecpar->codec_id = AV_CODEC_ID_MPEG2VIDEO;
> -            st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
> +            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
>              break;
>          case 22:
>          case 23:
>              st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>              st->codecpar->codec_id = AV_CODEC_ID_MPEG1VIDEO;
> -            st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
> +            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
>              break;
>          case 9:
>              st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
> @@ -169,7 +169,7 @@ static int get_sindex(AVFormatContext *s, int id, int format) {
>          case 29: /* AVCHD */
>              st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>              st->codecpar->codec_id = AV_CODEC_ID_H264;
> -            st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>              break;
>          // timecode tracks:
>          case 7:
> diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
> index d7a7cdaa16..aaf2ac362c 100644
> --- a/libavformat/img2dec.c
> +++ b/libavformat/img2dec.c
> @@ -209,7 +209,7 @@ int ff_img_read_header(AVFormatContext *s1)
>          s->is_pipe = 0;
>      else {
>          s->is_pipe       = 1;
> -        st->need_parsing = AVSTREAM_PARSE_FULL;
> +        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>      }
>  
>      if (s->ts_from_file == 2) {
> @@ -482,7 +482,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
>              return AVERROR_EOF;
>          if (s->frame_size > 0) {
>              size[0] = s->frame_size;
> -        } else if (!s1->streams[0]->parser) {
> +        } else if (!s1->streams[0]->internal->parser) {
>              size[0] = avio_size(s1->pb);
>          } else {
>              size[0] = 4096;
> diff --git a/libavformat/internal.h b/libavformat/internal.h
> index 6af38720c8..10fbd9b51b 100644
> --- a/libavformat/internal.h
> +++ b/libavformat/internal.h
> @@ -373,8 +373,14 @@ struct AVStreamInternal {
>       * Number of packets to buffer for codec probing
>       */
>      int probe_packets;
> +
> +    /* av_read_frame() support */
> +    enum AVStreamParseType need_parsing;
> +    struct AVCodecParserContext *parser;
>  };
>  
> +void avpriv_stream_set_need_parsing(AVStream *st, enum AVStreamParseType type);
> +
>  #ifdef __GNUC__
>  #define dynarray_add(tab, nb_ptr, elem)\
>  do {\
> diff --git a/libavformat/ipudec.c b/libavformat/ipudec.c
> index 283c798751..b76371b58c 100644
> --- a/libavformat/ipudec.c
> +++ b/libavformat/ipudec.c
> @@ -62,7 +62,7 @@ static int ipu_read_header(AVFormatContext *s)
>      st->start_time         = 0;
>      st->duration           =
>      st->nb_frames          = avio_rl32(pb);
> -    st->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
>      avpriv_set_pts_info(st, 64, 1, 25);
>  
>      return 0;
> diff --git a/libavformat/iv8.c b/libavformat/iv8.c
> index 7237e16172..b06797cbf3 100644
> --- a/libavformat/iv8.c
> +++ b/libavformat/iv8.c
> @@ -47,7 +47,7 @@ static int read_header(AVFormatContext *s)
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>      st->codecpar->codec_id = AV_CODEC_ID_MPEG4;
> -    st->need_parsing = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>      avpriv_set_pts_info(st, 64, 1, 90000);
>  
>      return 0;
> diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c
> index 3e1ea52cbf..26717c4999 100644
> --- a/libavformat/ivfdec.c
> +++ b/libavformat/ivfdec.c
> @@ -56,7 +56,7 @@ static int read_header(AVFormatContext *s)
>      st->duration          = avio_rl32(s->pb);
>      avio_skip(s->pb, 4); // unused
>  
> -    st->need_parsing      = AVSTREAM_PARSE_HEADERS;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
>  
>      if (!time_base.den || !time_base.num) {
>          av_log(s, AV_LOG_ERROR, "Invalid frame rate\n");
> diff --git a/libavformat/lmlm4.c b/libavformat/lmlm4.c
> index 99cba73a00..dbeaceab9c 100644
> --- a/libavformat/lmlm4.c
> +++ b/libavformat/lmlm4.c
> @@ -67,14 +67,14 @@ static int lmlm4_read_header(AVFormatContext *s)
>          return AVERROR(ENOMEM);
>      st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>      st->codecpar->codec_id   = AV_CODEC_ID_MPEG4;
> -    st->need_parsing      = AVSTREAM_PARSE_HEADERS;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
>      avpriv_set_pts_info(st, 64, 1001, 30000);
>  
>      if (!(st = avformat_new_stream(s, NULL)))
>          return AVERROR(ENOMEM);
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id   = AV_CODEC_ID_MP2;
> -    st->need_parsing      = AVSTREAM_PARSE_HEADERS;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
>  
>      /* the parameters will be extracted from the compressed bitstream */
>      return 0;
> diff --git a/libavformat/loasdec.c b/libavformat/loasdec.c
> index 490dd68ee0..97fabefcd7 100644
> --- a/libavformat/loasdec.c
> +++ b/libavformat/loasdec.c
> @@ -75,7 +75,7 @@ static int loas_read_header(AVFormatContext *s)
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id = s->iformat->raw_codec_id;
> -    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>  
>      //LCM of all possible AAC sample rates
>      avpriv_set_pts_info(st, 64, 1, 28224000);
> diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c
> index ebb745d360..79ccc77747 100644
> --- a/libavformat/lxfdec.c
> +++ b/libavformat/lxfdec.c
> @@ -262,7 +262,7 @@ static int lxf_read_header(AVFormatContext *s)
>      st->codecpar->bit_rate   = 1000000 * ((video_params >> 14) & 0xFF);
>      st->codecpar->codec_tag  = video_params & 0xF;
>      st->codecpar->codec_id   = ff_codec_get_id(lxf_tags, st->codecpar->codec_tag);
> -    st->need_parsing         = AVSTREAM_PARSE_HEADERS;
> +    st->internal->need_parsing         = AVSTREAM_PARSE_HEADERS;
>  
>      av_log(s, AV_LOG_DEBUG, "record: %x = %i-%02i-%02i\n",
>             record_date, 1900 + (record_date & 0x7F), (record_date >> 7) & 0xF,
> diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
> index 63faea4e35..8523261760 100644
> --- a/libavformat/matroskadec.c
> +++ b/libavformat/matroskadec.c
> @@ -2806,7 +2806,7 @@ static int matroska_parse_tracks(AVFormatContext *s)
>                            255);
>              }
>              if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
> -                st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +                st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>  
>              if (track->default_duration) {
>                  av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
> @@ -2864,9 +2864,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->need_parsing = AVSTREAM_PARSE_FULL;
> +                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>              else if (st->codecpar->codec_id != AV_CODEC_ID_AAC)
> -                st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +                st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>              if (track->codec_delay > 0) {
>                  st->codecpar->initial_padding = av_rescale_q(track->codec_delay,
>                                                               (AVRational){1, 1000000000},
> diff --git a/libavformat/mgsts.c b/libavformat/mgsts.c
> index 02f65e7b1b..5886d2475a 100644
> --- a/libavformat/mgsts.c
> +++ b/libavformat/mgsts.c
> @@ -50,7 +50,7 @@ static int read_header(AVFormatContext *s)
>      if (!st)
>          return AVERROR(ENOMEM);
>  
> -    st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +    st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>      st->start_time = 0;
>      st->nb_frames  =
>      st->duration   = avio_rb32(pb);
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index ca6a0f2db4..295a8e2b99 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -2186,7 +2186,7 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
>              switch (st->codecpar->codec_id) {
>              case AV_CODEC_ID_MP2:
>              case AV_CODEC_ID_MP3:
> -                st->need_parsing = AVSTREAM_PARSE_FULL;
> +                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>                  break;
>              }
>          }
> @@ -2424,10 +2424,10 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
>      case AV_CODEC_ID_VC1:
>      case AV_CODEC_ID_VP8:
>      case AV_CODEC_ID_VP9:
> -        st->need_parsing = AVSTREAM_PARSE_FULL;
> +        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>          break;
>      case AV_CODEC_ID_AV1:
> -        st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +        st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>          break;
>      default:
>          break;
> @@ -2773,8 +2773,8 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  
>      if (!entries) {
>          sc->keyframe_absent = 1;
> -        if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
> -            st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +        if (!st->internal->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
> +            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>          return 0;
>      }
>      if (sc->keyframes)
> @@ -4317,7 +4317,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>          && sc->stts_count > 3
>          && sc->stts_count*10 > st->nb_frames
>          && sc->time_scale == st->codecpar->sample_rate) {
> -            st->need_parsing = AVSTREAM_PARSE_FULL;
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>      }
>      /* Do not need those anymore. */
>      av_freep(&sc->chunk_offsets);
> @@ -7644,7 +7644,7 @@ static int mov_read_header(AVFormatContext *s)
>              mov->handbrake_version <= 1000000*0 + 1000*10 + 2 &&  // 0.10.2
>              st->codecpar->codec_id == AV_CODEC_ID_MP3) {
>              av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
> -            st->need_parsing = AVSTREAM_PARSE_FULL;
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>          }
>      }
>  
> @@ -7950,9 +7950,9 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
>                  sc->has_palette = 0;
>              }
>          }
> -        if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
> +        if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->internal->need_parsing && pkt->size > 4) {
>              if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
> -                st->need_parsing = AVSTREAM_PARSE_FULL;
> +                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>          }
>      }
>  
> diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
> index 611b423aea..b12cd31148 100644
> --- a/libavformat/mp3dec.c
> +++ b/libavformat/mp3dec.c
> @@ -374,7 +374,7 @@ static int mp3_read_header(AVFormatContext *s)
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id = AV_CODEC_ID_MP3;
> -    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>      st->start_time = 0;
>  
>      // lcm of all mp3 sample rates
> diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
> index fb1d54e52f..178e71d891 100644
> --- a/libavformat/mpeg.c
> +++ b/libavformat/mpeg.c
> @@ -623,7 +623,7 @@ skip:
>          st->codecpar->sample_rate = 8000;
>      }
>      st->internal->request_probe     = request_probe;
> -    st->need_parsing      = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
>  
>  found:
>      if (st->discard >= AVDISCARD_ALL)
> diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
> index 0ed108ce89..fb454b9fd3 100644
> --- a/libavformat/mpegts.c
> +++ b/libavformat/mpegts.c
> @@ -904,7 +904,7 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
>      st->priv_data         = pes;
>      st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
>      st->codecpar->codec_id   = AV_CODEC_ID_NONE;
> -    st->need_parsing      = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
>      pes->st          = st;
>      pes->stream_type = stream_type;
>  
> @@ -942,7 +942,7 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
>              sub_st->priv_data         = sub_pes;
>              sub_st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>              sub_st->codecpar->codec_id   = AV_CODEC_ID_AC3;
> -            sub_st->need_parsing      = AVSTREAM_PARSE_FULL;
> +            sub_st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
>              sub_pes->sub_st           = pes->sub_st = sub_st;
>          }
>      }
> @@ -1717,10 +1717,10 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section,
>              ff_mp4_read_dec_config_descr(s, st, &pb);
>              if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
>                  st->codecpar->extradata_size > 0)
> -                st->need_parsing = 0;
> +                st->internal->need_parsing = 0;
>              if (st->codecpar->codec_id == AV_CODEC_ID_H264 &&
>                  st->codecpar->extradata_size > 0)
> -                st->need_parsing = 0;
> +                st->internal->need_parsing = 0;
>  
>              st->codecpar->codec_type = avcodec_get_type(st->codecpar->codec_id);
>              st->internal->need_context_update = 1;
> @@ -1826,7 +1826,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
>                  ff_mp4_read_dec_config_descr(fc, st, &pb);
>                  if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
>                      st->codecpar->extradata_size > 0) {
> -                    st->need_parsing = 0;
> +                    st->internal->need_parsing = 0;
>                      st->internal->need_context_update = 1;
>                  }
>                  if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4SYSTEMS)
> @@ -1848,7 +1848,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
>              ff_mp4_read_dec_config_descr(fc, st, &pb);
>              if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
>                  st->codecpar->extradata_size > 0) {
> -                st->internal->request_probe = st->need_parsing = 0;
> +                st->internal->request_probe = st->internal->need_parsing = 0;
>                  st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>                  st->internal->need_context_update = 1;
>              }
> @@ -2035,7 +2035,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
>                  } else {
>                      avpriv_request_sample(fc, "Opus in MPEG-TS - channel_config_code > 0x8");
>                  }
> -                st->need_parsing = AVSTREAM_PARSE_FULL;
> +                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>                  st->internal->need_context_update = 1;
>              }
>          }
> diff --git a/libavformat/msf.c b/libavformat/msf.c
> index ca2b3a3bf5..43a7f7b616 100644
> --- a/libavformat/msf.c
> +++ b/libavformat/msf.c
> @@ -80,7 +80,7 @@ static int msf_read_header(AVFormatContext *s)
>              AV_WL16(st->codecpar->extradata+8, codec == 4 ? 1 : 0); /* joint stereo (repeat?) */
>              AV_WL16(st->codecpar->extradata+10, 1);
>              st->codecpar->codec_id = AV_CODEC_ID_ATRAC3;    break;
> -    case 7: st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +    case 7: st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>              st->codecpar->codec_id = AV_CODEC_ID_MP3;       break;
>      default:
>              avpriv_request_sample(s, "Codec %d", codec);
> diff --git a/libavformat/mtv.c b/libavformat/mtv.c
> index 26a0fd0ea4..d33561b6ec 100644
> --- a/libavformat/mtv.c
> +++ b/libavformat/mtv.c
> @@ -185,7 +185,7 @@ static int mtv_read_header(AVFormatContext *s)
>      st->codecpar->codec_type      = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id        = AV_CODEC_ID_MP3;
>      st->codecpar->bit_rate        = mtv->audio_br;
> -    st->need_parsing              = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing              = AVSTREAM_PARSE_FULL;
>  
>      // Jump over header
>  
> diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
> index f0c2c0b15f..3bf480a3a6 100644
> --- a/libavformat/mxfdec.c
> +++ b/libavformat/mxfdec.c
> @@ -2593,7 +2593,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
>                      }
>                  }
>              }
> -            st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>              if (material_track->sequence->origin) {
>                  av_dict_set_int(&st->metadata, "material_track_origin", material_track->sequence->origin, 0);
>              }
> @@ -2658,7 +2658,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
>                  else if (descriptor->bits_per_sample == 32)
>                      st->codecpar->codec_id = AV_CODEC_ID_PCM_S32BE;
>              } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
> -                st->need_parsing = AVSTREAM_PARSE_FULL;
> +                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>              }
>              st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id);
>          } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
> @@ -2692,7 +2692,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
>          }
>          if (st->codecpar->codec_type != AVMEDIA_TYPE_DATA && source_track->wrapping != FrameWrapped) {
>              /* TODO: decode timestamps */
> -            st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
> +            st->internal->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
>          }
>      }
>  
> @@ -3660,7 +3660,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
>                  if (next_ofs <= 0) {
>                      // If we have no way to packetize the data, then return it in chunks...
>                      if (klv.next_klv - klv.length == pos && max_data_size > MXF_MAX_CHUNK_SIZE) {
> -                        st->need_parsing = AVSTREAM_PARSE_FULL;
> +                        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>                          avpriv_request_sample(s, "Huge KLV without proper index in non-frame wrapped essence");
>                      }
>                      size = FFMIN(max_data_size, MXF_MAX_CHUNK_SIZE);
> diff --git a/libavformat/ncdec.c b/libavformat/ncdec.c
> index ff5eb189bc..3fe189e729 100644
> --- a/libavformat/ncdec.c
> +++ b/libavformat/ncdec.c
> @@ -53,7 +53,7 @@ static int nc_read_header(AVFormatContext *s)
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>      st->codecpar->codec_id   = AV_CODEC_ID_MPEG4;
> -    st->need_parsing      = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
>  
>      avpriv_set_pts_info(st, 64, 1, 100);
>  
> diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
> index b79d0dcc62..7dcc218546 100644
> --- a/libavformat/nsvdec.c
> +++ b/libavformat/nsvdec.c
> @@ -462,7 +462,7 @@ static int nsv_parse_NSVs_header(AVFormatContext *s)
>              st->codecpar->codec_tag = atag;
>              st->codecpar->codec_id = ff_codec_get_id(nsv_codec_audio_tags, atag);
>  
> -            st->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */
>  
>              /* set timebase to common denominator of ms and framerate */
>              avpriv_set_pts_info(st, 64, 1, framerate.num*1000);
> @@ -615,7 +615,7 @@ null_chunk_retry:
>              asize-=4;
>              av_log(s, AV_LOG_TRACE, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate);
>              if (fill_header) {
> -                st[NSV_ST_AUDIO]->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */
> +                st[NSV_ST_AUDIO]->internal->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */
>                  if (bps != 16) {
>                      av_log(s, AV_LOG_TRACE, "NSV AUDIO bit/sample != 16 (%d)!!!\n", bps);
>                  }
> diff --git a/libavformat/nuv.c b/libavformat/nuv.c
> index aec87f45fe..1d25d3b125 100644
> --- a/libavformat/nuv.c
> +++ b/libavformat/nuv.c
> @@ -132,7 +132,7 @@ static int get_codec_data(AVFormatContext *s, AVIOContext *pb, AVStream *vst,
>                  }
>                  ast->codecpar->codec_id = id;
>  
> -                ast->need_parsing = AVSTREAM_PARSE_FULL;
> +                ast->internal->need_parsing = AVSTREAM_PARSE_FULL;
>              } else
>                  avio_skip(pb, 4 * 4);
>  
> diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c
> index 4e85b05c67..15eeca56aa 100644
> --- a/libavformat/oggparseflac.c
> +++ b/libavformat/oggparseflac.c
> @@ -59,7 +59,7 @@ flac_header (AVFormatContext * s, int idx)
>  
>          st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>          st->codecpar->codec_id = AV_CODEC_ID_FLAC;
> -        st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +        st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>  
>          if ((ret = ff_alloc_extradata(st->codecpar, FLAC_STREAMINFO_SIZE)) < 0)
>              return ret;
> diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c
> index 469b229995..a8319b9dfa 100644
> --- a/libavformat/oggparseogm.c
> +++ b/libavformat/oggparseogm.c
> @@ -60,7 +60,7 @@ ogm_header(AVFormatContext *s, int idx)
>              st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag);
>              st->codecpar->codec_tag = tag;
>              if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4)
> -                st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +                st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>          } else if (bytestream2_peek_byte(&p) == 't') {
>              st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
>              st->codecpar->codec_id = AV_CODEC_ID_TEXT;
> @@ -76,7 +76,7 @@ ogm_header(AVFormatContext *s, int idx)
>              st->codecpar->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid);
>              // our parser completely breaks AAC in Ogg
>              if (st->codecpar->codec_id != AV_CODEC_ID_AAC)
> -                st->need_parsing = AVSTREAM_PARSE_FULL;
> +                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>          }
>  
>          size        = bytestream2_get_le32(&p);
> diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c
> index d1064e4328..28684f6ea9 100644
> --- a/libavformat/oggparsetheora.c
> +++ b/libavformat/oggparsetheora.c
> @@ -112,7 +112,7 @@ static int theora_header(AVFormatContext *s, int idx)
>  
>          st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>          st->codecpar->codec_id   = AV_CODEC_ID_THEORA;
> -        st->need_parsing      = AVSTREAM_PARSE_HEADERS;
> +        st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
>      }
>      break;
>      case 0x81:
> diff --git a/libavformat/oggparsevp8.c b/libavformat/oggparsevp8.c
> index b76ac71cc5..85b3627c9c 100644
> --- a/libavformat/oggparsevp8.c
> +++ b/libavformat/oggparsevp8.c
> @@ -61,7 +61,7 @@ static int vp8_header(AVFormatContext *s, int idx)
>          avpriv_set_pts_info(st, 64, framerate.den, framerate.num);
>          st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>          st->codecpar->codec_id   = AV_CODEC_ID_VP8;
> -        st->need_parsing      = AVSTREAM_PARSE_HEADERS;
> +        st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
>          break;
>      case 0x02:
>          if (p[6] != 0x20)
> diff --git a/libavformat/omadec.c b/libavformat/omadec.c
> index 1c2b04212c..8891cfc4b6 100644
> --- a/libavformat/omadec.c
> +++ b/libavformat/omadec.c
> @@ -520,7 +520,7 @@ static int oma_read_header(AVFormatContext *s)
>          avpriv_set_pts_info(st, 64, 1, samplerate);
>          break;
>      case OMA_CODECID_MP3:
> -        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +        st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>          framesize = 1024;
>          break;
>      case OMA_CODECID_LPCM:
> diff --git a/libavformat/pva.c b/libavformat/pva.c
> index 8e3013a496..ff30746bcb 100644
> --- a/libavformat/pva.c
> +++ b/libavformat/pva.c
> @@ -61,7 +61,7 @@ static int pva_read_header(AVFormatContext *s) {
>          return AVERROR(ENOMEM);
>      st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>      st->codecpar->codec_id   = AV_CODEC_ID_MPEG2VIDEO;
> -    st->need_parsing      = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
>      avpriv_set_pts_info(st, 32, 1, 90000);
>      av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME);
>  
> @@ -69,7 +69,7 @@ static int pva_read_header(AVFormatContext *s) {
>          return AVERROR(ENOMEM);
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id   = AV_CODEC_ID_MP2;
> -    st->need_parsing      = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
>      avpriv_set_pts_info(st, 33, 1, 90000);
>      av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME);
>  
> diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c
> index c162b52940..a1f593c66a 100644
> --- a/libavformat/rawdec.c
> +++ b/libavformat/rawdec.c
> @@ -60,7 +60,7 @@ int ff_raw_audio_read_header(AVFormatContext *s)
>          return AVERROR(ENOMEM);
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id = s->iformat->raw_codec_id;
> -    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>      st->start_time = 0;
>      /* the parameters will be extracted from the compressed bitstream */
>  
> @@ -83,7 +83,7 @@ int ff_raw_video_read_header(AVFormatContext *s)
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>      st->codecpar->codec_id = s->iformat->raw_codec_id;
> -    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>  
>      st->internal->avctx->framerate = s1->framerate;
>      avpriv_set_pts_info(st, 64, 1, 1200000);
> diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
> index 538f549495..68b5c3b75a 100644
> --- a/libavformat/rmdec.c
> +++ b/libavformat/rmdec.c
> @@ -204,7 +204,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
>  
>          switch (st->codecpar->codec_id) {
>          case AV_CODEC_ID_AC3:
> -            st->need_parsing = AVSTREAM_PARSE_FULL;
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>              break;
>          case AV_CODEC_ID_RA_288:
>              st->codecpar->extradata_size= 0;
> @@ -213,7 +213,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
>              st->codecpar->block_align = coded_framesize;
>              break;
>          case AV_CODEC_ID_COOK:
> -            st->need_parsing = AVSTREAM_PARSE_HEADERS;
> +            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
>          case AV_CODEC_ID_ATRAC3:
>          case AV_CODEC_ID_SIPR:
>              if (read_all) {
> @@ -237,7 +237,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
>                      return -1;
>                  }
>                  st->codecpar->block_align = ff_sipr_subpk_size[flavor];
> -                st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +                st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>              } else {
>                  if(sub_packet_size <= 0){
>                      av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n");
> @@ -390,7 +390,7 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb,
>          avio_skip(pb, 2); // looks like bits per sample
>          avio_skip(pb, 4); // always zero?
>          st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
> -        st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
> +        st->internal->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
>          fps = avio_rb32(pb);
>  
>          if ((ret = rm_read_extradata(s, pb, st->codecpar, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)
> diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
> index 2749ad1380..f6e7f00bbe 100644
> --- a/libavformat/rtpdec_asf.c
> +++ b/libavformat/rtpdec_asf.c
> @@ -167,8 +167,8 @@ static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index,
>                  if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) {
>                      avcodec_parameters_copy(s->streams[stream_index]->codecpar,
>                                              rt->asf_ctx->streams[i]->codecpar);
> -                    s->streams[stream_index]->need_parsing =
> -                        rt->asf_ctx->streams[i]->need_parsing;
> +                    s->streams[stream_index]->internal->need_parsing =
> +                        rt->asf_ctx->streams[i]->internal->need_parsing;
>                      avpriv_set_pts_info(s->streams[stream_index], 32, 1, 1000);
>                  }
>             }
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index 3899c26fa4..9f509a229f 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -218,7 +218,7 @@ static void init_rtp_handler(const RTPDynamicProtocolHandler *handler,
>          par->codec_id          = handler->codec_id;
>      rtsp_st->dynamic_handler = handler;
>      if (st)
> -        st->need_parsing = handler->need_parsing;
> +        st->internal->need_parsing = handler->need_parsing;
>      if (handler->priv_data_size) {
>          rtsp_st->dynamic_protocol_context = av_mallocz(handler->priv_data_size);
>          if (!rtsp_st->dynamic_protocol_context)
> diff --git a/libavformat/s337m.c b/libavformat/s337m.c
> index 37e93db7d5..e1d921c303 100644
> --- a/libavformat/s337m.c
> +++ b/libavformat/s337m.c
> @@ -20,6 +20,7 @@
>  
>  #include "libavutil/intreadwrite.h"
>  #include "avformat.h"
> +#include "internal.h"
>  #include "spdif.h"
>  
>  #define MARKER_16LE         0x72F81F4E
> @@ -180,7 +181,7 @@ static int s337m_read_packet(AVFormatContext *s, AVPacket *pkt)
>          }
>          st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>          st->codecpar->codec_id   = codec;
> -        st->need_parsing         = AVSTREAM_PARSE_HEADERS;
> +        st->internal->need_parsing         = AVSTREAM_PARSE_HEADERS;
>      }
>  
>      return 0;
> diff --git a/libavformat/sdr2.c b/libavformat/sdr2.c
> index 373116a4a6..0f506fd074 100644
> --- a/libavformat/sdr2.c
> +++ b/libavformat/sdr2.c
> @@ -51,7 +51,7 @@ static int sdr2_read_header(AVFormatContext *s)
>      st->codecpar->width      = avio_rl32(s->pb);
>      st->codecpar->height     = avio_rl32(s->pb);
>      st->codecpar->codec_id   = AV_CODEC_ID_H264;
> -    st->need_parsing      = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
>  
>      ast->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
>      ast->codecpar->channels    = 1;
> diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
> index 4b4327a179..05b4d9e6a8 100644
> --- a/libavformat/segafilm.c
> +++ b/libavformat/segafilm.c
> @@ -183,7 +183,7 @@ static int film_read_header(AVFormatContext *s)
>          if (film->audio_type == AV_CODEC_ID_ADPCM_ADX) {
>              st->codecpar->bits_per_coded_sample = 18 * 8 / 32;
>              st->codecpar->block_align = st->codecpar->channels * 18;
> -            st->need_parsing = AVSTREAM_PARSE_FULL;
> +            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
>          } else {
>              st->codecpar->bits_per_coded_sample = film->audio_bits;
>              st->codecpar->block_align = st->codecpar->channels *
> diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
> index f5a98e8b53..8eda80b4f6 100644
> --- a/libavformat/swfdec.c
> +++ b/libavformat/swfdec.c
> @@ -204,7 +204,7 @@ static AVStream *create_new_audio_stream(AVFormatContext *s, int id, int info)
>      }
>      ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      ast->codecpar->codec_id   = ff_codec_get_id(swf_audio_codec_tags, info>>4 & 15);
> -    ast->need_parsing = AVSTREAM_PARSE_FULL;
> +    ast->internal->need_parsing = AVSTREAM_PARSE_FULL;
>      sample_rate_code = info>>2 & 3;
>      sample_size_code = info>>1 & 1;
>      if (!sample_size_code && ast->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE)
> diff --git a/libavformat/takdec.c b/libavformat/takdec.c
> index 46c500efef..cbb9a9345e 100644
> --- a/libavformat/takdec.c
> +++ b/libavformat/takdec.c
> @@ -65,7 +65,7 @@ static int tak_read_header(AVFormatContext *s)
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id   = AV_CODEC_ID_TAK;
> -    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
>  
>      tc->mlast_frame = 0;
>      if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
> diff --git a/libavformat/ty.c b/libavformat/ty.c
> index 8830467f99..5bb5d4267b 100644
> --- a/libavformat/ty.c
> +++ b/libavformat/ty.c
> @@ -308,7 +308,7 @@ static int ty_read_header(AVFormatContext *s)
>          return AVERROR(ENOMEM);
>      st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
>      st->codecpar->codec_id   = AV_CODEC_ID_MPEG2VIDEO;
> -    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
>      avpriv_set_pts_info(st, 64, 1, 90000);
>  
>      ast = avformat_new_stream(s, NULL);
> @@ -318,7 +318,7 @@ static int ty_read_header(AVFormatContext *s)
>  
>      if (ty->audio_type == TIVO_AUDIO_MPEG) {
>          ast->codecpar->codec_id = AV_CODEC_ID_MP2;
> -        ast->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
> +        ast->internal->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
>      } else {
>          ast->codecpar->codec_id = AV_CODEC_ID_AC3;
>      }
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index df6d9b5cf6..85f7b2e1cb 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -123,7 +123,12 @@ int64_t av_stream_get_end_pts(const AVStream *st)
>  
>  struct AVCodecParserContext *av_stream_get_parser(const AVStream *st)
>  {
> -    return st->parser;
> +    return st->internal->parser;
> +}
> +
> +void avpriv_stream_set_need_parsing(AVStream *st, enum AVStreamParseType type)
> +{
> +    st->internal->need_parsing = type;
>  }
>  
>  void av_format_inject_global_side_data(AVFormatContext *s)
> @@ -457,9 +462,9 @@ static int update_stream_avctx(AVFormatContext *s)
>              continue;
>  
>          /* close parser, because it depends on the codec */
> -        if (st->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
> -            av_parser_close(st->parser);
> -            st->parser = NULL;
> +        if (st->internal->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
> +            av_parser_close(st->internal->parser);
> +            st->internal->parser = NULL;
>          }
>  
>          /* update internal codec context, for the parser */
> @@ -1256,7 +1261,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
>  
>      /* Correct timestamps with byte offset if demuxers only have timestamps
>       * on packet boundaries */
> -    if (pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size) {
> +    if (pc && st->internal->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size) {
>          /* this will estimate bitrate based on this frame's duration and size */
>          offset = av_rescale(pc->offset, pkt->duration, pkt->size);
>          if (pkt->pts != AV_NOPTS_VALUE)
> @@ -1365,9 +1370,9 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
>      int size      = pkt->size;
>      int ret = 0, got_output = flush;
>  
> -    if (!size && !flush && st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) {
> +    if (!size && !flush && st->internal->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) {
>          // preserve 0-size sync packets
> -        compute_pkt_fields(s, st, st->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
> +        compute_pkt_fields(s, st, st->internal->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
>      }
>  
>      while (size > 0 || (flush && got_output)) {
> @@ -1375,7 +1380,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
>          int64_t next_pts = pkt->pts;
>          int64_t next_dts = pkt->dts;
>  
> -        len = av_parser_parse2(st->parser, st->internal->avctx,
> +        len = av_parser_parse2(st->internal->parser, st->internal->avctx,
>                                 &out_pkt->data, &out_pkt->size, data, size,
>                                 pkt->pts, pkt->dts, pkt->pos);
>  
> @@ -1394,7 +1399,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
>          if (pkt->buf && out_pkt->data == pkt->data) {
>              /* reference pkt->buf only when out_pkt->data is guaranteed to point
>               * to data in it and not in the parser's internal buffer. */
> -            /* XXX: Ensure this is the case with all parsers when st->parser->flags
> +            /* XXX: Ensure this is the case with all parsers when st->internal->parser->flags
>               * is PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */
>              out_pkt->buf = av_buffer_ref(pkt->buf);
>              if (!out_pkt->buf) {
> @@ -1415,11 +1420,11 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
>          }
>  
>          /* set the duration */
> -        out_pkt->duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0;
> +        out_pkt->duration = (st->internal->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0;
>          if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
>              if (st->internal->avctx->sample_rate > 0) {
>                  out_pkt->duration =
> -                    av_rescale_q_rnd(st->parser->duration,
> +                    av_rescale_q_rnd(st->internal->parser->duration,
>                                       (AVRational) { 1, st->internal->avctx->sample_rate },
>                                       st->time_base,
>                                       AV_ROUND_DOWN);
> @@ -1427,23 +1432,23 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
>          }
>  
>          out_pkt->stream_index = st->index;
> -        out_pkt->pts          = st->parser->pts;
> -        out_pkt->dts          = st->parser->dts;
> -        out_pkt->pos          = st->parser->pos;
> +        out_pkt->pts          = st->internal->parser->pts;
> +        out_pkt->dts          = st->internal->parser->dts;
> +        out_pkt->pos          = st->internal->parser->pos;
>          out_pkt->flags       |= pkt->flags & AV_PKT_FLAG_DISCARD;
>  
> -        if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
> -            out_pkt->pos = st->parser->frame_offset;
> +        if (st->internal->need_parsing == AVSTREAM_PARSE_FULL_RAW)
> +            out_pkt->pos = st->internal->parser->frame_offset;
>  
> -        if (st->parser->key_frame == 1 ||
> -            (st->parser->key_frame == -1 &&
> -             st->parser->pict_type == AV_PICTURE_TYPE_I))
> +        if (st->internal->parser->key_frame == 1 ||
> +            (st->internal->parser->key_frame == -1 &&
> +             st->internal->parser->pict_type == AV_PICTURE_TYPE_I))
>              out_pkt->flags |= AV_PKT_FLAG_KEY;
>  
> -        if (st->parser->key_frame == -1 && st->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY))
> +        if (st->internal->parser->key_frame == -1 && st->internal->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY))
>              out_pkt->flags |= AV_PKT_FLAG_KEY;
>  
> -        compute_pkt_fields(s, st, st->parser, out_pkt, next_dts, next_pts);
> +        compute_pkt_fields(s, st, st->internal->parser, out_pkt, next_dts, next_pts);
>  
>          ret = avpriv_packet_list_put(&s->internal->parse_queue,
>                                   &s->internal->parse_queue_end,
> @@ -1454,8 +1459,8 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
>  
>      /* end of the stream => close and free the parser */
>      if (flush) {
> -        av_parser_close(st->parser);
> -        st->parser = NULL;
> +        av_parser_close(st->internal->parser);
> +        st->internal->parser = NULL;
>      }
>  
>  fail:
> @@ -1486,7 +1491,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
>              /* flush the parsers */
>              for (i = 0; i < s->nb_streams; i++) {
>                  st = s->streams[i];
> -                if (st->parser && st->need_parsing)
> +                if (st->internal->parser && st->internal->need_parsing)
>                      parse_packet(s, pkt, st->index, 1);
>              }
>              /* all remaining packets are now in parse_queue =>
> @@ -1507,9 +1512,9 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
>              }
>  
>              /* close parser, because it depends on the codec */
> -            if (st->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
> -                av_parser_close(st->parser);
> -                st->parser = NULL;
> +            if (st->internal->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
> +                av_parser_close(st->internal->parser);
> +                st->internal->parser = NULL;
>              }
>  
>              ret = avcodec_parameters_to_context(st->internal->avctx, st->codecpar);
> @@ -1539,23 +1544,23 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
>                     av_ts2str(pkt->dts),
>                     pkt->size, pkt->duration, pkt->flags);
>  
> -        if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
> -            st->parser = av_parser_init(st->codecpar->codec_id);
> -            if (!st->parser) {
> +        if (st->internal->need_parsing && !st->internal->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
> +            st->internal->parser = av_parser_init(st->codecpar->codec_id);
> +            if (!st->internal->parser) {
>                  av_log(s, AV_LOG_VERBOSE, "parser not found for codec "
>                         "%s, packets or times may be invalid.\n",
>                         avcodec_get_name(st->codecpar->codec_id));
>                  /* no parser available: just output the raw packets */
> -                st->need_parsing = AVSTREAM_PARSE_NONE;
> -            } else if (st->need_parsing == AVSTREAM_PARSE_HEADERS)
> -                st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
> -            else if (st->need_parsing == AVSTREAM_PARSE_FULL_ONCE)
> -                st->parser->flags |= PARSER_FLAG_ONCE;
> -            else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
> -                st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
> +                st->internal->need_parsing = AVSTREAM_PARSE_NONE;
> +            } else if (st->internal->need_parsing == AVSTREAM_PARSE_HEADERS)
> +                st->internal->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
> +            else if (st->internal->need_parsing == AVSTREAM_PARSE_FULL_ONCE)
> +                st->internal->parser->flags |= PARSER_FLAG_ONCE;
> +            else if (st->internal->need_parsing == AVSTREAM_PARSE_FULL_RAW)
> +                st->internal->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
>          }
>  
> -        if (!st->need_parsing || !st->parser) {
> +        if (!st->internal->need_parsing || !st->internal->parser) {
>              /* no parsing needed: we just output the packet as is */
>              compute_pkt_fields(s, st, NULL, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
>              if ((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
> @@ -1819,9 +1824,9 @@ void ff_read_frame_flush(AVFormatContext *s)
>      for (i = 0; i < s->nb_streams; i++) {
>          st = s->streams[i];
>  
> -        if (st->parser) {
> -            av_parser_close(st->parser);
> -            st->parser = NULL;
> +        if (st->internal->parser) {
> +            av_parser_close(st->internal->parser);
> +            st->internal->parser = NULL;
>          }
>          st->internal->last_IP_pts = AV_NOPTS_VALUE;
>          st->internal->last_dts_for_order_check = AV_NOPTS_VALUE;
> @@ -2736,9 +2741,9 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
>              av_log(ic, AV_LOG_WARNING,
>                     "start time for stream %d is not set in estimate_timings_from_pts\n", i);
>  
> -        if (st->parser) {
> -            av_parser_close(st->parser);
> -            st->parser = NULL;
> +        if (st->internal->parser) {
> +            av_parser_close(st->internal->parser);
> +            st->internal->parser = NULL;
>          }
>      }
>  
> @@ -2774,7 +2779,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
>                  (st->start_time != AV_NOPTS_VALUE ||
>                   st->first_dts  != AV_NOPTS_VALUE)) {
>                  if (pkt->duration == 0) {
> -                    ff_compute_frame_duration(ic, &num, &den, st, st->parser, pkt);
> +                    ff_compute_frame_duration(ic, &num, &den, st, st->internal->parser, pkt);
>                      if (den && num) {
>                          pkt->duration = av_rescale_rnd(1,
>                                             num * (int64_t) st->time_base.den,
> @@ -3589,15 +3594,15 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
>  
>          /* check if the caller has overridden the codec id */
>          // only for the split stuff
> -        if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->internal->request_probe <= 0) {
> -            st->parser = av_parser_init(st->codecpar->codec_id);
> -            if (st->parser) {
> -                if (st->need_parsing == AVSTREAM_PARSE_HEADERS) {
> -                    st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
> -                } else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) {
> -                    st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
> +        if (!st->internal->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->internal->request_probe <= 0) {
> +            st->internal->parser = av_parser_init(st->codecpar->codec_id);
> +            if (st->internal->parser) {
> +                if (st->internal->need_parsing == AVSTREAM_PARSE_HEADERS) {
> +                    st->internal->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
> +                } else if (st->internal->need_parsing == AVSTREAM_PARSE_FULL_RAW) {
> +                    st->internal->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
>                  }
> -            } else if (st->need_parsing) {
> +            } else if (st->internal->need_parsing) {
>                  av_log(ic, AV_LOG_VERBOSE, "parser not found for codec "
>                         "%s, packets or times may be invalid.\n",
>                         avcodec_get_name(st->codecpar->codec_id));
> @@ -3840,7 +3845,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
>                      st->internal->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->internal->info->codec_info_duration + pkt->duration);
>                  } else
>                      st->internal->info->codec_info_duration += pkt->duration;
> -                st->internal->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2;
> +                st->internal->info->codec_info_duration_fields += st->internal->parser && st->internal->need_parsing && avctx->ticks_per_frame == 2
> +                                                                  ? st->internal->parser->repeat_pict + 1 : 2;
>              }
>          }
>          if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
> @@ -4256,8 +4262,8 @@ static void free_stream(AVStream **pst)
>          av_freep(&st->side_data[i].data);
>      av_freep(&st->side_data);
>  
> -    if (st->parser)
> -        av_parser_close(st->parser);
> +    if (st->internal->parser)
> +        av_parser_close(st->internal->parser);
>  
>      if (st->attached_pic.data)
>          av_packet_unref(&st->attached_pic);
> diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
> index 8e2a7a7475..6bce9ba688 100644
> --- a/libavformat/wavdec.c
> +++ b/libavformat/wavdec.c
> @@ -183,7 +183,7 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream *st)
>          return ret;
>      handle_stream_probing(st);
>  
> -    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>  
>      avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
>  
> @@ -200,7 +200,7 @@ static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream *st)
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
>      st->codecpar->codec_id   = AV_CODEC_ID_XMA2;
> -    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
>  
>      version = avio_r8(pb);
>      if (version != 3 && version != 4)
> @@ -950,7 +950,7 @@ static int w64_read_header(AVFormatContext *s)
>      ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
>  
>      handle_stream_probing(st);
> -    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
> +    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
>  
>      avio_seek(pb, data_ofs, SEEK_SET);
>  
> diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
> index ab7e6b8188..a549681322 100644
> --- a/libavformat/wtvdec.c
> +++ b/libavformat/wtvdec.c
> @@ -618,7 +618,7 @@ static AVStream * new_stream(AVFormatContext *s, AVStream *st, int sid, int code
>          st->priv_data = wst;
>      }
>      st->codecpar->codec_type = codec_type;
> -    st->need_parsing      = AVSTREAM_PARSE_FULL;
> +    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
>      avpriv_set_pts_info(st, 64, 1, 10000000);
>      return st;
>  }
> diff --git a/libavformat/xvag.c b/libavformat/xvag.c
> index 55bc25227e..2a85d66ecb 100644
> --- a/libavformat/xvag.c
> +++ b/libavformat/xvag.c
> @@ -87,7 +87,7 @@ static int xvag_read_header(AVFormatContext *s)
>      if (avio_rb16(s->pb) == 0xFFFB) {
>          st->codecpar->codec_id    = AV_CODEC_ID_MP3;
>          st->codecpar->block_align = 0x1000;
> -        st->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
> +        st->internal->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
>      }
>  
>      avio_skip(s->pb, -2);
> diff --git a/libavformat/xwma.c b/libavformat/xwma.c
> index 9c9b02e515..d7fd05504b 100644
> --- a/libavformat/xwma.c
> +++ b/libavformat/xwma.c
> @@ -78,7 +78,7 @@ static int xwma_read_header(AVFormatContext *s)
>      ret = ff_get_wav_header(s, pb, st->codecpar, size, 0);
>      if (ret < 0)
>          return ret;
> -    st->need_parsing = AVSTREAM_PARSE_NONE;
> +    st->internal->need_parsing = AVSTREAM_PARSE_NONE;
>  
>      /* XWMA encoder only allows a few channel/sample rate/bitrate combinations,
>       * but some create identical files with fake bitrate (1ch 22050hz at
>
James Almer May 6, 2021, 6:47 p.m. UTC | #2
On 5/6/2021 3:31 PM, Andreas Rheinhardt wrote:
> James Almer:
>> Those are private fields, no reason to have them exposed in a public
>> header.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> Now also porting the v4l2 outdev, which unfortunately requires an accessor.
>> If anyone with a v4l2 capable machine wants to check if not setting
>> need_parsing at all for h264 streams is an option, that'd be better.
>>
> 
> Alternatively one could just move needs_parsing to the beginning of
> AVStreamInternal.

That still ties the contents of AVStreamInternal to the ABI, even if a 
single field at the beginning, and the plan is to replace the 
AVCodecParserContext API altogether, which may include removing this 
field or even changing its semantics.

Once any change takes place, avpriv_stream_set_need_parsing() can be 
made into a no-op, or made to set a different field converting 
AVStreamParseType values as required.
diff mbox series

Patch

diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index a5149a9132..981b6207fb 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -961,7 +961,7 @@  static int v4l2_read_header(AVFormatContext *ctx)
         st->codecpar->codec_tag =
             avcodec_pix_fmt_to_codec_tag(st->codecpar->format);
     else if (codec_id == AV_CODEC_ID_H264) {
-        st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
+        avpriv_stream_set_need_parsing(st, AVSTREAM_PARSE_FULL_ONCE);
     }
     if (desired_format == V4L2_PIX_FMT_YVU420)
         st->codecpar->codec_tag = MKTAG('Y', 'V', '1', '2');
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index ba468909e9..94e39f592f 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -112,7 +112,7 @@  static int adts_aac_read_header(AVFormatContext *s)
 
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id   = s->iformat->raw_codec_id;
-    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
 
     ff_id3v1_read(s);
     if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
diff --git a/libavformat/aadec.c b/libavformat/aadec.c
index 21051d79b8..9fe24d5d53 100644
--- a/libavformat/aadec.c
+++ b/libavformat/aadec.c
@@ -183,7 +183,7 @@  static int aa_read_header(AVFormatContext *s)
     if (!strcmp(codec_name, "mp332")) {
         st->codecpar->codec_id = AV_CODEC_ID_MP3;
         st->codecpar->sample_rate = 22050;
-        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+        st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
         avpriv_set_pts_info(st, 64, 8, 32000 * TIMEPREC);
         // encoded audio frame is MP3_FRAME_SIZE bytes (+1 with padding, unlikely)
     } else if (!strcmp(codec_name, "acelp85")) {
@@ -192,7 +192,7 @@  static int aa_read_header(AVFormatContext *s)
         st->codecpar->channels = 1;
         st->codecpar->sample_rate = 8500;
         st->codecpar->bit_rate = 8500;
-        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+        st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
         avpriv_set_pts_info(st, 64, 8, 8500 * TIMEPREC);
     } else if (!strcmp(codec_name, "acelp16")) {
         st->codecpar->codec_id = AV_CODEC_ID_SIPR;
@@ -200,7 +200,7 @@  static int aa_read_header(AVFormatContext *s)
         st->codecpar->channels = 1;
         st->codecpar->sample_rate = 16000;
         st->codecpar->bit_rate = 16000;
-        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+        st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
         avpriv_set_pts_info(st, 64, 8, 16000 * TIMEPREC);
     }
 
diff --git a/libavformat/acm.c b/libavformat/acm.c
index c78a408aa0..bc87b3fab9 100644
--- a/libavformat/acm.c
+++ b/libavformat/acm.c
@@ -54,7 +54,7 @@  static int acm_read_header(AVFormatContext *s)
         return AVERROR_INVALIDDATA;
     st->start_time         = 0;
     st->duration           = AV_RL32(st->codecpar->extradata +  4) / st->codecpar->channels;
-    st->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
     avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
 
     return 0;
diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
index 2e806dd452..053c815977 100644
--- a/libavformat/asfdec_f.c
+++ b/libavformat/asfdec_f.c
@@ -382,9 +382,9 @@  static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
             st->codecpar->codec_tag = 0;
         }
         if (st->codecpar->codec_id == AV_CODEC_ID_AAC)
-            st->need_parsing = AVSTREAM_PARSE_NONE;
+            st->internal->need_parsing = AVSTREAM_PARSE_NONE;
         else
-            st->need_parsing = AVSTREAM_PARSE_FULL;
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
         /* We have to init the frame size at some point .... */
         pos2 = avio_tell(pb);
         if (size >= (pos2 + 8 - pos1 + 24)) {
@@ -443,7 +443,7 @@  static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
         st->codecpar->codec_tag = tag1;
         st->codecpar->codec_id  = ff_codec_get_id(ff_codec_bmp_tags, tag1);
         if (tag1 == MKTAG('D', 'V', 'R', ' ')) {
-            st->need_parsing = AVSTREAM_PARSE_FULL;
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
             /* issue658 contains wrong w/h and MS even puts a fake seq header
              * with wrong w/h in extradata while a correct one is in the stream.
              * maximum lameness */
@@ -453,9 +453,9 @@  static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
             st->codecpar->extradata_size = 0;
         }
         if (st->codecpar->codec_id == AV_CODEC_ID_H264)
-            st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
         if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4)
-            st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
     }
     pos2 = avio_tell(pb);
     avio_skip(pb, size - (pos2 - pos1 + 24));
diff --git a/libavformat/av1dec.c b/libavformat/av1dec.c
index b71d5d0e19..8ca804c2a3 100644
--- a/libavformat/av1dec.c
+++ b/libavformat/av1dec.c
@@ -66,7 +66,7 @@  static int read_header(AVFormatContext *s, const AVRational *framerate, AVBSFCon
 
     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codecpar->codec_id = AV_CODEC_ID_AV1;
-    st->need_parsing = AVSTREAM_PARSE_HEADERS;
+    st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
 
     st->internal->avctx->framerate = *framerate;
     // taken from rawvideo demuxers
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index d796f02094..9ed6d333d3 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1008,10 +1008,6 @@  typedef struct AVStream {
      */
     int codec_info_nb_frames;
 
-    /* av_read_frame() support */
-    enum AVStreamParseType need_parsing;
-    struct AVCodecParserContext *parser;
-
     /**
      * Stream Identifier
      * This is the MPEG-TS stream identifier +1
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index e0d868e074..14a2dd6cd7 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -824,19 +824,19 @@  static int avi_read_header(AVFormatContext *s)
 
                     /* This is needed to get the pict type which is necessary
                      * for generating correct pts. */
-                    st->need_parsing = AVSTREAM_PARSE_HEADERS;
+                    st->internal->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->need_parsing = AVSTREAM_PARSE_FULL;
+                        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
                     if (st->codecpar->codec_id == AV_CODEC_ID_RV40)
-                        st->need_parsing = AVSTREAM_PARSE_NONE;
+                        st->internal->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;
+                        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
 
                     if (st->codecpar->codec_id  == AV_CODEC_ID_AVRN &&
                         st->codecpar->codec_tag == MKTAG('A', 'V', 'R', 'n') &&
@@ -880,16 +880,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->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
+                    st->internal->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->need_parsing = AVSTREAM_PARSE_NONE;
+                        st->internal->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->need_parsing = AVSTREAM_PARSE_NONE;
+                        st->internal->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")) {
@@ -1052,7 +1052,7 @@  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->need_parsing = AVSTREAM_PARSE_FULL;
+                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
         }
 
     for (i = 0; i < s->nb_streams; i++) {
diff --git a/libavformat/dtshddec.c b/libavformat/dtshddec.c
index 48d3afbebd..2900623690 100644
--- a/libavformat/dtshddec.c
+++ b/libavformat/dtshddec.c
@@ -65,7 +65,7 @@  static int dtshd_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id   = AV_CODEC_ID_DTS;
-    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
 
     for (;;) {
         chunk_type = avio_rb64(pb);
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index 8080ee7e41..4d0fddab3d 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -503,7 +503,7 @@  static int init_video_stream(AVFormatContext *s, VideoProperties *video)
     st->codecpar->codec_id    = video->codec;
     // parsing is necessary to make FFmpeg generate correct timestamps
     if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO)
-        st->need_parsing = AVSTREAM_PARSE_HEADERS;
+        st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
     st->codecpar->codec_tag   = 0; /* no fourcc */
     st->codecpar->width       = video->width;
     st->codecpar->height      = video->height;
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index 4ed523f309..d4158032e4 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -56,7 +56,7 @@  static int flac_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id = AV_CODEC_ID_FLAC;
-    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
     /* the parameters will be extracted from the compressed bitstream */
 
     /* if fLaC marker is not found, assume there is no header */
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 718d690421..e6c2877a74 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -271,7 +271,7 @@  static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
         break;
     case FLV_CODECID_MP3:
         apar->codec_id      = AV_CODEC_ID_MP3;
-        astream->need_parsing = AVSTREAM_PARSE_FULL;
+        astream->internal->need_parsing = AVSTREAM_PARSE_FULL;
         break;
     case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
         // in case metadata does not otherwise declare samplerate
@@ -362,7 +362,7 @@  static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
         break;
     case FLV_CODECID_H264:
         par->codec_id = AV_CODEC_ID_H264;
-        vstream->need_parsing = AVSTREAM_PARSE_HEADERS;
+        vstream->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
         ret = 3;     // not 4, reading packet type will consume one byte
         break;
     case FLV_CODECID_MPEG4:
diff --git a/libavformat/gxf.c b/libavformat/gxf.c
index 53fa302828..7d23cbd692 100644
--- a/libavformat/gxf.c
+++ b/libavformat/gxf.c
@@ -130,13 +130,13 @@  static int get_sindex(AVFormatContext *s, int id, int format) {
         case 20:
             st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
             st->codecpar->codec_id = AV_CODEC_ID_MPEG2VIDEO;
-            st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
+            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
             break;
         case 22:
         case 23:
             st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
             st->codecpar->codec_id = AV_CODEC_ID_MPEG1VIDEO;
-            st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
+            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
             break;
         case 9:
             st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -169,7 +169,7 @@  static int get_sindex(AVFormatContext *s, int id, int format) {
         case 29: /* AVCHD */
             st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
             st->codecpar->codec_id = AV_CODEC_ID_H264;
-            st->need_parsing = AVSTREAM_PARSE_HEADERS;
+            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
             break;
         // timecode tracks:
         case 7:
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index d7a7cdaa16..aaf2ac362c 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -209,7 +209,7 @@  int ff_img_read_header(AVFormatContext *s1)
         s->is_pipe = 0;
     else {
         s->is_pipe       = 1;
-        st->need_parsing = AVSTREAM_PARSE_FULL;
+        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
     }
 
     if (s->ts_from_file == 2) {
@@ -482,7 +482,7 @@  int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
             return AVERROR_EOF;
         if (s->frame_size > 0) {
             size[0] = s->frame_size;
-        } else if (!s1->streams[0]->parser) {
+        } else if (!s1->streams[0]->internal->parser) {
             size[0] = avio_size(s1->pb);
         } else {
             size[0] = 4096;
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 6af38720c8..10fbd9b51b 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -373,8 +373,14 @@  struct AVStreamInternal {
      * Number of packets to buffer for codec probing
      */
     int probe_packets;
+
+    /* av_read_frame() support */
+    enum AVStreamParseType need_parsing;
+    struct AVCodecParserContext *parser;
 };
 
+void avpriv_stream_set_need_parsing(AVStream *st, enum AVStreamParseType type);
+
 #ifdef __GNUC__
 #define dynarray_add(tab, nb_ptr, elem)\
 do {\
diff --git a/libavformat/ipudec.c b/libavformat/ipudec.c
index 283c798751..b76371b58c 100644
--- a/libavformat/ipudec.c
+++ b/libavformat/ipudec.c
@@ -62,7 +62,7 @@  static int ipu_read_header(AVFormatContext *s)
     st->start_time         = 0;
     st->duration           =
     st->nb_frames          = avio_rl32(pb);
-    st->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
     avpriv_set_pts_info(st, 64, 1, 25);
 
     return 0;
diff --git a/libavformat/iv8.c b/libavformat/iv8.c
index 7237e16172..b06797cbf3 100644
--- a/libavformat/iv8.c
+++ b/libavformat/iv8.c
@@ -47,7 +47,7 @@  static int read_header(AVFormatContext *s)
 
     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codecpar->codec_id = AV_CODEC_ID_MPEG4;
-    st->need_parsing = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing = AVSTREAM_PARSE_FULL;
     avpriv_set_pts_info(st, 64, 1, 90000);
 
     return 0;
diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c
index 3e1ea52cbf..26717c4999 100644
--- a/libavformat/ivfdec.c
+++ b/libavformat/ivfdec.c
@@ -56,7 +56,7 @@  static int read_header(AVFormatContext *s)
     st->duration          = avio_rl32(s->pb);
     avio_skip(s->pb, 4); // unused
 
-    st->need_parsing      = AVSTREAM_PARSE_HEADERS;
+    st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
 
     if (!time_base.den || !time_base.num) {
         av_log(s, AV_LOG_ERROR, "Invalid frame rate\n");
diff --git a/libavformat/lmlm4.c b/libavformat/lmlm4.c
index 99cba73a00..dbeaceab9c 100644
--- a/libavformat/lmlm4.c
+++ b/libavformat/lmlm4.c
@@ -67,14 +67,14 @@  static int lmlm4_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codecpar->codec_id   = AV_CODEC_ID_MPEG4;
-    st->need_parsing      = AVSTREAM_PARSE_HEADERS;
+    st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
     avpriv_set_pts_info(st, 64, 1001, 30000);
 
     if (!(st = avformat_new_stream(s, NULL)))
         return AVERROR(ENOMEM);
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id   = AV_CODEC_ID_MP2;
-    st->need_parsing      = AVSTREAM_PARSE_HEADERS;
+    st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
 
     /* the parameters will be extracted from the compressed bitstream */
     return 0;
diff --git a/libavformat/loasdec.c b/libavformat/loasdec.c
index 490dd68ee0..97fabefcd7 100644
--- a/libavformat/loasdec.c
+++ b/libavformat/loasdec.c
@@ -75,7 +75,7 @@  static int loas_read_header(AVFormatContext *s)
 
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id = s->iformat->raw_codec_id;
-    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     //LCM of all possible AAC sample rates
     avpriv_set_pts_info(st, 64, 1, 28224000);
diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c
index ebb745d360..79ccc77747 100644
--- a/libavformat/lxfdec.c
+++ b/libavformat/lxfdec.c
@@ -262,7 +262,7 @@  static int lxf_read_header(AVFormatContext *s)
     st->codecpar->bit_rate   = 1000000 * ((video_params >> 14) & 0xFF);
     st->codecpar->codec_tag  = video_params & 0xF;
     st->codecpar->codec_id   = ff_codec_get_id(lxf_tags, st->codecpar->codec_tag);
-    st->need_parsing         = AVSTREAM_PARSE_HEADERS;
+    st->internal->need_parsing         = AVSTREAM_PARSE_HEADERS;
 
     av_log(s, AV_LOG_DEBUG, "record: %x = %i-%02i-%02i\n",
            record_date, 1900 + (record_date & 0x7F), (record_date >> 7) & 0xF,
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 63faea4e35..8523261760 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -2806,7 +2806,7 @@  static int matroska_parse_tracks(AVFormatContext *s)
                           255);
             }
             if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
-                st->need_parsing = AVSTREAM_PARSE_HEADERS;
+                st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
 
             if (track->default_duration) {
                 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
@@ -2864,9 +2864,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->need_parsing = AVSTREAM_PARSE_FULL;
+                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
             else if (st->codecpar->codec_id != AV_CODEC_ID_AAC)
-                st->need_parsing = AVSTREAM_PARSE_HEADERS;
+                st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
             if (track->codec_delay > 0) {
                 st->codecpar->initial_padding = av_rescale_q(track->codec_delay,
                                                              (AVRational){1, 1000000000},
diff --git a/libavformat/mgsts.c b/libavformat/mgsts.c
index 02f65e7b1b..5886d2475a 100644
--- a/libavformat/mgsts.c
+++ b/libavformat/mgsts.c
@@ -50,7 +50,7 @@  static int read_header(AVFormatContext *s)
     if (!st)
         return AVERROR(ENOMEM);
 
-    st->need_parsing = AVSTREAM_PARSE_HEADERS;
+    st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
     st->start_time = 0;
     st->nb_frames  =
     st->duration   = avio_rb32(pb);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index ca6a0f2db4..295a8e2b99 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2186,7 +2186,7 @@  static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
             switch (st->codecpar->codec_id) {
             case AV_CODEC_ID_MP2:
             case AV_CODEC_ID_MP3:
-                st->need_parsing = AVSTREAM_PARSE_FULL;
+                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
                 break;
             }
         }
@@ -2424,10 +2424,10 @@  static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
     case AV_CODEC_ID_VC1:
     case AV_CODEC_ID_VP8:
     case AV_CODEC_ID_VP9:
-        st->need_parsing = AVSTREAM_PARSE_FULL;
+        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
         break;
     case AV_CODEC_ID_AV1:
-        st->need_parsing = AVSTREAM_PARSE_HEADERS;
+        st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
         break;
     default:
         break;
@@ -2773,8 +2773,8 @@  static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     if (!entries) {
         sc->keyframe_absent = 1;
-        if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
-            st->need_parsing = AVSTREAM_PARSE_HEADERS;
+        if (!st->internal->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
+            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
         return 0;
     }
     if (sc->keyframes)
@@ -4317,7 +4317,7 @@  static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         && sc->stts_count > 3
         && sc->stts_count*10 > st->nb_frames
         && sc->time_scale == st->codecpar->sample_rate) {
-            st->need_parsing = AVSTREAM_PARSE_FULL;
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
     }
     /* Do not need those anymore. */
     av_freep(&sc->chunk_offsets);
@@ -7644,7 +7644,7 @@  static int mov_read_header(AVFormatContext *s)
             mov->handbrake_version <= 1000000*0 + 1000*10 + 2 &&  // 0.10.2
             st->codecpar->codec_id == AV_CODEC_ID_MP3) {
             av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
-            st->need_parsing = AVSTREAM_PARSE_FULL;
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
         }
     }
 
@@ -7950,9 +7950,9 @@  static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
                 sc->has_palette = 0;
             }
         }
-        if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
+        if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->internal->need_parsing && pkt->size > 4) {
             if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
-                st->need_parsing = AVSTREAM_PARSE_FULL;
+                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
         }
     }
 
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 611b423aea..b12cd31148 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -374,7 +374,7 @@  static int mp3_read_header(AVFormatContext *s)
 
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id = AV_CODEC_ID_MP3;
-    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
     st->start_time = 0;
 
     // lcm of all mp3 sample rates
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index fb1d54e52f..178e71d891 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -623,7 +623,7 @@  skip:
         st->codecpar->sample_rate = 8000;
     }
     st->internal->request_probe     = request_probe;
-    st->need_parsing      = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
 
 found:
     if (st->discard >= AVDISCARD_ALL)
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 0ed108ce89..fb454b9fd3 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -904,7 +904,7 @@  static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
     st->priv_data         = pes;
     st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
     st->codecpar->codec_id   = AV_CODEC_ID_NONE;
-    st->need_parsing      = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
     pes->st          = st;
     pes->stream_type = stream_type;
 
@@ -942,7 +942,7 @@  static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
             sub_st->priv_data         = sub_pes;
             sub_st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
             sub_st->codecpar->codec_id   = AV_CODEC_ID_AC3;
-            sub_st->need_parsing      = AVSTREAM_PARSE_FULL;
+            sub_st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
             sub_pes->sub_st           = pes->sub_st = sub_st;
         }
     }
@@ -1717,10 +1717,10 @@  static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section,
             ff_mp4_read_dec_config_descr(s, st, &pb);
             if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
                 st->codecpar->extradata_size > 0)
-                st->need_parsing = 0;
+                st->internal->need_parsing = 0;
             if (st->codecpar->codec_id == AV_CODEC_ID_H264 &&
                 st->codecpar->extradata_size > 0)
-                st->need_parsing = 0;
+                st->internal->need_parsing = 0;
 
             st->codecpar->codec_type = avcodec_get_type(st->codecpar->codec_id);
             st->internal->need_context_update = 1;
@@ -1826,7 +1826,7 @@  int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
                 ff_mp4_read_dec_config_descr(fc, st, &pb);
                 if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
                     st->codecpar->extradata_size > 0) {
-                    st->need_parsing = 0;
+                    st->internal->need_parsing = 0;
                     st->internal->need_context_update = 1;
                 }
                 if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4SYSTEMS)
@@ -1848,7 +1848,7 @@  int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
             ff_mp4_read_dec_config_descr(fc, st, &pb);
             if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
                 st->codecpar->extradata_size > 0) {
-                st->internal->request_probe = st->need_parsing = 0;
+                st->internal->request_probe = st->internal->need_parsing = 0;
                 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
                 st->internal->need_context_update = 1;
             }
@@ -2035,7 +2035,7 @@  int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
                 } else {
                     avpriv_request_sample(fc, "Opus in MPEG-TS - channel_config_code > 0x8");
                 }
-                st->need_parsing = AVSTREAM_PARSE_FULL;
+                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
                 st->internal->need_context_update = 1;
             }
         }
diff --git a/libavformat/msf.c b/libavformat/msf.c
index ca2b3a3bf5..43a7f7b616 100644
--- a/libavformat/msf.c
+++ b/libavformat/msf.c
@@ -80,7 +80,7 @@  static int msf_read_header(AVFormatContext *s)
             AV_WL16(st->codecpar->extradata+8, codec == 4 ? 1 : 0); /* joint stereo (repeat?) */
             AV_WL16(st->codecpar->extradata+10, 1);
             st->codecpar->codec_id = AV_CODEC_ID_ATRAC3;    break;
-    case 7: st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+    case 7: st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
             st->codecpar->codec_id = AV_CODEC_ID_MP3;       break;
     default:
             avpriv_request_sample(s, "Codec %d", codec);
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index 26a0fd0ea4..d33561b6ec 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -185,7 +185,7 @@  static int mtv_read_header(AVFormatContext *s)
     st->codecpar->codec_type      = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id        = AV_CODEC_ID_MP3;
     st->codecpar->bit_rate        = mtv->audio_br;
-    st->need_parsing              = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing              = AVSTREAM_PARSE_FULL;
 
     // Jump over header
 
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index f0c2c0b15f..3bf480a3a6 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -2593,7 +2593,7 @@  static int mxf_parse_structural_metadata(MXFContext *mxf)
                     }
                 }
             }
-            st->need_parsing = AVSTREAM_PARSE_HEADERS;
+            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
             if (material_track->sequence->origin) {
                 av_dict_set_int(&st->metadata, "material_track_origin", material_track->sequence->origin, 0);
             }
@@ -2658,7 +2658,7 @@  static int mxf_parse_structural_metadata(MXFContext *mxf)
                 else if (descriptor->bits_per_sample == 32)
                     st->codecpar->codec_id = AV_CODEC_ID_PCM_S32BE;
             } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
-                st->need_parsing = AVSTREAM_PARSE_FULL;
+                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
             }
             st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id);
         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
@@ -2692,7 +2692,7 @@  static int mxf_parse_structural_metadata(MXFContext *mxf)
         }
         if (st->codecpar->codec_type != AVMEDIA_TYPE_DATA && source_track->wrapping != FrameWrapped) {
             /* TODO: decode timestamps */
-            st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
+            st->internal->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
         }
     }
 
@@ -3660,7 +3660,7 @@  static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
                 if (next_ofs <= 0) {
                     // If we have no way to packetize the data, then return it in chunks...
                     if (klv.next_klv - klv.length == pos && max_data_size > MXF_MAX_CHUNK_SIZE) {
-                        st->need_parsing = AVSTREAM_PARSE_FULL;
+                        st->internal->need_parsing = AVSTREAM_PARSE_FULL;
                         avpriv_request_sample(s, "Huge KLV without proper index in non-frame wrapped essence");
                     }
                     size = FFMIN(max_data_size, MXF_MAX_CHUNK_SIZE);
diff --git a/libavformat/ncdec.c b/libavformat/ncdec.c
index ff5eb189bc..3fe189e729 100644
--- a/libavformat/ncdec.c
+++ b/libavformat/ncdec.c
@@ -53,7 +53,7 @@  static int nc_read_header(AVFormatContext *s)
 
     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codecpar->codec_id   = AV_CODEC_ID_MPEG4;
-    st->need_parsing      = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
 
     avpriv_set_pts_info(st, 64, 1, 100);
 
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index b79d0dcc62..7dcc218546 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -462,7 +462,7 @@  static int nsv_parse_NSVs_header(AVFormatContext *s)
             st->codecpar->codec_tag = atag;
             st->codecpar->codec_id = ff_codec_get_id(nsv_codec_audio_tags, atag);
 
-            st->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */
 
             /* set timebase to common denominator of ms and framerate */
             avpriv_set_pts_info(st, 64, 1, framerate.num*1000);
@@ -615,7 +615,7 @@  null_chunk_retry:
             asize-=4;
             av_log(s, AV_LOG_TRACE, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate);
             if (fill_header) {
-                st[NSV_ST_AUDIO]->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */
+                st[NSV_ST_AUDIO]->internal->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */
                 if (bps != 16) {
                     av_log(s, AV_LOG_TRACE, "NSV AUDIO bit/sample != 16 (%d)!!!\n", bps);
                 }
diff --git a/libavformat/nuv.c b/libavformat/nuv.c
index aec87f45fe..1d25d3b125 100644
--- a/libavformat/nuv.c
+++ b/libavformat/nuv.c
@@ -132,7 +132,7 @@  static int get_codec_data(AVFormatContext *s, AVIOContext *pb, AVStream *vst,
                 }
                 ast->codecpar->codec_id = id;
 
-                ast->need_parsing = AVSTREAM_PARSE_FULL;
+                ast->internal->need_parsing = AVSTREAM_PARSE_FULL;
             } else
                 avio_skip(pb, 4 * 4);
 
diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c
index 4e85b05c67..15eeca56aa 100644
--- a/libavformat/oggparseflac.c
+++ b/libavformat/oggparseflac.c
@@ -59,7 +59,7 @@  flac_header (AVFormatContext * s, int idx)
 
         st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
         st->codecpar->codec_id = AV_CODEC_ID_FLAC;
-        st->need_parsing = AVSTREAM_PARSE_HEADERS;
+        st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
 
         if ((ret = ff_alloc_extradata(st->codecpar, FLAC_STREAMINFO_SIZE)) < 0)
             return ret;
diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c
index 469b229995..a8319b9dfa 100644
--- a/libavformat/oggparseogm.c
+++ b/libavformat/oggparseogm.c
@@ -60,7 +60,7 @@  ogm_header(AVFormatContext *s, int idx)
             st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag);
             st->codecpar->codec_tag = tag;
             if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4)
-                st->need_parsing = AVSTREAM_PARSE_HEADERS;
+                st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
         } else if (bytestream2_peek_byte(&p) == 't') {
             st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
             st->codecpar->codec_id = AV_CODEC_ID_TEXT;
@@ -76,7 +76,7 @@  ogm_header(AVFormatContext *s, int idx)
             st->codecpar->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid);
             // our parser completely breaks AAC in Ogg
             if (st->codecpar->codec_id != AV_CODEC_ID_AAC)
-                st->need_parsing = AVSTREAM_PARSE_FULL;
+                st->internal->need_parsing = AVSTREAM_PARSE_FULL;
         }
 
         size        = bytestream2_get_le32(&p);
diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c
index d1064e4328..28684f6ea9 100644
--- a/libavformat/oggparsetheora.c
+++ b/libavformat/oggparsetheora.c
@@ -112,7 +112,7 @@  static int theora_header(AVFormatContext *s, int idx)
 
         st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
         st->codecpar->codec_id   = AV_CODEC_ID_THEORA;
-        st->need_parsing      = AVSTREAM_PARSE_HEADERS;
+        st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
     }
     break;
     case 0x81:
diff --git a/libavformat/oggparsevp8.c b/libavformat/oggparsevp8.c
index b76ac71cc5..85b3627c9c 100644
--- a/libavformat/oggparsevp8.c
+++ b/libavformat/oggparsevp8.c
@@ -61,7 +61,7 @@  static int vp8_header(AVFormatContext *s, int idx)
         avpriv_set_pts_info(st, 64, framerate.den, framerate.num);
         st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
         st->codecpar->codec_id   = AV_CODEC_ID_VP8;
-        st->need_parsing      = AVSTREAM_PARSE_HEADERS;
+        st->internal->need_parsing      = AVSTREAM_PARSE_HEADERS;
         break;
     case 0x02:
         if (p[6] != 0x20)
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index 1c2b04212c..8891cfc4b6 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -520,7 +520,7 @@  static int oma_read_header(AVFormatContext *s)
         avpriv_set_pts_info(st, 64, 1, samplerate);
         break;
     case OMA_CODECID_MP3:
-        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+        st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
         framesize = 1024;
         break;
     case OMA_CODECID_LPCM:
diff --git a/libavformat/pva.c b/libavformat/pva.c
index 8e3013a496..ff30746bcb 100644
--- a/libavformat/pva.c
+++ b/libavformat/pva.c
@@ -61,7 +61,7 @@  static int pva_read_header(AVFormatContext *s) {
         return AVERROR(ENOMEM);
     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codecpar->codec_id   = AV_CODEC_ID_MPEG2VIDEO;
-    st->need_parsing      = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
     avpriv_set_pts_info(st, 32, 1, 90000);
     av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME);
 
@@ -69,7 +69,7 @@  static int pva_read_header(AVFormatContext *s) {
         return AVERROR(ENOMEM);
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id   = AV_CODEC_ID_MP2;
-    st->need_parsing      = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
     avpriv_set_pts_info(st, 33, 1, 90000);
     av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME);
 
diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c
index c162b52940..a1f593c66a 100644
--- a/libavformat/rawdec.c
+++ b/libavformat/rawdec.c
@@ -60,7 +60,7 @@  int ff_raw_audio_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id = s->iformat->raw_codec_id;
-    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
     st->start_time = 0;
     /* the parameters will be extracted from the compressed bitstream */
 
@@ -83,7 +83,7 @@  int ff_raw_video_read_header(AVFormatContext *s)
 
     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codecpar->codec_id = s->iformat->raw_codec_id;
-    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     st->internal->avctx->framerate = s1->framerate;
     avpriv_set_pts_info(st, 64, 1, 1200000);
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index 538f549495..68b5c3b75a 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -204,7 +204,7 @@  static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
 
         switch (st->codecpar->codec_id) {
         case AV_CODEC_ID_AC3:
-            st->need_parsing = AVSTREAM_PARSE_FULL;
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
             break;
         case AV_CODEC_ID_RA_288:
             st->codecpar->extradata_size= 0;
@@ -213,7 +213,7 @@  static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
             st->codecpar->block_align = coded_framesize;
             break;
         case AV_CODEC_ID_COOK:
-            st->need_parsing = AVSTREAM_PARSE_HEADERS;
+            st->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
         case AV_CODEC_ID_ATRAC3:
         case AV_CODEC_ID_SIPR:
             if (read_all) {
@@ -237,7 +237,7 @@  static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
                     return -1;
                 }
                 st->codecpar->block_align = ff_sipr_subpk_size[flavor];
-                st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+                st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
             } else {
                 if(sub_packet_size <= 0){
                     av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n");
@@ -390,7 +390,7 @@  int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb,
         avio_skip(pb, 2); // looks like bits per sample
         avio_skip(pb, 4); // always zero?
         st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
-        st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
+        st->internal->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
         fps = avio_rb32(pb);
 
         if ((ret = rm_read_extradata(s, pb, st->codecpar, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)
diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
index 2749ad1380..f6e7f00bbe 100644
--- a/libavformat/rtpdec_asf.c
+++ b/libavformat/rtpdec_asf.c
@@ -167,8 +167,8 @@  static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index,
                 if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) {
                     avcodec_parameters_copy(s->streams[stream_index]->codecpar,
                                             rt->asf_ctx->streams[i]->codecpar);
-                    s->streams[stream_index]->need_parsing =
-                        rt->asf_ctx->streams[i]->need_parsing;
+                    s->streams[stream_index]->internal->need_parsing =
+                        rt->asf_ctx->streams[i]->internal->need_parsing;
                     avpriv_set_pts_info(s->streams[stream_index], 32, 1, 1000);
                 }
            }
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 3899c26fa4..9f509a229f 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -218,7 +218,7 @@  static void init_rtp_handler(const RTPDynamicProtocolHandler *handler,
         par->codec_id          = handler->codec_id;
     rtsp_st->dynamic_handler = handler;
     if (st)
-        st->need_parsing = handler->need_parsing;
+        st->internal->need_parsing = handler->need_parsing;
     if (handler->priv_data_size) {
         rtsp_st->dynamic_protocol_context = av_mallocz(handler->priv_data_size);
         if (!rtsp_st->dynamic_protocol_context)
diff --git a/libavformat/s337m.c b/libavformat/s337m.c
index 37e93db7d5..e1d921c303 100644
--- a/libavformat/s337m.c
+++ b/libavformat/s337m.c
@@ -20,6 +20,7 @@ 
 
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
+#include "internal.h"
 #include "spdif.h"
 
 #define MARKER_16LE         0x72F81F4E
@@ -180,7 +181,7 @@  static int s337m_read_packet(AVFormatContext *s, AVPacket *pkt)
         }
         st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
         st->codecpar->codec_id   = codec;
-        st->need_parsing         = AVSTREAM_PARSE_HEADERS;
+        st->internal->need_parsing         = AVSTREAM_PARSE_HEADERS;
     }
 
     return 0;
diff --git a/libavformat/sdr2.c b/libavformat/sdr2.c
index 373116a4a6..0f506fd074 100644
--- a/libavformat/sdr2.c
+++ b/libavformat/sdr2.c
@@ -51,7 +51,7 @@  static int sdr2_read_header(AVFormatContext *s)
     st->codecpar->width      = avio_rl32(s->pb);
     st->codecpar->height     = avio_rl32(s->pb);
     st->codecpar->codec_id   = AV_CODEC_ID_H264;
-    st->need_parsing      = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
 
     ast->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
     ast->codecpar->channels    = 1;
diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
index 4b4327a179..05b4d9e6a8 100644
--- a/libavformat/segafilm.c
+++ b/libavformat/segafilm.c
@@ -183,7 +183,7 @@  static int film_read_header(AVFormatContext *s)
         if (film->audio_type == AV_CODEC_ID_ADPCM_ADX) {
             st->codecpar->bits_per_coded_sample = 18 * 8 / 32;
             st->codecpar->block_align = st->codecpar->channels * 18;
-            st->need_parsing = AVSTREAM_PARSE_FULL;
+            st->internal->need_parsing = AVSTREAM_PARSE_FULL;
         } else {
             st->codecpar->bits_per_coded_sample = film->audio_bits;
             st->codecpar->block_align = st->codecpar->channels *
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index f5a98e8b53..8eda80b4f6 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -204,7 +204,7 @@  static AVStream *create_new_audio_stream(AVFormatContext *s, int id, int info)
     }
     ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     ast->codecpar->codec_id   = ff_codec_get_id(swf_audio_codec_tags, info>>4 & 15);
-    ast->need_parsing = AVSTREAM_PARSE_FULL;
+    ast->internal->need_parsing = AVSTREAM_PARSE_FULL;
     sample_rate_code = info>>2 & 3;
     sample_size_code = info>>1 & 1;
     if (!sample_size_code && ast->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE)
diff --git a/libavformat/takdec.c b/libavformat/takdec.c
index 46c500efef..cbb9a9345e 100644
--- a/libavformat/takdec.c
+++ b/libavformat/takdec.c
@@ -65,7 +65,7 @@  static int tak_read_header(AVFormatContext *s)
 
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id   = AV_CODEC_ID_TAK;
-    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
 
     tc->mlast_frame = 0;
     if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
diff --git a/libavformat/ty.c b/libavformat/ty.c
index 8830467f99..5bb5d4267b 100644
--- a/libavformat/ty.c
+++ b/libavformat/ty.c
@@ -308,7 +308,7 @@  static int ty_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codecpar->codec_id   = AV_CODEC_ID_MPEG2VIDEO;
-    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
     avpriv_set_pts_info(st, 64, 1, 90000);
 
     ast = avformat_new_stream(s, NULL);
@@ -318,7 +318,7 @@  static int ty_read_header(AVFormatContext *s)
 
     if (ty->audio_type == TIVO_AUDIO_MPEG) {
         ast->codecpar->codec_id = AV_CODEC_ID_MP2;
-        ast->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
+        ast->internal->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
     } else {
         ast->codecpar->codec_id = AV_CODEC_ID_AC3;
     }
diff --git a/libavformat/utils.c b/libavformat/utils.c
index df6d9b5cf6..85f7b2e1cb 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -123,7 +123,12 @@  int64_t av_stream_get_end_pts(const AVStream *st)
 
 struct AVCodecParserContext *av_stream_get_parser(const AVStream *st)
 {
-    return st->parser;
+    return st->internal->parser;
+}
+
+void avpriv_stream_set_need_parsing(AVStream *st, enum AVStreamParseType type)
+{
+    st->internal->need_parsing = type;
 }
 
 void av_format_inject_global_side_data(AVFormatContext *s)
@@ -457,9 +462,9 @@  static int update_stream_avctx(AVFormatContext *s)
             continue;
 
         /* close parser, because it depends on the codec */
-        if (st->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
-            av_parser_close(st->parser);
-            st->parser = NULL;
+        if (st->internal->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
+            av_parser_close(st->internal->parser);
+            st->internal->parser = NULL;
         }
 
         /* update internal codec context, for the parser */
@@ -1256,7 +1261,7 @@  static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
 
     /* Correct timestamps with byte offset if demuxers only have timestamps
      * on packet boundaries */
-    if (pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size) {
+    if (pc && st->internal->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size) {
         /* this will estimate bitrate based on this frame's duration and size */
         offset = av_rescale(pc->offset, pkt->duration, pkt->size);
         if (pkt->pts != AV_NOPTS_VALUE)
@@ -1365,9 +1370,9 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
     int size      = pkt->size;
     int ret = 0, got_output = flush;
 
-    if (!size && !flush && st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+    if (!size && !flush && st->internal->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) {
         // preserve 0-size sync packets
-        compute_pkt_fields(s, st, st->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
+        compute_pkt_fields(s, st, st->internal->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
     }
 
     while (size > 0 || (flush && got_output)) {
@@ -1375,7 +1380,7 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
         int64_t next_pts = pkt->pts;
         int64_t next_dts = pkt->dts;
 
-        len = av_parser_parse2(st->parser, st->internal->avctx,
+        len = av_parser_parse2(st->internal->parser, st->internal->avctx,
                                &out_pkt->data, &out_pkt->size, data, size,
                                pkt->pts, pkt->dts, pkt->pos);
 
@@ -1394,7 +1399,7 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
         if (pkt->buf && out_pkt->data == pkt->data) {
             /* reference pkt->buf only when out_pkt->data is guaranteed to point
              * to data in it and not in the parser's internal buffer. */
-            /* XXX: Ensure this is the case with all parsers when st->parser->flags
+            /* XXX: Ensure this is the case with all parsers when st->internal->parser->flags
              * is PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */
             out_pkt->buf = av_buffer_ref(pkt->buf);
             if (!out_pkt->buf) {
@@ -1415,11 +1420,11 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
         }
 
         /* set the duration */
-        out_pkt->duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0;
+        out_pkt->duration = (st->internal->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0;
         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
             if (st->internal->avctx->sample_rate > 0) {
                 out_pkt->duration =
-                    av_rescale_q_rnd(st->parser->duration,
+                    av_rescale_q_rnd(st->internal->parser->duration,
                                      (AVRational) { 1, st->internal->avctx->sample_rate },
                                      st->time_base,
                                      AV_ROUND_DOWN);
@@ -1427,23 +1432,23 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
         }
 
         out_pkt->stream_index = st->index;
-        out_pkt->pts          = st->parser->pts;
-        out_pkt->dts          = st->parser->dts;
-        out_pkt->pos          = st->parser->pos;
+        out_pkt->pts          = st->internal->parser->pts;
+        out_pkt->dts          = st->internal->parser->dts;
+        out_pkt->pos          = st->internal->parser->pos;
         out_pkt->flags       |= pkt->flags & AV_PKT_FLAG_DISCARD;
 
-        if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
-            out_pkt->pos = st->parser->frame_offset;
+        if (st->internal->need_parsing == AVSTREAM_PARSE_FULL_RAW)
+            out_pkt->pos = st->internal->parser->frame_offset;
 
-        if (st->parser->key_frame == 1 ||
-            (st->parser->key_frame == -1 &&
-             st->parser->pict_type == AV_PICTURE_TYPE_I))
+        if (st->internal->parser->key_frame == 1 ||
+            (st->internal->parser->key_frame == -1 &&
+             st->internal->parser->pict_type == AV_PICTURE_TYPE_I))
             out_pkt->flags |= AV_PKT_FLAG_KEY;
 
-        if (st->parser->key_frame == -1 && st->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY))
+        if (st->internal->parser->key_frame == -1 && st->internal->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY))
             out_pkt->flags |= AV_PKT_FLAG_KEY;
 
-        compute_pkt_fields(s, st, st->parser, out_pkt, next_dts, next_pts);
+        compute_pkt_fields(s, st, st->internal->parser, out_pkt, next_dts, next_pts);
 
         ret = avpriv_packet_list_put(&s->internal->parse_queue,
                                  &s->internal->parse_queue_end,
@@ -1454,8 +1459,8 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt,
 
     /* end of the stream => close and free the parser */
     if (flush) {
-        av_parser_close(st->parser);
-        st->parser = NULL;
+        av_parser_close(st->internal->parser);
+        st->internal->parser = NULL;
     }
 
 fail:
@@ -1486,7 +1491,7 @@  static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
             /* flush the parsers */
             for (i = 0; i < s->nb_streams; i++) {
                 st = s->streams[i];
-                if (st->parser && st->need_parsing)
+                if (st->internal->parser && st->internal->need_parsing)
                     parse_packet(s, pkt, st->index, 1);
             }
             /* all remaining packets are now in parse_queue =>
@@ -1507,9 +1512,9 @@  static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
             }
 
             /* close parser, because it depends on the codec */
-            if (st->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
-                av_parser_close(st->parser);
-                st->parser = NULL;
+            if (st->internal->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
+                av_parser_close(st->internal->parser);
+                st->internal->parser = NULL;
             }
 
             ret = avcodec_parameters_to_context(st->internal->avctx, st->codecpar);
@@ -1539,23 +1544,23 @@  static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
                    av_ts2str(pkt->dts),
                    pkt->size, pkt->duration, pkt->flags);
 
-        if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
-            st->parser = av_parser_init(st->codecpar->codec_id);
-            if (!st->parser) {
+        if (st->internal->need_parsing && !st->internal->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
+            st->internal->parser = av_parser_init(st->codecpar->codec_id);
+            if (!st->internal->parser) {
                 av_log(s, AV_LOG_VERBOSE, "parser not found for codec "
                        "%s, packets or times may be invalid.\n",
                        avcodec_get_name(st->codecpar->codec_id));
                 /* no parser available: just output the raw packets */
-                st->need_parsing = AVSTREAM_PARSE_NONE;
-            } else if (st->need_parsing == AVSTREAM_PARSE_HEADERS)
-                st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
-            else if (st->need_parsing == AVSTREAM_PARSE_FULL_ONCE)
-                st->parser->flags |= PARSER_FLAG_ONCE;
-            else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
-                st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
+                st->internal->need_parsing = AVSTREAM_PARSE_NONE;
+            } else if (st->internal->need_parsing == AVSTREAM_PARSE_HEADERS)
+                st->internal->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+            else if (st->internal->need_parsing == AVSTREAM_PARSE_FULL_ONCE)
+                st->internal->parser->flags |= PARSER_FLAG_ONCE;
+            else if (st->internal->need_parsing == AVSTREAM_PARSE_FULL_RAW)
+                st->internal->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
         }
 
-        if (!st->need_parsing || !st->parser) {
+        if (!st->internal->need_parsing || !st->internal->parser) {
             /* no parsing needed: we just output the packet as is */
             compute_pkt_fields(s, st, NULL, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
             if ((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
@@ -1819,9 +1824,9 @@  void ff_read_frame_flush(AVFormatContext *s)
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
 
-        if (st->parser) {
-            av_parser_close(st->parser);
-            st->parser = NULL;
+        if (st->internal->parser) {
+            av_parser_close(st->internal->parser);
+            st->internal->parser = NULL;
         }
         st->internal->last_IP_pts = AV_NOPTS_VALUE;
         st->internal->last_dts_for_order_check = AV_NOPTS_VALUE;
@@ -2736,9 +2741,9 @@  static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
             av_log(ic, AV_LOG_WARNING,
                    "start time for stream %d is not set in estimate_timings_from_pts\n", i);
 
-        if (st->parser) {
-            av_parser_close(st->parser);
-            st->parser = NULL;
+        if (st->internal->parser) {
+            av_parser_close(st->internal->parser);
+            st->internal->parser = NULL;
         }
     }
 
@@ -2774,7 +2779,7 @@  static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
                 (st->start_time != AV_NOPTS_VALUE ||
                  st->first_dts  != AV_NOPTS_VALUE)) {
                 if (pkt->duration == 0) {
-                    ff_compute_frame_duration(ic, &num, &den, st, st->parser, pkt);
+                    ff_compute_frame_duration(ic, &num, &den, st, st->internal->parser, pkt);
                     if (den && num) {
                         pkt->duration = av_rescale_rnd(1,
                                            num * (int64_t) st->time_base.den,
@@ -3589,15 +3594,15 @@  int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
 
         /* check if the caller has overridden the codec id */
         // only for the split stuff
-        if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->internal->request_probe <= 0) {
-            st->parser = av_parser_init(st->codecpar->codec_id);
-            if (st->parser) {
-                if (st->need_parsing == AVSTREAM_PARSE_HEADERS) {
-                    st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
-                } else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) {
-                    st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
+        if (!st->internal->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->internal->request_probe <= 0) {
+            st->internal->parser = av_parser_init(st->codecpar->codec_id);
+            if (st->internal->parser) {
+                if (st->internal->need_parsing == AVSTREAM_PARSE_HEADERS) {
+                    st->internal->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+                } else if (st->internal->need_parsing == AVSTREAM_PARSE_FULL_RAW) {
+                    st->internal->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
                 }
-            } else if (st->need_parsing) {
+            } else if (st->internal->need_parsing) {
                 av_log(ic, AV_LOG_VERBOSE, "parser not found for codec "
                        "%s, packets or times may be invalid.\n",
                        avcodec_get_name(st->codecpar->codec_id));
@@ -3840,7 +3845,8 @@  int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
                     st->internal->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->internal->info->codec_info_duration + pkt->duration);
                 } else
                     st->internal->info->codec_info_duration += pkt->duration;
-                st->internal->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2;
+                st->internal->info->codec_info_duration_fields += st->internal->parser && st->internal->need_parsing && avctx->ticks_per_frame == 2
+                                                                  ? st->internal->parser->repeat_pict + 1 : 2;
             }
         }
         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -4256,8 +4262,8 @@  static void free_stream(AVStream **pst)
         av_freep(&st->side_data[i].data);
     av_freep(&st->side_data);
 
-    if (st->parser)
-        av_parser_close(st->parser);
+    if (st->internal->parser)
+        av_parser_close(st->internal->parser);
 
     if (st->attached_pic.data)
         av_packet_unref(&st->attached_pic);
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 8e2a7a7475..6bce9ba688 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -183,7 +183,7 @@  static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream *st)
         return ret;
     handle_stream_probing(st);
 
-    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
 
@@ -200,7 +200,7 @@  static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream *st)
 
     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id   = AV_CODEC_ID_XMA2;
-    st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
 
     version = avio_r8(pb);
     if (version != 3 && version != 4)
@@ -950,7 +950,7 @@  static int w64_read_header(AVFormatContext *s)
     ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
 
     handle_stream_probing(st);
-    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+    st->internal->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     avio_seek(pb, data_ofs, SEEK_SET);
 
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
index ab7e6b8188..a549681322 100644
--- a/libavformat/wtvdec.c
+++ b/libavformat/wtvdec.c
@@ -618,7 +618,7 @@  static AVStream * new_stream(AVFormatContext *s, AVStream *st, int sid, int code
         st->priv_data = wst;
     }
     st->codecpar->codec_type = codec_type;
-    st->need_parsing      = AVSTREAM_PARSE_FULL;
+    st->internal->need_parsing      = AVSTREAM_PARSE_FULL;
     avpriv_set_pts_info(st, 64, 1, 10000000);
     return st;
 }
diff --git a/libavformat/xvag.c b/libavformat/xvag.c
index 55bc25227e..2a85d66ecb 100644
--- a/libavformat/xvag.c
+++ b/libavformat/xvag.c
@@ -87,7 +87,7 @@  static int xvag_read_header(AVFormatContext *s)
     if (avio_rb16(s->pb) == 0xFFFB) {
         st->codecpar->codec_id    = AV_CODEC_ID_MP3;
         st->codecpar->block_align = 0x1000;
-        st->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
+        st->internal->need_parsing       = AVSTREAM_PARSE_FULL_RAW;
     }
 
     avio_skip(s->pb, -2);
diff --git a/libavformat/xwma.c b/libavformat/xwma.c
index 9c9b02e515..d7fd05504b 100644
--- a/libavformat/xwma.c
+++ b/libavformat/xwma.c
@@ -78,7 +78,7 @@  static int xwma_read_header(AVFormatContext *s)
     ret = ff_get_wav_header(s, pb, st->codecpar, size, 0);
     if (ret < 0)
         return ret;
-    st->need_parsing = AVSTREAM_PARSE_NONE;
+    st->internal->need_parsing = AVSTREAM_PARSE_NONE;
 
     /* XWMA encoder only allows a few channel/sample rate/bitrate combinations,
      * but some create identical files with fake bitrate (1ch 22050hz at