diff mbox series

[FFmpeg-devel,3/7,v2] avformat/mov: make MOVStreamContext refcounted

Message ID 20240130173218.63297-3-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel,1/7,v2] avcodec: add an Immersive Audio Model and Formats frame split bsf | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 fail Make failed
andriy/make_x86 fail Make failed

Commit Message

James Almer Jan. 30, 2024, 5:32 p.m. UTC
This will be needed by the following commit.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavformat/mov.c | 257 ++++++++++++++++++++++++++--------------------
 1 file changed, 145 insertions(+), 112 deletions(-)

Comments

Andreas Rheinhardt Jan. 30, 2024, 10:31 p.m. UTC | #1
James Almer:
> This will be needed by the following commit.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavformat/mov.c | 257 ++++++++++++++++++++++++++--------------------
>  1 file changed, 145 insertions(+), 112 deletions(-)
> 
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 3e71252e46..a0dfa22598 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -31,6 +31,7 @@
>  
>  #include "libavutil/attributes.h"
>  #include "libavutil/bprint.h"
> +#include "libavutil/buffer.h"
>  #include "libavutil/channel_layout.h"
>  #include "libavutil/dict_internal.h"
>  #include "libavutil/internal.h"
> @@ -184,10 +185,20 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
>      return p - dst;
>  }
>  
> +static void mov_free_stream_context(void *opaque, uint8_t *data);
> +
> +static inline MOVStreamContext *mov_get_stream_context(const AVStream *st)
> +{
> +    AVBufferRef *buf = st->priv_data;
> +
> +    return (MOVStreamContext *)buf->data;
> +}
> +
>  static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
>  {
>      AVStream *st;
> -    MOVStreamContext *sc;
> +    AVBufferRef *buf;
> +    uint8_t *data;
>      enum AVCodecID id;
>      int ret;
>  
> @@ -201,16 +212,22 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
>          return 0;
>      }
>  
> -    sc = av_mallocz(sizeof(*sc));
> -    if (!sc)
> +    data = av_mallocz(sizeof(MOVStreamContext));
> +    if (!data)
> +        return AVERROR(ENOMEM);
> +    buf = av_buffer_create(data, sizeof(MOVStreamContext), mov_free_stream_context, c->fc, 0);
> +    if (!buf) {
> +        av_free(data);
>          return AVERROR(ENOMEM);
> +    }
> +
>      ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
>      if (ret < 0) {
> -        av_free(sc);
> +        av_buffer_unref(&buf);
>          return ret;
>      }
>      st = c->fc->streams[c->fc->nb_streams - 1];
> -    st->priv_data = sc;
> +    st->priv_data = buf;
>  
>      if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
>          if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
> @@ -590,7 +607,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_rb32(pb); // version + flags
>      entries = avio_rb32(pb);
> @@ -1372,7 +1389,7 @@ static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st,
>                               MOVFragmentIndex *frag_index, int index)
>  {
>      MOVFragmentStreamInfo * frag_stream_info;
> -    MOVStreamContext *sc = dst_st->priv_data;
> +    MOVStreamContext *sc = mov_get_stream_context(dst_st);
>      int64_t timestamp;
>      int i, j;
>  
> @@ -1571,7 +1588,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      if (sc->time_scale) {
>          av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
> @@ -1714,7 +1731,7 @@ static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>          return AVERROR_INVALIDDATA;
>  
>      st = fc->streams[fc->nb_streams - 1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      if (sc->format == MOV_MP4_FPCM_TAG) {
>          switch (pcm_sample_size) {
> @@ -2217,7 +2234,7 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -2555,7 +2572,7 @@ static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
>          if (ret < 0)
>              return ret;
>          if (size > 16) {
> -            MOVStreamContext *tmcd_ctx = st->priv_data;
> +            MOVStreamContext *tmcd_ctx = mov_get_stream_context(st);
>              int val;
>              val = AV_RB32(st->codecpar->extradata + 4);
>              tmcd_ctx->tmcd_flags = val;
> @@ -2721,7 +2738,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
>  
>      av_assert0 (c->fc->nb_streams >= 1);
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      for (pseudo_stream_id = 0;
>           pseudo_stream_id < entries && !pb->eof_reached;
> @@ -2819,7 +2836,7 @@ static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams - 1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      sc->stsd_version = avio_r8(pb);
>      avio_rb24(pb); /* flags */
> @@ -2884,7 +2901,7 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -2980,7 +2997,7 @@ static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_rb32(pb); // version + flags
>  
> @@ -3018,7 +3035,7 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
>      sti = ffstream(st);
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -3069,7 +3086,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -3158,7 +3175,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -3269,7 +3286,7 @@ static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams - 1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -3314,7 +3331,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -3384,7 +3401,7 @@ static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams - 1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      version = avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -3440,7 +3457,7 @@ static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      version = avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -3541,7 +3558,7 @@ static int find_prev_closest_index(AVStream *st,
>                                     int64_t* ctts_index,
>                                     int64_t* ctts_sample)
>  {
> -    MOVStreamContext *msc = st->priv_data;
> +    MOVStreamContext *msc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      AVIndexEntry *e_keep = sti->index_entries;
>      int nb_keep = sti->nb_index_entries;
> @@ -3714,7 +3731,7 @@ static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, uns
>  #define MAX_REORDER_DELAY 16
>  static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
>  {
> -    MOVStreamContext *msc = st->priv_data;
> +    MOVStreamContext *msc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      int ctts_ind = 0;
>      int ctts_sample = 0;
> @@ -3822,7 +3839,7 @@ static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
>   */
>  static void mov_fix_index(MOVContext *mov, AVStream *st)
>  {
> -    MOVStreamContext *msc = st->priv_data;
> +    MOVStreamContext *msc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      AVIndexEntry *e_old = sti->index_entries;
>      int nb_old = sti->nb_index_entries;
> @@ -4136,7 +4153,7 @@ static int build_open_gop_key_points(AVStream *st)
>      int k;
>      int sample_id = 0;
>      uint32_t cra_index;
> -    MOVStreamContext *sc = st->priv_data;
> +    MOVStreamContext *sc = mov_get_stream_context(st);
>  
>      if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
>          return 0;
> @@ -4196,7 +4213,7 @@ static int build_open_gop_key_points(AVStream *st)
>  
>  static void mov_build_index(MOVContext *mov, AVStream *st)
>  {
> -    MOVStreamContext *sc = st->priv_data;
> +    MOVStreamContext *sc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      int64_t current_offset;
>      int64_t current_dts = 0;
> @@ -4636,16 +4653,24 @@ static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
>  static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  {
>      AVStream *st;
> +    AVBufferRef *buf;
>      MOVStreamContext *sc;
> +    uint8_t *data;
>      int ret;
>  
>      st = avformat_new_stream(c->fc, NULL);
>      if (!st) return AVERROR(ENOMEM);
>      st->id = -1;
> -    sc = av_mallocz(sizeof(MOVStreamContext));
> -    if (!sc) return AVERROR(ENOMEM);
> +    data = av_mallocz(sizeof(MOVStreamContext));
> +    if (!data) return AVERROR(ENOMEM);
> +    buf = av_buffer_create(data, sizeof(MOVStreamContext), mov_free_stream_context, c->fc, 0);
> +    if (!buf) {
> +        av_free(data);
> +        return AVERROR(ENOMEM);
> +    }
>  
> -    st->priv_data = sc;
> +    st->priv_data = buf;
> +    sc = mov_get_stream_context(st);
>      st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
>      sc->ffindex = st->index;
>      c->trak_index = st->index;
> @@ -4841,7 +4866,7 @@ static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      for (i = 0; i < 3; i++) {
>          uint8_t **p;
> @@ -4941,7 +4966,7 @@ static int heif_add_stream(MOVContext *c, HEIFItem *item)
>      st->time_base.num = st->time_base.den = 1;
>      st->nb_frames = 1;
>      sc->time_scale = 1;
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>      sc->pb = c->fc->pb;
>      sc->pb_is_copied = 1;
>  
> @@ -5013,7 +5038,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
>      // avoids corrupting AVStreams mapped to an earlier tkhd.
> @@ -5215,7 +5240,7 @@ static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>          av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
>          return 0;
>      }
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>      if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
>          return 0;
>      version = avio_r8(pb);
> @@ -5269,7 +5294,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>          av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
>          return 0;
>      }
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>      if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
>          return 0;
>  
> @@ -5572,7 +5597,7 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>          return 0;
>      }
>  
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      timescale = av_make_q(1, avio_rb32(pb));
>  
> @@ -5655,14 +5680,14 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>                  si = &item->stream_info[j];
>                  if (si->sidx_pts != AV_NOPTS_VALUE) {
>                      ref_st = c->fc->streams[j];
> -                    ref_sc = ref_st->priv_data;
> +                    ref_sc = mov_get_stream_context(ref_st);
>                      break;
>                  }
>              }
>          }
>          if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
>              st = c->fc->streams[i];
> -            sc = st->priv_data;
> +            sc = mov_get_stream_context(st);
>              if (!sc->has_sidx) {
>                  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
>              }
> @@ -5758,7 +5783,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  
>      if (c->fc->nb_streams < 1 || c->ignore_editlist)
>          return 0;
> -    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
> +    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams-1]);
>  
>      version = avio_r8(pb); /* version */
>      avio_rb24(pb); /* flags */
> @@ -5825,7 +5850,7 @@ static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  
>      if (c->fc->nb_streams < 1)
>          return AVERROR_INVALIDDATA;
> -    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
> +    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
>      sc->timecode_track = avio_rb32(pb);
>      return 0;
>  }
> @@ -5882,7 +5907,7 @@ static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return AVERROR_INVALIDDATA;
>  
> -    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
> +    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
>  
>      if (atom.size < 5) {
>          av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
> @@ -5930,7 +5955,7 @@ static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return AVERROR_INVALIDDATA;
>  
> -    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
> +    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
>  
>      if (atom.size < 24 || sc->mastering) {
>          av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
> @@ -5966,7 +5991,7 @@ static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return AVERROR_INVALIDDATA;
>  
> -    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
> +    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
>  
>      if (atom.size < 5) {
>          av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
> @@ -6002,7 +6027,7 @@ static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return AVERROR_INVALIDDATA;
>  
> -    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
> +    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
>  
>      if (atom.size < 4) {
>          av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
> @@ -6035,7 +6060,7 @@ static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>          return 0;
>  
>      st = c->fc->streams[c->fc->nb_streams - 1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      if (atom.size < 5) {
>          av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
> @@ -6085,7 +6110,7 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>          return 0;
>  
>      st = c->fc->streams[c->fc->nb_streams - 1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      if (atom.size < 8) {
>          av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
> @@ -6296,7 +6321,7 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams - 1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
>      if (ret < 0)
> @@ -6408,7 +6433,7 @@ static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams - 1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      switch (sc->format)
>      {
> @@ -6461,7 +6486,7 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry
>          }
>          if (i == c->fc->nb_streams)
>              return 0;
> -        *sc = st->priv_data;
> +        *sc = mov_get_stream_context(st);
>  
>          if (!frag_stream_info->encryption_index) {
>              // If this stream isn't encrypted, don't create the index.
> @@ -6479,7 +6504,7 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry
>          if (c->fc->nb_streams < 1)
>              return 0;
>          st = c->fc->streams[c->fc->nb_streams - 1];
> -        *sc = st->priv_data;
> +        *sc = mov_get_stream_context(st);
>  
>          if (!(*sc)->cenc.encryption_index) {
>              // If this stream isn't encrypted, don't create the index.
> @@ -6972,7 +6997,7 @@ static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      if (sc->pseudo_stream_id != 0) {
>          av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
> @@ -7004,7 +7029,7 @@ static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>  
>      if (sc->pseudo_stream_id != 0) {
>          av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
> @@ -8416,7 +8441,7 @@ static void mov_read_chapters(AVFormatContext *s)
>          }
>          sti = ffstream(st);
>  
> -        sc = st->priv_data;
> +        sc = mov_get_stream_context(st);
>          cur_pos = avio_tell(sc->pb);
>  
>          if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
> @@ -8506,7 +8531,7 @@ static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
>  
>  static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
>  {
> -    MOVStreamContext *sc = st->priv_data;
> +    MOVStreamContext *sc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      char buf[AV_TIMECODE_STR_SIZE];
>      int64_t cur_pos = avio_tell(sc->pb);
> @@ -8532,7 +8557,7 @@ static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
>  
>  static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
>  {
> -    MOVStreamContext *sc = st->priv_data;
> +    MOVStreamContext *sc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      int flags = 0;
>      int64_t cur_pos = avio_tell(sc->pb);
> @@ -8589,6 +8614,56 @@ static void mov_free_encryption_index(MOVEncryptionIndex **index) {
>      av_freep(index);
>  }
>  
> +static void mov_free_stream_context(void *opaque, uint8_t *data)
> +{
> +    AVFormatContext *s = opaque;
> +    MOVStreamContext *sc = (MOVStreamContext *)data;
> +
> +    av_freep(&sc->ctts_data);
> +    for (int i = 0; i < sc->drefs_count; i++) {
> +        av_freep(&sc->drefs[i].path);
> +        av_freep(&sc->drefs[i].dir);
> +    }
> +    av_freep(&sc->drefs);
> +
> +    sc->drefs_count = 0;
> +
> +    if (!sc->pb_is_copied)
> +        ff_format_io_close(s, &sc->pb);
> +
> +    sc->pb = NULL;
> +    av_freep(&sc->chunk_offsets);
> +    av_freep(&sc->stsc_data);
> +    av_freep(&sc->sample_sizes);
> +    av_freep(&sc->keyframes);
> +    av_freep(&sc->stts_data);
> +    av_freep(&sc->sdtp_data);
> +    av_freep(&sc->stps_data);
> +    av_freep(&sc->elst_data);
> +    av_freep(&sc->rap_group);
> +    av_freep(&sc->sync_group);
> +    av_freep(&sc->sgpd_sync);
> +    av_freep(&sc->sample_offsets);
> +    av_freep(&sc->open_key_samples);
> +    av_freep(&sc->display_matrix);
> +    av_freep(&sc->index_ranges);
> +
> +    if (sc->extradata)
> +        for (int i = 0; i < sc->stsd_count; i++)
> +            av_free(sc->extradata[i]);
> +    av_freep(&sc->extradata);
> +    av_freep(&sc->extradata_size);
> +
> +    mov_free_encryption_index(&sc->cenc.encryption_index);
> +    av_encryption_info_free(sc->cenc.default_encrypted_sample);
> +    av_aes_ctr_free(sc->cenc.aes_ctr);
> +
> +    av_freep(&sc->stereo3d);
> +    av_freep(&sc->spherical);
> +    av_freep(&sc->mastering);
> +    av_freep(&sc->coll);
> +}
> +
>  static int mov_read_close(AVFormatContext *s)
>  {
>      MOVContext *mov = s->priv_data;
> @@ -8596,54 +8671,12 @@ static int mov_read_close(AVFormatContext *s)
>  
>      for (i = 0; i < s->nb_streams; i++) {
>          AVStream *st = s->streams[i];
> -        MOVStreamContext *sc = st->priv_data;
> +        MOVStreamContext *sc = mov_get_stream_context(st);
>  
>          if (!sc)
>              continue;
>  
> -        av_freep(&sc->ctts_data);
> -        for (j = 0; j < sc->drefs_count; j++) {
> -            av_freep(&sc->drefs[j].path);
> -            av_freep(&sc->drefs[j].dir);
> -        }
> -        av_freep(&sc->drefs);
> -
> -        sc->drefs_count = 0;
> -
> -        if (!sc->pb_is_copied)
> -            ff_format_io_close(s, &sc->pb);
> -
> -        sc->pb = NULL;
> -        av_freep(&sc->chunk_offsets);
> -        av_freep(&sc->stsc_data);
> -        av_freep(&sc->sample_sizes);
> -        av_freep(&sc->keyframes);
> -        av_freep(&sc->stts_data);
> -        av_freep(&sc->sdtp_data);
> -        av_freep(&sc->stps_data);
> -        av_freep(&sc->elst_data);
> -        av_freep(&sc->rap_group);
> -        av_freep(&sc->sync_group);
> -        av_freep(&sc->sgpd_sync);
> -        av_freep(&sc->sample_offsets);
> -        av_freep(&sc->open_key_samples);
> -        av_freep(&sc->display_matrix);
> -        av_freep(&sc->index_ranges);
> -
> -        if (sc->extradata)
> -            for (j = 0; j < sc->stsd_count; j++)
> -                av_free(sc->extradata[j]);
> -        av_freep(&sc->extradata);
> -        av_freep(&sc->extradata_size);
> -
> -        mov_free_encryption_index(&sc->cenc.encryption_index);
> -        av_encryption_info_free(sc->cenc.default_encrypted_sample);
> -        av_aes_ctr_free(sc->cenc.aes_ctr);
> -
> -        av_freep(&sc->stereo3d);
> -        av_freep(&sc->spherical);
> -        av_freep(&sc->mastering);
> -        av_freep(&sc->coll);
> +        av_buffer_unref((AVBufferRef **)&st->priv_data);
>      }
>  
>      av_freep(&mov->dv_demux);
> @@ -8682,7 +8715,7 @@ static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
>  
>      for (i = 0; i < s->nb_streams; i++) {
>          AVStream *st = s->streams[i];
> -        MOVStreamContext *sc = st->priv_data;
> +        MOVStreamContext *sc = mov_get_stream_context(st);
>  
>          if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
>              sc->timecode_track == tmcd_id)
> @@ -8882,7 +8915,7 @@ static int mov_read_header(AVFormatContext *s)
>      /* copy timecode metadata from tmcd tracks to the related video streams */
>      for (i = 0; i < s->nb_streams; i++) {
>          AVStream *st = s->streams[i];
> -        MOVStreamContext *sc = st->priv_data;
> +        MOVStreamContext *sc = mov_get_stream_context(st);
>          if (sc->timecode_track > 0) {
>              AVDictionaryEntry *tcr;
>              int tmcd_st_id = -1;
> @@ -8903,7 +8936,7 @@ static int mov_read_header(AVFormatContext *s)
>      for (i = 0; i < s->nb_streams; i++) {
>          AVStream *st = s->streams[i];
>          FFStream *const sti = ffstream(st);
> -        MOVStreamContext *sc = st->priv_data;
> +        MOVStreamContext *sc = mov_get_stream_context(st);
>          fix_timescale(mov, sc);
>          if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
>              st->codecpar->codec_id   == AV_CODEC_ID_AAC) {
> @@ -8933,7 +8966,7 @@ static int mov_read_header(AVFormatContext *s)
>      if (mov->trex_data) {
>          for (i = 0; i < s->nb_streams; i++) {
>              AVStream *st = s->streams[i];
> -            MOVStreamContext *sc = st->priv_data;
> +            MOVStreamContext *sc = mov_get_stream_context(st);
>              if (st->duration > 0) {
>                  /* Akin to sc->data_size * 8 * sc->time_scale / st->duration but accounting for overflows. */
>                  st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, st->duration);
> @@ -8951,7 +8984,7 @@ static int mov_read_header(AVFormatContext *s)
>      if (mov->use_mfra_for > 0) {
>          for (i = 0; i < s->nb_streams; i++) {
>              AVStream *st = s->streams[i];
> -            MOVStreamContext *sc = st->priv_data;
> +            MOVStreamContext *sc = mov_get_stream_context(st);
>              if (sc->duration_for_fps > 0) {
>                  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
>                  st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, sc->duration_for_fps);
> @@ -8976,7 +9009,7 @@ static int mov_read_header(AVFormatContext *s)
>  
>      for (i = 0; i < s->nb_streams; i++) {
>          AVStream *st = s->streams[i];
> -        MOVStreamContext *sc = st->priv_data;
> +        MOVStreamContext *sc = mov_get_stream_context(st);
>  
>          switch (st->codecpar->codec_type) {
>          case AVMEDIA_TYPE_AUDIO:
> @@ -9047,7 +9080,7 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
>      for (i = 0; i < s->nb_streams; i++) {
>          AVStream *avst = s->streams[i];
>          FFStream *const avsti = ffstream(avst);
> -        MOVStreamContext *msc = avst->priv_data;
> +        MOVStreamContext *msc = mov_get_stream_context(avst);
>          if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
>              AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
>              int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
> @@ -9172,7 +9205,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
>              return ret;
>          goto retry;
>      }
> -    sc = st->priv_data;
> +    sc = mov_get_stream_context(st);
>      /* must be done just before reading, to avoid infinite loop on sample */
>      current_index = sc->current_index;
>      mov_current_sample_inc(sc);
> @@ -9338,7 +9371,7 @@ static int is_open_key_sample(const MOVStreamContext *sc, int sample)
>   */
>  static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
>  {
> -    MOVStreamContext *sc = st->priv_data;
> +    MOVStreamContext *sc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      int64_t key_sample_dts, key_sample_pts;
>  
> @@ -9364,7 +9397,7 @@ static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pt
>  
>  static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
>  {
> -    MOVStreamContext *sc = st->priv_data;
> +    MOVStreamContext *sc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      int sample, time_sample, ret;
>      unsigned int i;
> @@ -9426,7 +9459,7 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
>  
>  static int64_t mov_get_skip_samples(AVStream *st, int sample)
>  {
> -    MOVStreamContext *sc = st->priv_data;
> +    MOVStreamContext *sc = mov_get_stream_context(st);
>      FFStream *const sti = ffstream(st);
>      int64_t first_ts = sti->index_entries[0].timestamp;
>      int64_t ts = sti->index_entries[sample].timestamp;
> @@ -9480,7 +9513,7 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
>          for (i = 0; i < s->nb_streams; i++) {
>              MOVStreamContext *sc;
>              st = s->streams[i];
> -            sc = st->priv_data;
> +            sc = mov_get_stream_context(st);
>              mov_current_sample_set(sc, 0);
>          }
>          while (1) {
> @@ -9488,7 +9521,7 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
>              AVIndexEntry *entry = mov_find_next_sample(s, &st);
>              if (!entry)
>                  return AVERROR_INVALIDDATA;
> -            sc = st->priv_data;
> +            sc = mov_get_stream_context(st);
>              if (sc->ffindex == stream_index && sc->current_sample == sample)
>                  break;
>              mov_current_sample_inc(sc);

This is using the AVBuffer API for stuff for which lots of simpler ways
of achieving the same aim are possible: Simply add a refcount field to
MOVStreamContext and add a ref function and an unref function that
decrements the refcount, frees the MOVStreamContext if necessary and
(always) resets st->priv_data.

- Andreas
Michael Niedermayer Jan. 31, 2024, 1:58 a.m. UTC | #2
On Tue, Jan 30, 2024 at 02:32:14PM -0300, James Almer wrote:
> This will be needed by the following commit.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavformat/mov.c | 257 ++++++++++++++++++++++++++--------------------
>  1 file changed, 145 insertions(+), 112 deletions(-)

The previous commits dont seem to build alone

libavformat/mov.c: In function ‘heif_add_stream’:
libavformat/mov.c:4931:60: error: ‘mov_free_stream_context’ undeclared (first use in this function); did you mean ‘ff_find_stream_index’?
     buf = av_buffer_create(data, sizeof(MOVStreamContext), mov_free_stream_context, c->fc, 0);
                                                            ^~~~~~~~~~~~~~~~~~~~~~~
                                                            ff_find_stream_index
libavformat/mov.c:4931:60: note: each undeclared identifier is reported only once for each function it appears in
libavformat/mov.c:4942:10: error: implicit declaration of function ‘mov_get_stream_context’; did you mean ‘ffio_init_read_context’? [-Werror=implicit-function-declaration]
     sc = mov_get_stream_context(st);

And with this commit also not:

    libavcodec/libavcodec.a(bitstream_filters.o):(.data.rel.ro+0x90): undefined reference to `ff_iamf_stream_split_bsf'
collect2: error: ld returned 1 exit status
Makefile:133: recipe for target 'ffmpeg_g' failed
make: *** [ffmpeg_g] Error 1

the next builds


[...]
James Almer Jan. 31, 2024, 2:01 a.m. UTC | #3
On 1/30/2024 10:58 PM, Michael Niedermayer wrote:
> On Tue, Jan 30, 2024 at 02:32:14PM -0300, James Almer wrote:
>> This will be needed by the following commit.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>   libavformat/mov.c | 257 ++++++++++++++++++++++++++--------------------
>>   1 file changed, 145 insertions(+), 112 deletions(-)
> 
> The previous commits dont seem to build alone
> 
> libavformat/mov.c: In function ‘heif_add_stream’:
> libavformat/mov.c:4931:60: error: ‘mov_free_stream_context’ undeclared (first use in this function); did you mean ‘ff_find_stream_index’?
>       buf = av_buffer_create(data, sizeof(MOVStreamContext), mov_free_stream_context, c->fc, 0);
>                                                              ^~~~~~~~~~~~~~~~~~~~~~~
>                                                              ff_find_stream_index
> libavformat/mov.c:4931:60: note: each undeclared identifier is reported only once for each function it appears in
> libavformat/mov.c:4942:10: error: implicit declaration of function ‘mov_get_stream_context’; did you mean ‘ffio_init_read_context’? [-Werror=implicit-function-declaration]
>       sc = mov_get_stream_context(st);
> 
> And with this commit also not:
> 
>      libavcodec/libavcodec.a(bitstream_filters.o):(.data.rel.ro+0x90): undefined reference to `ff_iamf_stream_split_bsf'
> collect2: error: ld returned 1 exit status
> Makefile:133: recipe for target 'ffmpeg_g' failed
> make: *** [ffmpeg_g] Error 1
> 
> the next builds

Yes, i fucked up a rebase and some code meant for this patch ended up in 
2/7.

Will resend the set with some changes suggested by Andreas.
diff mbox series

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 3e71252e46..a0dfa22598 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -31,6 +31,7 @@ 
 
 #include "libavutil/attributes.h"
 #include "libavutil/bprint.h"
+#include "libavutil/buffer.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/dict_internal.h"
 #include "libavutil/internal.h"
@@ -184,10 +185,20 @@  static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
     return p - dst;
 }
 
+static void mov_free_stream_context(void *opaque, uint8_t *data);
+
+static inline MOVStreamContext *mov_get_stream_context(const AVStream *st)
+{
+    AVBufferRef *buf = st->priv_data;
+
+    return (MOVStreamContext *)buf->data;
+}
+
 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
 {
     AVStream *st;
-    MOVStreamContext *sc;
+    AVBufferRef *buf;
+    uint8_t *data;
     enum AVCodecID id;
     int ret;
 
@@ -201,16 +212,22 @@  static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
         return 0;
     }
 
-    sc = av_mallocz(sizeof(*sc));
-    if (!sc)
+    data = av_mallocz(sizeof(MOVStreamContext));
+    if (!data)
+        return AVERROR(ENOMEM);
+    buf = av_buffer_create(data, sizeof(MOVStreamContext), mov_free_stream_context, c->fc, 0);
+    if (!buf) {
+        av_free(data);
         return AVERROR(ENOMEM);
+    }
+
     ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
     if (ret < 0) {
-        av_free(sc);
+        av_buffer_unref(&buf);
         return ret;
     }
     st = c->fc->streams[c->fc->nb_streams - 1];
-    st->priv_data = sc;
+    st->priv_data = buf;
 
     if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
         if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
@@ -590,7 +607,7 @@  static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_rb32(pb); // version + flags
     entries = avio_rb32(pb);
@@ -1372,7 +1389,7 @@  static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st,
                              MOVFragmentIndex *frag_index, int index)
 {
     MOVFragmentStreamInfo * frag_stream_info;
-    MOVStreamContext *sc = dst_st->priv_data;
+    MOVStreamContext *sc = mov_get_stream_context(dst_st);
     int64_t timestamp;
     int i, j;
 
@@ -1571,7 +1588,7 @@  static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     if (sc->time_scale) {
         av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
@@ -1714,7 +1731,7 @@  static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return AVERROR_INVALIDDATA;
 
     st = fc->streams[fc->nb_streams - 1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     if (sc->format == MOV_MP4_FPCM_TAG) {
         switch (pcm_sample_size) {
@@ -2217,7 +2234,7 @@  static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -2555,7 +2572,7 @@  static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
         if (ret < 0)
             return ret;
         if (size > 16) {
-            MOVStreamContext *tmcd_ctx = st->priv_data;
+            MOVStreamContext *tmcd_ctx = mov_get_stream_context(st);
             int val;
             val = AV_RB32(st->codecpar->extradata + 4);
             tmcd_ctx->tmcd_flags = val;
@@ -2721,7 +2738,7 @@  int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
 
     av_assert0 (c->fc->nb_streams >= 1);
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     for (pseudo_stream_id = 0;
          pseudo_stream_id < entries && !pb->eof_reached;
@@ -2819,7 +2836,7 @@  static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams - 1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     sc->stsd_version = avio_r8(pb);
     avio_rb24(pb); /* flags */
@@ -2884,7 +2901,7 @@  static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -2980,7 +2997,7 @@  static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_rb32(pb); // version + flags
 
@@ -3018,7 +3035,7 @@  static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
     sti = ffstream(st);
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -3069,7 +3086,7 @@  static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -3158,7 +3175,7 @@  static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -3269,7 +3286,7 @@  static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams - 1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -3314,7 +3331,7 @@  static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -3384,7 +3401,7 @@  static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams - 1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     version = avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -3440,7 +3457,7 @@  static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     version = avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -3541,7 +3558,7 @@  static int find_prev_closest_index(AVStream *st,
                                    int64_t* ctts_index,
                                    int64_t* ctts_sample)
 {
-    MOVStreamContext *msc = st->priv_data;
+    MOVStreamContext *msc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     AVIndexEntry *e_keep = sti->index_entries;
     int nb_keep = sti->nb_index_entries;
@@ -3714,7 +3731,7 @@  static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, uns
 #define MAX_REORDER_DELAY 16
 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
 {
-    MOVStreamContext *msc = st->priv_data;
+    MOVStreamContext *msc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     int ctts_ind = 0;
     int ctts_sample = 0;
@@ -3822,7 +3839,7 @@  static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
  */
 static void mov_fix_index(MOVContext *mov, AVStream *st)
 {
-    MOVStreamContext *msc = st->priv_data;
+    MOVStreamContext *msc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     AVIndexEntry *e_old = sti->index_entries;
     int nb_old = sti->nb_index_entries;
@@ -4136,7 +4153,7 @@  static int build_open_gop_key_points(AVStream *st)
     int k;
     int sample_id = 0;
     uint32_t cra_index;
-    MOVStreamContext *sc = st->priv_data;
+    MOVStreamContext *sc = mov_get_stream_context(st);
 
     if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
         return 0;
@@ -4196,7 +4213,7 @@  static int build_open_gop_key_points(AVStream *st)
 
 static void mov_build_index(MOVContext *mov, AVStream *st)
 {
-    MOVStreamContext *sc = st->priv_data;
+    MOVStreamContext *sc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     int64_t current_offset;
     int64_t current_dts = 0;
@@ -4636,16 +4653,24 @@  static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
+    AVBufferRef *buf;
     MOVStreamContext *sc;
+    uint8_t *data;
     int ret;
 
     st = avformat_new_stream(c->fc, NULL);
     if (!st) return AVERROR(ENOMEM);
     st->id = -1;
-    sc = av_mallocz(sizeof(MOVStreamContext));
-    if (!sc) return AVERROR(ENOMEM);
+    data = av_mallocz(sizeof(MOVStreamContext));
+    if (!data) return AVERROR(ENOMEM);
+    buf = av_buffer_create(data, sizeof(MOVStreamContext), mov_free_stream_context, c->fc, 0);
+    if (!buf) {
+        av_free(data);
+        return AVERROR(ENOMEM);
+    }
 
-    st->priv_data = sc;
+    st->priv_data = buf;
+    sc = mov_get_stream_context(st);
     st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
     sc->ffindex = st->index;
     c->trak_index = st->index;
@@ -4841,7 +4866,7 @@  static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     for (i = 0; i < 3; i++) {
         uint8_t **p;
@@ -4941,7 +4966,7 @@  static int heif_add_stream(MOVContext *c, HEIFItem *item)
     st->time_base.num = st->time_base.den = 1;
     st->nb_frames = 1;
     sc->time_scale = 1;
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
     sc->pb = c->fc->pb;
     sc->pb_is_copied = 1;
 
@@ -5013,7 +5038,7 @@  static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
     // avoids corrupting AVStreams mapped to an earlier tkhd.
@@ -5215,7 +5240,7 @@  static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
         return 0;
     }
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
     if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
         return 0;
     version = avio_r8(pb);
@@ -5269,7 +5294,7 @@  static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
         return 0;
     }
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
     if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
         return 0;
 
@@ -5572,7 +5597,7 @@  static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return 0;
     }
 
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     timescale = av_make_q(1, avio_rb32(pb));
 
@@ -5655,14 +5680,14 @@  static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
                 si = &item->stream_info[j];
                 if (si->sidx_pts != AV_NOPTS_VALUE) {
                     ref_st = c->fc->streams[j];
-                    ref_sc = ref_st->priv_data;
+                    ref_sc = mov_get_stream_context(ref_st);
                     break;
                 }
             }
         }
         if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
             st = c->fc->streams[i];
-            sc = st->priv_data;
+            sc = mov_get_stream_context(st);
             if (!sc->has_sidx) {
                 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
             }
@@ -5758,7 +5783,7 @@  static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     if (c->fc->nb_streams < 1 || c->ignore_editlist)
         return 0;
-    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
+    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams-1]);
 
     version = avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -5825,7 +5850,7 @@  static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     if (c->fc->nb_streams < 1)
         return AVERROR_INVALIDDATA;
-    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
     sc->timecode_track = avio_rb32(pb);
     return 0;
 }
@@ -5882,7 +5907,7 @@  static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return AVERROR_INVALIDDATA;
 
-    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
 
     if (atom.size < 5) {
         av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
@@ -5930,7 +5955,7 @@  static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return AVERROR_INVALIDDATA;
 
-    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
 
     if (atom.size < 24 || sc->mastering) {
         av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
@@ -5966,7 +5991,7 @@  static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return AVERROR_INVALIDDATA;
 
-    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
 
     if (atom.size < 5) {
         av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
@@ -6002,7 +6027,7 @@  static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return AVERROR_INVALIDDATA;
 
-    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+    sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
 
     if (atom.size < 4) {
         av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
@@ -6035,7 +6060,7 @@  static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return 0;
 
     st = c->fc->streams[c->fc->nb_streams - 1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     if (atom.size < 5) {
         av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
@@ -6085,7 +6110,7 @@  static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return 0;
 
     st = c->fc->streams[c->fc->nb_streams - 1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     if (atom.size < 8) {
         av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
@@ -6296,7 +6321,7 @@  static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams - 1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
     if (ret < 0)
@@ -6408,7 +6433,7 @@  static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams - 1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     switch (sc->format)
     {
@@ -6461,7 +6486,7 @@  static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry
         }
         if (i == c->fc->nb_streams)
             return 0;
-        *sc = st->priv_data;
+        *sc = mov_get_stream_context(st);
 
         if (!frag_stream_info->encryption_index) {
             // If this stream isn't encrypted, don't create the index.
@@ -6479,7 +6504,7 @@  static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry
         if (c->fc->nb_streams < 1)
             return 0;
         st = c->fc->streams[c->fc->nb_streams - 1];
-        *sc = st->priv_data;
+        *sc = mov_get_stream_context(st);
 
         if (!(*sc)->cenc.encryption_index) {
             // If this stream isn't encrypted, don't create the index.
@@ -6972,7 +6997,7 @@  static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     if (sc->pseudo_stream_id != 0) {
         av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
@@ -7004,7 +7029,7 @@  static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
 
     if (sc->pseudo_stream_id != 0) {
         av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
@@ -8416,7 +8441,7 @@  static void mov_read_chapters(AVFormatContext *s)
         }
         sti = ffstream(st);
 
-        sc = st->priv_data;
+        sc = mov_get_stream_context(st);
         cur_pos = avio_tell(sc->pb);
 
         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -8506,7 +8531,7 @@  static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
 
 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
 {
-    MOVStreamContext *sc = st->priv_data;
+    MOVStreamContext *sc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     char buf[AV_TIMECODE_STR_SIZE];
     int64_t cur_pos = avio_tell(sc->pb);
@@ -8532,7 +8557,7 @@  static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
 
 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
 {
-    MOVStreamContext *sc = st->priv_data;
+    MOVStreamContext *sc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     int flags = 0;
     int64_t cur_pos = avio_tell(sc->pb);
@@ -8589,6 +8614,56 @@  static void mov_free_encryption_index(MOVEncryptionIndex **index) {
     av_freep(index);
 }
 
+static void mov_free_stream_context(void *opaque, uint8_t *data)
+{
+    AVFormatContext *s = opaque;
+    MOVStreamContext *sc = (MOVStreamContext *)data;
+
+    av_freep(&sc->ctts_data);
+    for (int i = 0; i < sc->drefs_count; i++) {
+        av_freep(&sc->drefs[i].path);
+        av_freep(&sc->drefs[i].dir);
+    }
+    av_freep(&sc->drefs);
+
+    sc->drefs_count = 0;
+
+    if (!sc->pb_is_copied)
+        ff_format_io_close(s, &sc->pb);
+
+    sc->pb = NULL;
+    av_freep(&sc->chunk_offsets);
+    av_freep(&sc->stsc_data);
+    av_freep(&sc->sample_sizes);
+    av_freep(&sc->keyframes);
+    av_freep(&sc->stts_data);
+    av_freep(&sc->sdtp_data);
+    av_freep(&sc->stps_data);
+    av_freep(&sc->elst_data);
+    av_freep(&sc->rap_group);
+    av_freep(&sc->sync_group);
+    av_freep(&sc->sgpd_sync);
+    av_freep(&sc->sample_offsets);
+    av_freep(&sc->open_key_samples);
+    av_freep(&sc->display_matrix);
+    av_freep(&sc->index_ranges);
+
+    if (sc->extradata)
+        for (int i = 0; i < sc->stsd_count; i++)
+            av_free(sc->extradata[i]);
+    av_freep(&sc->extradata);
+    av_freep(&sc->extradata_size);
+
+    mov_free_encryption_index(&sc->cenc.encryption_index);
+    av_encryption_info_free(sc->cenc.default_encrypted_sample);
+    av_aes_ctr_free(sc->cenc.aes_ctr);
+
+    av_freep(&sc->stereo3d);
+    av_freep(&sc->spherical);
+    av_freep(&sc->mastering);
+    av_freep(&sc->coll);
+}
+
 static int mov_read_close(AVFormatContext *s)
 {
     MOVContext *mov = s->priv_data;
@@ -8596,54 +8671,12 @@  static int mov_read_close(AVFormatContext *s)
 
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
-        MOVStreamContext *sc = st->priv_data;
+        MOVStreamContext *sc = mov_get_stream_context(st);
 
         if (!sc)
             continue;
 
-        av_freep(&sc->ctts_data);
-        for (j = 0; j < sc->drefs_count; j++) {
-            av_freep(&sc->drefs[j].path);
-            av_freep(&sc->drefs[j].dir);
-        }
-        av_freep(&sc->drefs);
-
-        sc->drefs_count = 0;
-
-        if (!sc->pb_is_copied)
-            ff_format_io_close(s, &sc->pb);
-
-        sc->pb = NULL;
-        av_freep(&sc->chunk_offsets);
-        av_freep(&sc->stsc_data);
-        av_freep(&sc->sample_sizes);
-        av_freep(&sc->keyframes);
-        av_freep(&sc->stts_data);
-        av_freep(&sc->sdtp_data);
-        av_freep(&sc->stps_data);
-        av_freep(&sc->elst_data);
-        av_freep(&sc->rap_group);
-        av_freep(&sc->sync_group);
-        av_freep(&sc->sgpd_sync);
-        av_freep(&sc->sample_offsets);
-        av_freep(&sc->open_key_samples);
-        av_freep(&sc->display_matrix);
-        av_freep(&sc->index_ranges);
-
-        if (sc->extradata)
-            for (j = 0; j < sc->stsd_count; j++)
-                av_free(sc->extradata[j]);
-        av_freep(&sc->extradata);
-        av_freep(&sc->extradata_size);
-
-        mov_free_encryption_index(&sc->cenc.encryption_index);
-        av_encryption_info_free(sc->cenc.default_encrypted_sample);
-        av_aes_ctr_free(sc->cenc.aes_ctr);
-
-        av_freep(&sc->stereo3d);
-        av_freep(&sc->spherical);
-        av_freep(&sc->mastering);
-        av_freep(&sc->coll);
+        av_buffer_unref((AVBufferRef **)&st->priv_data);
     }
 
     av_freep(&mov->dv_demux);
@@ -8682,7 +8715,7 @@  static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
 
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
-        MOVStreamContext *sc = st->priv_data;
+        MOVStreamContext *sc = mov_get_stream_context(st);
 
         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
             sc->timecode_track == tmcd_id)
@@ -8882,7 +8915,7 @@  static int mov_read_header(AVFormatContext *s)
     /* copy timecode metadata from tmcd tracks to the related video streams */
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
-        MOVStreamContext *sc = st->priv_data;
+        MOVStreamContext *sc = mov_get_stream_context(st);
         if (sc->timecode_track > 0) {
             AVDictionaryEntry *tcr;
             int tmcd_st_id = -1;
@@ -8903,7 +8936,7 @@  static int mov_read_header(AVFormatContext *s)
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         FFStream *const sti = ffstream(st);
-        MOVStreamContext *sc = st->priv_data;
+        MOVStreamContext *sc = mov_get_stream_context(st);
         fix_timescale(mov, sc);
         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
             st->codecpar->codec_id   == AV_CODEC_ID_AAC) {
@@ -8933,7 +8966,7 @@  static int mov_read_header(AVFormatContext *s)
     if (mov->trex_data) {
         for (i = 0; i < s->nb_streams; i++) {
             AVStream *st = s->streams[i];
-            MOVStreamContext *sc = st->priv_data;
+            MOVStreamContext *sc = mov_get_stream_context(st);
             if (st->duration > 0) {
                 /* Akin to sc->data_size * 8 * sc->time_scale / st->duration but accounting for overflows. */
                 st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, st->duration);
@@ -8951,7 +8984,7 @@  static int mov_read_header(AVFormatContext *s)
     if (mov->use_mfra_for > 0) {
         for (i = 0; i < s->nb_streams; i++) {
             AVStream *st = s->streams[i];
-            MOVStreamContext *sc = st->priv_data;
+            MOVStreamContext *sc = mov_get_stream_context(st);
             if (sc->duration_for_fps > 0) {
                 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
                 st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, sc->duration_for_fps);
@@ -8976,7 +9009,7 @@  static int mov_read_header(AVFormatContext *s)
 
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
-        MOVStreamContext *sc = st->priv_data;
+        MOVStreamContext *sc = mov_get_stream_context(st);
 
         switch (st->codecpar->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
@@ -9047,7 +9080,7 @@  static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *avst = s->streams[i];
         FFStream *const avsti = ffstream(avst);
-        MOVStreamContext *msc = avst->priv_data;
+        MOVStreamContext *msc = mov_get_stream_context(avst);
         if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
             AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
             int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
@@ -9172,7 +9205,7 @@  static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
             return ret;
         goto retry;
     }
-    sc = st->priv_data;
+    sc = mov_get_stream_context(st);
     /* must be done just before reading, to avoid infinite loop on sample */
     current_index = sc->current_index;
     mov_current_sample_inc(sc);
@@ -9338,7 +9371,7 @@  static int is_open_key_sample(const MOVStreamContext *sc, int sample)
  */
 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
 {
-    MOVStreamContext *sc = st->priv_data;
+    MOVStreamContext *sc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     int64_t key_sample_dts, key_sample_pts;
 
@@ -9364,7 +9397,7 @@  static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pt
 
 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
 {
-    MOVStreamContext *sc = st->priv_data;
+    MOVStreamContext *sc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     int sample, time_sample, ret;
     unsigned int i;
@@ -9426,7 +9459,7 @@  static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
 
 static int64_t mov_get_skip_samples(AVStream *st, int sample)
 {
-    MOVStreamContext *sc = st->priv_data;
+    MOVStreamContext *sc = mov_get_stream_context(st);
     FFStream *const sti = ffstream(st);
     int64_t first_ts = sti->index_entries[0].timestamp;
     int64_t ts = sti->index_entries[sample].timestamp;
@@ -9480,7 +9513,7 @@  static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
         for (i = 0; i < s->nb_streams; i++) {
             MOVStreamContext *sc;
             st = s->streams[i];
-            sc = st->priv_data;
+            sc = mov_get_stream_context(st);
             mov_current_sample_set(sc, 0);
         }
         while (1) {
@@ -9488,7 +9521,7 @@  static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
             AVIndexEntry *entry = mov_find_next_sample(s, &st);
             if (!entry)
                 return AVERROR_INVALIDDATA;
-            sc = st->priv_data;
+            sc = mov_get_stream_context(st);
             if (sc->ffindex == stream_index && sc->current_sample == sample)
                 break;
             mov_current_sample_inc(sc);