diff mbox series

[FFmpeg-devel,20/25] avformat: Avoid allocation for AVFormatInternal

Message ID AM7PR03MB6660310CEDCD8A4D85294E508FC89@AM7PR03MB6660.eurprd03.prod.outlook.com
State Superseded
Headers show
Series [FFmpeg-devel,01/25] avformat/matroskadec: Fix heap-buffer overflow upon gigantic timestamps | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/configureppc warning Failed to apply patch

Commit Message

Andreas Rheinhardt Aug. 27, 2021, 2:27 p.m. UTC
Do this by allocating AVFormatContext together with the data that is
currently in AVFormatInternal; or rather: Put AVFormatContext at the
beginning of a new structure called FFFormatContext (which encompasses
more than just the internal fields and is a proper context in its own
right, hence the name) and remove AVFormatInternal altogether.

The biggest simplifications occured in avformat_alloc_context(), where
one can now simply call avformat_free_context() in case of errors.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavformat/asfdec_f.c    | 12 ++++----
 libavformat/avformat.h    |  8 ------
 libavformat/boadec.c      |  4 +--
 libavformat/codec2.c      |  3 +-
 libavformat/dsfdec.c      |  7 ++---
 libavformat/dv.c          |  4 +--
 libavformat/flacdec.c     |  2 +-
 libavformat/fsb.c         |  2 +-
 libavformat/hca.c         | 12 ++++----
 libavformat/internal.h    | 14 +++++++--
 libavformat/ipmovie.c     |  2 +-
 libavformat/matroskadec.c |  6 ++--
 libavformat/matroskaenc.c |  4 +--
 libavformat/mp3dec.c      | 12 ++++----
 libavformat/mpegts.c      |  2 +-
 libavformat/mtv.c         |  2 +-
 libavformat/mux.c         | 28 +++++++++---------
 libavformat/mxfenc.c      |  2 +-
 libavformat/nutdec.c      |  2 +-
 libavformat/oggdec.c      | 11 +++----
 libavformat/options.c     | 45 +++++++++++------------------
 libavformat/pcm.c         |  2 +-
 libavformat/r3d.c         |  6 ++--
 libavformat/serdec.c      |  2 +-
 libavformat/smacker.c     |  2 +-
 libavformat/svs.c         |  1 -
 libavformat/utils.c       | 60 +++++++++++++++++++--------------------
 libavformat/vqf.c         |  2 +-
 libavformat/wavdec.c      |  2 +-
 libavformat/webm_chunk.c  |  4 +--
 libavformat/yop.c         |  2 +-
 libavformat/yuv4mpegdec.c |  6 ++--
 32 files changed, 130 insertions(+), 143 deletions(-)

Comments

James Almer Aug. 27, 2021, 4:34 p.m. UTC | #1
On 8/27/2021 11:27 AM, Andreas Rheinhardt wrote:
> diff --git a/libavformat/internal.h b/libavformat/internal.h
> index 4fc1154b9d..813032870f 100644
> --- a/libavformat/internal.h
> +++ b/libavformat/internal.h
> @@ -69,7 +69,12 @@ typedef struct FFFrac {
>   } FFFrac;
>   
>   
> -struct AVFormatInternal {
> +typedef struct FFFormatContext {

Why not just keep the AVFormatInternal name?

[...]

> diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
> index 5afbae2147..c80ea5e216 100644
> --- a/libavformat/oggdec.c
> +++ b/libavformat/oggdec.c
> @@ -174,7 +174,7 @@ static int ogg_reset(AVFormatContext *s)
>          os->segp       = 0;
>          os->incomplete = 0;
>          os->got_data = 0;
> -        if (start_pos <= s->internal->data_offset) {
> +        if (start_pos <= ffformatcontext(s)->data_offset) {

I'd prefer if you use dedicated pointers here and everywhere else you 
replace s->internal, like you did in patch 19, and get rid of 
ffformatcontext().

>              os->lastpts = 0;
>          }
>          os->start_trimming = 0;
diff mbox series

Patch

diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
index ff6ddfb967..eccf21f3b1 100644
--- a/libavformat/asfdec_f.c
+++ b/libavformat/asfdec_f.c
@@ -753,7 +753,7 @@  static int asf_read_header(AVFormatContext *s)
         } else {
             if (!s->keylen) {
                 if (!ff_guidcmp(&g, &ff_asf_content_encryption)) {
-                    AVPacket *pkt = s->internal->parse_pkt;
+                    AVPacket *pkt = ffformatcontext(s)->parse_pkt;
                     unsigned int len;
                     av_log(s, AV_LOG_WARNING,
                            "DRM protected stream detected, decoding will likely fail!\n");
@@ -884,7 +884,7 @@  static int asf_get_packet(AVFormatContext *s, AVIOContext *pb)
         if (asf->no_resync_search)
             off = 3;
 //         else if (s->packet_size > 0 && !asf->uses_std_ecc)
-//             off = (avio_tell(pb) - s->internal->data_offset) % s->packet_size + 3;
+//             off = (avio_tell(pb) - ffformatcontext(s)->data_offset) % s->packet_size + 3;
 
         c = d = e = -1;
         while (off-- > 0) {
@@ -1441,9 +1441,9 @@  static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
         start_pos[i] = pos;
 
     if (s->packet_size > 0)
-        pos = (pos + s->packet_size - 1 - s->internal->data_offset) /
+        pos = (pos + s->packet_size - 1 - ffformatcontext(s)->data_offset) /
               s->packet_size * s->packet_size +
-              s->internal->data_offset;
+              ffformatcontext(s)->data_offset;
     *ppos = pos;
     if (avio_seek(s->pb, pos, SEEK_SET) < 0)
         return AV_NOPTS_VALUE;
@@ -1525,7 +1525,7 @@  static int asf_build_simple_index(AVFormatContext *s, int stream_index)
         for (i = 0; i < ict; i++) {
             int pktnum        = avio_rl32(s->pb);
             int pktct         = avio_rl16(s->pb);
-            int64_t pos       = s->internal->data_offset + s->packet_size * (int64_t)pktnum;
+            int64_t pos       = ffformatcontext(s)->data_offset + s->packet_size * (int64_t)pktnum;
             int64_t index_pts = FFMAX(av_rescale(itime, i, 10000) - asf->hdr.preroll, 0);
 
             if (avio_feof(s->pb)) {
@@ -1573,7 +1573,7 @@  static int asf_read_seek(AVFormatContext *s, int stream_index,
     /* explicitly handle the case of seeking to 0 */
     if (!pts) {
         asf_reset_header(s);
-        avio_seek(s->pb, s->internal->data_offset, SEEK_SET);
+        avio_seek(s->pb, ffformatcontext(s)->data_offset, SEEK_SET);
         return 0;
     }
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 81d2ac38d0..95746ec46a 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1090,8 +1090,6 @@  enum AVDurationEstimationMethod {
     AVFMT_DURATION_FROM_BITRATE ///< Duration estimated from bitrate (less accurate)
 };
 
-typedef struct AVFormatInternal AVFormatInternal;
-
 /**
  * Format I/O context.
  * New fields can be added to the end with minor version bumps.
@@ -1560,12 +1558,6 @@  typedef struct AVFormatContext {
      */
     char *format_whitelist;
 
-    /**
-     * An opaque field for libavformat internal usage.
-     * Must not be accessed in any way by callers.
-     */
-    AVFormatInternal *internal;
-
     /**
      * IO repositioned flag.
      * This is set by avformat when the underlaying IO context read pointer
diff --git a/libavformat/boadec.c b/libavformat/boadec.c
index 69d17763ef..3c335cf410 100644
--- a/libavformat/boadec.c
+++ b/libavformat/boadec.c
@@ -56,14 +56,14 @@  static int read_header(AVFormatContext *s)
     st->codecpar->channels    = avio_rl32(s->pb);
     if (st->codecpar->channels > FF_SANE_NB_CHANNELS || st->codecpar->channels <= 0)
         return AVERROR(ENOSYS);
-    s->internal->data_offset = avio_rl32(s->pb);
+    ffformatcontext(s)->data_offset = avio_rl32(s->pb);
     avio_r8(s->pb);
     st->codecpar->block_align = avio_rl32(s->pb);
     if (st->codecpar->block_align > INT_MAX / FF_SANE_NB_CHANNELS || st->codecpar->block_align <= 0)
         return AVERROR_INVALIDDATA;
     st->codecpar->block_align *= st->codecpar->channels;
 
-    avio_seek(s->pb, s->internal->data_offset, SEEK_SET);
+    avio_seek(s->pb, ffformatcontext(s)->data_offset, SEEK_SET);
 
     return 0;
 }
diff --git a/libavformat/codec2.c b/libavformat/codec2.c
index 1ddba808dd..0b992836b3 100644
--- a/libavformat/codec2.c
+++ b/libavformat/codec2.c
@@ -177,7 +177,7 @@  static int codec2_read_header(AVFormatContext *s)
         return AVERROR_PATCHWELCOME;
     }
 
-    s->internal->data_offset = CODEC2_HEADER_SIZE;
+    ffformatcontext(s)->data_offset = CODEC2_HEADER_SIZE;
 
     return codec2_read_header_common(s, st);
 }
@@ -255,7 +255,6 @@  static int codec2raw_read_header(AVFormatContext *s)
         return ret;
     }
 
-    s->internal->data_offset = 0;
     codec2_make_extradata(st->codecpar->extradata, c2->mode);
 
     return codec2_read_header_common(s, st);
diff --git a/libavformat/dsfdec.c b/libavformat/dsfdec.c
index c872f98cc2..8acf17dd3d 100644
--- a/libavformat/dsfdec.c
+++ b/libavformat/dsfdec.c
@@ -141,7 +141,6 @@  static int dsf_read_header(AVFormatContext *s)
         return AVERROR_INVALIDDATA;
     dsf->data_size = avio_rl64(pb) - 12;
     dsf->data_end += dsf->data_size + 12;
-    s->internal->data_offset = avio_tell(pb);
 
     return 0;
 }
@@ -161,7 +160,7 @@  static int dsf_read_packet(AVFormatContext *s, AVPacket *pkt)
         int last_packet = pos == (dsf->data_end - st->codecpar->block_align);
 
         if (last_packet) {
-            int64_t data_pos = pos - s->internal->data_offset;
+            int64_t data_pos = pos - ffformatcontext(s)->data_offset;
             int64_t packet_size = dsf->audio_size - data_pos;
             int64_t skip_size = dsf->data_size - data_pos - packet_size;
             uint8_t *dst;
@@ -184,7 +183,7 @@  static int dsf_read_packet(AVFormatContext *s, AVPacket *pkt)
 
             pkt->pos = pos;
             pkt->stream_index = 0;
-            pkt->pts = (pos - s->internal->data_offset) / st->codecpar->channels;
+            pkt->pts = (pos - ffformatcontext(s)->data_offset) / st->codecpar->channels;
             pkt->duration = packet_size / st->codecpar->channels;
             return 0;
         }
@@ -194,7 +193,7 @@  static int dsf_read_packet(AVFormatContext *s, AVPacket *pkt)
         return ret;
 
     pkt->stream_index = 0;
-    pkt->pts = (pos - s->internal->data_offset) / st->codecpar->channels;
+    pkt->pts = (pos - ffformatcontext(s)->data_offset) / st->codecpar->channels;
     pkt->duration = st->codecpar->block_align / st->codecpar->channels;
 
     return 0;
diff --git a/libavformat/dv.c b/libavformat/dv.c
index d7909683c3..3f953be0aa 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -439,7 +439,7 @@  static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
     // FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
     const int frame_size = c->sys->frame_size;
     int64_t offset;
-    int64_t size       = avio_size(s->pb) - s->internal->data_offset;
+    int64_t size       = avio_size(s->pb) - ffformatcontext(s)->data_offset;
     int64_t max_offset = ((size - 1) / frame_size) * frame_size;
 
     offset = frame_size * timestamp;
@@ -449,7 +449,7 @@  static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
     else if (offset < 0)
         offset = 0;
 
-    return offset + s->internal->data_offset;
+    return offset + ffformatcontext(s)->data_offset;
 }
 
 void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index bfa464c508..2730e9cc50 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -258,7 +258,7 @@  static int flac_probe(const AVProbeData *p)
 static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_index,
                                              int64_t *ppos, int64_t pos_limit)
 {
-    AVPacket *pkt = s->internal->parse_pkt;
+    AVPacket *pkt = ffformatcontext(s)->parse_pkt;
     AVStream *st = s->streams[stream_index];
     AVCodecParserContext *parser;
     int ret;
diff --git a/libavformat/fsb.c b/libavformat/fsb.c
index f145d10fd3..9e8b9ca6b1 100644
--- a/libavformat/fsb.c
+++ b/libavformat/fsb.c
@@ -156,7 +156,7 @@  static int fsb_read_header(AVFormatContext *s)
     }
 
     avio_skip(pb, offset - avio_tell(pb));
-    s->internal->data_offset = avio_tell(pb);
+    ffformatcontext(s)->data_offset = avio_tell(pb);
 
     avpriv_set_pts_info(st, 64, 1, par->sample_rate);
 
diff --git a/libavformat/hca.c b/libavformat/hca.c
index 86be5b1345..eaa96a9b17 100644
--- a/libavformat/hca.c
+++ b/libavformat/hca.c
@@ -45,14 +45,14 @@  static int hca_read_header(AVFormatContext *s)
     uint32_t chunk;
     uint16_t version;
     uint32_t block_count;
-    uint16_t block_size;
+    uint16_t block_size, data_offset;
     int ret;
 
     avio_skip(pb, 4);
     version = avio_rb16(pb);
 
-    s->internal->data_offset = avio_rb16(pb);
-    if (s->internal->data_offset <= 8)
+    data_offset = avio_rb16(pb);
+    if (data_offset <= 8)
         return AVERROR_INVALIDDATA;
 
     st = avformat_new_stream(s, NULL);
@@ -60,7 +60,7 @@  static int hca_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
 
     par = st->codecpar;
-    ret = ff_alloc_extradata(par, s->internal->data_offset);
+    ret = ff_alloc_extradata(par, data_offset);
     if (ret < 0)
         return ret;
 
@@ -69,7 +69,7 @@  static int hca_read_header(AVFormatContext *s)
         return AVERROR(EIO);
     AV_WL32(par->extradata, MKTAG('H', 'C', 'A', 0));
     AV_WB16(par->extradata + 4, version);
-    AV_WB16(par->extradata + 6, s->internal->data_offset);
+    AV_WB16(par->extradata + 6, data_offset);
 
     bytestream2_init(&gb, par->extradata + 8, par->extradata_size - 8);
 
@@ -97,7 +97,7 @@  static int hca_read_header(AVFormatContext *s)
     par->block_align = block_size;
     st->duration = 1024 * block_count;
 
-    avio_seek(pb, s->internal->data_offset, SEEK_SET);
+    avio_seek(pb, data_offset, SEEK_SET);
     avpriv_set_pts_info(st, 64, 1, par->sample_rate);
 
     return 0;
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 4fc1154b9d..813032870f 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -69,7 +69,12 @@  typedef struct FFFrac {
 } FFFrac;
 
 
-struct AVFormatInternal {
+typedef struct FFFormatContext {
+    /**
+     * The public context.
+     */
+    AVFormatContext pub;
+
     /**
      * Number of streams relevant for interleaving.
      * Muxing only.
@@ -173,7 +178,12 @@  struct AVFormatInternal {
      * Set if chapter ids are strictly monotonic.
      */
     int chapter_ids_monotonic;
-};
+} FFFormatContext;
+
+static av_always_inline FFFormatContext *ffformatcontext(AVFormatContext *s)
+{
+    return (FFFormatContext*)s;
+}
 
 struct AVStreamInternal {
     /**
diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c
index c2505c6faf..9c996d4a98 100644
--- a/libavformat/ipmovie.c
+++ b/libavformat/ipmovie.c
@@ -644,7 +644,7 @@  static int ipmovie_read_header(AVFormatContext *s)
 
     if (chunk_type == CHUNK_VIDEO)
         ipmovie->audio_type = AV_CODEC_ID_NONE;  /* no audio */
-    else if (process_ipmovie_chunk(ipmovie, pb, s->internal->parse_pkt) != CHUNK_INIT_AUDIO) {
+    else if (process_ipmovie_chunk(ipmovie, pb, ffformatcontext(s)->parse_pkt) != CHUNK_INIT_AUDIO) {
         return AVERROR_INVALIDDATA;
     }
 
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index c67a728737..4bc6b40f44 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -382,7 +382,7 @@  typedef struct MatroskaDemuxContext {
     /* byte position of the segment inside the stream */
     int64_t segment_start;
 
-    /* This packet coincides with AVFormatInternal.parse_pkt
+    /* This packet coincides with FFFormatContext.parse_pkt
      * and is not owned by us. */
     AVPacket *pkt;
 
@@ -2944,7 +2944,7 @@  static int matroska_read_header(AVFormatContext *s)
     }
     ebml_free(ebml_syntax, &ebml);
 
-    matroska->pkt = s->internal->parse_pkt;
+    matroska->pkt = ffformatcontext(s)->parse_pkt;
 
     /* The next thing is a segment. */
     pos = avio_tell(matroska->ctx->pb);
@@ -2961,7 +2961,7 @@  static int matroska_read_header(AVFormatContext *s)
     }
     /* Set data_offset as it might be needed later by seek_frame_generic. */
     if (matroska->current_id == MATROSKA_ID_CLUSTER)
-        s->internal->data_offset = avio_tell(matroska->ctx->pb) - 4;
+        ffformatcontext(s)->data_offset = avio_tell(matroska->ctx->pb) - 4;
     matroska_execute_seekhead(matroska);
 
     if (!matroska->time_scale)
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 6e34243f6b..62be0ac386 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -1253,7 +1253,7 @@  static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
             // if there is no mkv-specific codec ID, use VFW mode
             put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC");
             track->write_dts = 1;
-            s->internal->avoid_negative_ts_use_pts = 0;
+            ffformatcontext(s)->avoid_negative_ts_use_pts = 0;
         }
 
         subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0);
@@ -2674,7 +2674,7 @@  static int mkv_init(struct AVFormatContext *s)
 
     if (s->avoid_negative_ts < 0) {
         s->avoid_negative_ts = 1;
-        s->internal->avoid_negative_ts_use_pts = 1;
+        ffformatcontext(s)->avoid_negative_ts_use_pts = 1;
     }
 
     if (!strcmp(s->oformat->name, "webm")) {
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 195d89814e..622b94e8ff 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -365,8 +365,8 @@  static int mp3_read_header(AVFormatContext *s)
     int ret;
     int i;
 
-    s->metadata = s->internal->id3v2_meta;
-    s->internal->id3v2_meta = NULL;
+    s->metadata = ffformatcontext(s)->id3v2_meta;
+    ffformatcontext(s)->id3v2_meta = NULL;
 
     st = avformat_new_stream(s, NULL);
     if (!st)
@@ -553,8 +553,8 @@  static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
 
     if (filesize <= 0) {
         int64_t size = avio_size(s->pb);
-        if (size > 0 && size > s->internal->data_offset)
-            filesize = size - s->internal->data_offset;
+        if (size > 0 && size > ffformatcontext(s)->data_offset)
+            filesize = size - ffformatcontext(s)->data_offset;
     }
 
     if (mp3->xing_toc && (mp3->usetoc || (fast_seek && !mp3->is_cbr))) {
@@ -575,7 +575,7 @@  static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
         ie = &ie1;
         timestamp = av_clip64(timestamp, 0, st->duration);
         ie->timestamp = timestamp;
-        ie->pos       = av_rescale(timestamp, filesize, st->duration) + s->internal->data_offset;
+        ie->pos       = av_rescale(timestamp, filesize, st->duration) + ffformatcontext(s)->data_offset;
     } else {
         return -1; // generic index code
     }
@@ -586,7 +586,7 @@  static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
 
     if (mp3->is_cbr && ie == &ie1 && mp3->frames) {
         int frame_duration = av_rescale(st->duration, 1, mp3->frames);
-        ie1.timestamp = frame_duration * av_rescale(best_pos - s->internal->data_offset, mp3->frames, mp3->header_filesize);
+        ie1.timestamp = frame_duration * av_rescale(best_pos - ffformatcontext(s)->data_offset, mp3->frames, mp3->header_filesize);
     }
 
     avpriv_update_cur_dts(s, st, ie->timestamp);
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index fe89d4fb9f..9662ef1e61 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -3070,7 +3070,7 @@  static int mpegts_read_header(AVFormatContext *s)
     int64_t pos, probesize = s->probesize;
     int64_t seekback = FFMAX(s->probesize, (int64_t)ts->resync_size + PROBE_PACKET_MAX_BUF);
 
-    s->internal->prefer_codec_framerate = 1;
+    ffformatcontext(s)->prefer_codec_framerate = 1;
 
     if (ffio_ensure_seekback(pb, seekback) < 0)
         av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n");
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index d33561b6ec..da02965fd8 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -202,7 +202,7 @@  static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
     AVIOContext *pb = s->pb;
     int ret;
 
-    if((avio_tell(pb) - s->internal->data_offset + mtv->img_segment_size) % mtv->full_segment_size)
+    if((avio_tell(pb) - ffformatcontext(s)->data_offset + mtv->img_segment_size) % mtv->full_segment_size)
     {
         avio_skip(pb, MTV_AUDIO_PADDING_SIZE);
 
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 036a1956f6..c2a1dc8a28 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -330,7 +330,7 @@  static int init_muxer(AVFormatContext *s, AVDictionary **options)
         }
 
         if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT)
-            s->internal->nb_interleaved_streams++;
+            ffformatcontext(s)->nb_interleaved_streams++;
     }
 
     if (!s->priv_data && of->priv_data_size > 0) {
@@ -433,7 +433,7 @@  static void flush_if_needed(AVFormatContext *s)
 
 static void deinit_muxer(AVFormatContext *s)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     if (s->oformat && s->oformat->deinit && si->initialized)
         s->oformat->deinit(s);
     si->initialized =
@@ -447,8 +447,8 @@  int avformat_init_output(AVFormatContext *s, AVDictionary **options)
     if ((ret = init_muxer(s, options)) < 0)
         return ret;
 
-    s->internal->initialized = 1;
-    s->internal->streams_initialized = ret;
+    ffformatcontext(s)->initialized = 1;
+    ffformatcontext(s)->streams_initialized = ret;
 
     if (s->oformat->init && ret) {
         if ((ret = init_pts(s)) < 0)
@@ -463,7 +463,7 @@  int avformat_init_output(AVFormatContext *s, AVDictionary **options)
 int avformat_write_header(AVFormatContext *s, AVDictionary **options)
 {
     int ret = 0;
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     int already_initialized = si->initialized;
     int streams_already_initialized = si->streams_initialized;
 
@@ -507,7 +507,7 @@  static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *
     int delay = st->codecpar->video_delay;
     int frame_size;
 
-    if (!s->internal->missing_ts_warning &&
+    if (!ffformatcontext(s)->missing_ts_warning &&
         !(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
         (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC) || (st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS)) &&
         (pkt->pts == AV_NOPTS_VALUE || pkt->dts == AV_NOPTS_VALUE)) {
@@ -515,7 +515,7 @@  static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *
                "Timestamps are unset in a packet for stream %d. "
                "This is deprecated and will stop working in the future. "
                "Fix your code to set the timestamps properly\n", st->index);
-        s->internal->missing_ts_warning = 1;
+        ffformatcontext(s)->missing_ts_warning = 1;
     }
 
     if (s->debug & FF_FDEBUG_TS)
@@ -652,7 +652,7 @@  static int write_packet(AVFormatContext *s, AVPacket *pkt)
     }
 
     if (s->avoid_negative_ts > 0) {
-        AVFormatInternal *const si = s->internal;
+        FFFormatContext *const si = ffformatcontext(s);
         AVStream *st = s->streams[pkt->stream_index];
         int64_t offset = st->internal->mux_ts_offset;
         int64_t ts = si->avoid_negative_ts_use_pts ? pkt->pts : pkt->dts;
@@ -789,7 +789,7 @@  int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
                              int (*compare)(AVFormatContext *, const AVPacket *, const AVPacket *))
 {
     int ret;
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     PacketList **next_point, *this_pktl;
     AVStream *st = s->streams[pkt->stream_index];
     int chunked  = s->max_chunk_size || s->max_chunk_duration;
@@ -891,7 +891,7 @@  static int interleave_compare_dts(AVFormatContext *s, const AVPacket *next,
 int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
                                  AVPacket *pkt, int flush)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     int stream_count = 0;
     int noninterleaved_count = 0;
     int ret;
@@ -1020,7 +1020,7 @@  int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset
 
 const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream)
 {
-    PacketList *pktl = s->internal->packet_buffer;
+    PacketList *pktl = ffformatcontext(s)->packet_buffer;
     while (pktl) {
         if (pktl->pkt.stream_index == stream) {
             return &pktl->pkt;
@@ -1166,7 +1166,7 @@  static int write_packets_common(AVFormatContext *s, AVPacket *pkt, int interleav
 
 int av_write_frame(AVFormatContext *s, AVPacket *in)
 {
-    AVPacket *pkt = s->internal->pkt;
+    AVPacket *pkt = ffformatcontext(s)->pkt;
     int ret;
 
     if (!in) {
@@ -1228,7 +1228,7 @@  int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
 
 int av_write_trailer(AVFormatContext *s)
 {
-    AVPacket *pkt = s->internal->pkt;
+    AVPacket *pkt = ffformatcontext(s)->pkt;
     int ret1, ret = 0;
 
     av_packet_unref(pkt);
@@ -1310,7 +1310,7 @@  static void uncoded_frame_free(void *unused, uint8_t *data)
 static int write_uncoded_frame_internal(AVFormatContext *s, int stream_index,
                                         AVFrame *frame, int interleaved)
 {
-    AVPacket *pkt = s->internal->pkt;
+    AVPacket *pkt = ffformatcontext(s)->pkt;
 
     av_assert0(s->oformat);
     if (!s->oformat->write_uncoded_frame) {
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 36f334adbf..8e57e10487 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -3100,7 +3100,7 @@  static void mxf_deinit(AVFormatContext *s)
 
 static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     int i, stream_count = 0;
 
     for (i = 0; i < s->nb_streams; i++)
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index c6c015f8f0..50f8b64d10 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -845,7 +845,7 @@  static int nut_read_header(AVFormatContext *s)
         decode_info_header(nut);
     }
 
-    s->internal->data_offset = pos - 8;
+    ffformatcontext(s)->data_offset = pos - 8;
 
     if (bc->seekable & AVIO_SEEKABLE_NORMAL) {
         int64_t orig_pos = avio_tell(bc);
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 5afbae2147..c80ea5e216 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -174,7 +174,7 @@  static int ogg_reset(AVFormatContext *s)
         os->segp       = 0;
         os->incomplete = 0;
         os->got_data = 0;
-        if (start_pos <= s->internal->data_offset) {
+        if (start_pos <= ffformatcontext(s)->data_offset) {
             os->lastpts = 0;
         }
         os->start_trimming = 0;
@@ -572,6 +572,7 @@  static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
         }
         os->header = ret;
         if (!os->header) {
+            FFFormatContext *const si = ffformatcontext(s);
             os->segp  = segp;
             os->psize = psize;
 
@@ -582,8 +583,8 @@  static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
 
             // Update the header state for all streams and
             // compute the data_offset.
-            if (!s->internal->data_offset)
-                s->internal->data_offset = os->sync_pos;
+            if (!si->data_offset)
+                si->data_offset = os->sync_pos;
 
             for (i = 0; i < ogg->nstreams; i++) {
                 struct ogg_stream *cur_os = ogg->streams + i;
@@ -591,7 +592,7 @@  static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
                 // if we have a partial non-header packet, its start is
                 // obviously at or after the data start
                 if (cur_os->incomplete)
-                    s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
+                    si->data_offset = FFMIN(si->data_offset, cur_os->sync_pos);
             }
         } else {
             os->nb_header++;
@@ -684,7 +685,7 @@  static int ogg_get_length(AVFormatContext *s)
     if (ret < 0)
         return ret;
 
-    avio_seek (s->pb, s->internal->data_offset, SEEK_SET);
+    avio_seek (s->pb, ffformatcontext(s)->data_offset, SEEK_SET);
     ogg_reset(s);
     while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
         int64_t pts;
diff --git a/libavformat/options.c b/libavformat/options.c
index dccb6faa73..753aa9b8dc 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -151,46 +151,33 @@  static void io_close_default(AVFormatContext *s, AVIOContext *pb)
     avio_close(pb);
 }
 
-static void avformat_get_context_defaults(AVFormatContext *s)
+AVFormatContext *avformat_alloc_context(void)
 {
-    memset(s, 0, sizeof(AVFormatContext));
+    FFFormatContext *const si = av_mallocz(sizeof(*si));
+    AVFormatContext *s;
 
-    s->av_class = &av_format_context_class;
+    if (!si)
+        return NULL;
 
+    s = &si->pub;
+    s->av_class = &av_format_context_class;
     s->io_open  = io_open_default;
     s->io_close = io_close_default;
 
     av_opt_set_defaults(s);
-}
 
-AVFormatContext *avformat_alloc_context(void)
-{
-    AVFormatContext *ic;
-    AVFormatInternal *internal;
-    ic = av_malloc(sizeof(AVFormatContext));
-    if (!ic) return ic;
-
-    internal = av_mallocz(sizeof(*internal));
-    if (!internal) {
-        av_free(ic);
+    si->pkt = av_packet_alloc();
+    si->parse_pkt = av_packet_alloc();
+    if (!si->pkt || !si->parse_pkt) {
+        avformat_free_context(s);
         return NULL;
     }
-    internal->pkt = av_packet_alloc();
-    internal->parse_pkt = av_packet_alloc();
-    if (!internal->pkt || !internal->parse_pkt) {
-        av_packet_free(&internal->pkt);
-        av_packet_free(&internal->parse_pkt);
-        av_free(internal);
-        av_free(ic);
-        return NULL;
-    }
-    avformat_get_context_defaults(ic);
-    ic->internal = internal;
-    ic->internal->offset = AV_NOPTS_VALUE;
-    ic->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
-    ic->internal->shortest_end = AV_NOPTS_VALUE;
 
-    return ic;
+    si->offset = AV_NOPTS_VALUE;
+    si->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
+    si->shortest_end = AV_NOPTS_VALUE;
+
+    return s;
 }
 
 enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx)
diff --git a/libavformat/pcm.c b/libavformat/pcm.c
index 0e5443a826..cfa5b969cb 100644
--- a/libavformat/pcm.c
+++ b/libavformat/pcm.c
@@ -80,7 +80,7 @@  int ff_pcm_read_seek(AVFormatContext *s,
 
     /* recompute exact position */
     st->internal->cur_dts = av_rescale(pos, st->time_base.den, byte_rate * (int64_t)st->time_base.num);
-    if ((ret = avio_seek(s->pb, pos + s->internal->data_offset, SEEK_SET)) < 0)
+    if ((ret = avio_seek(s->pb, pos + ffformatcontext(s)->data_offset, SEEK_SET)) < 0)
         return ret;
     return 0;
 }
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 004efac355..2b1fe3099a 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -183,8 +183,8 @@  static int r3d_read_header(AVFormatContext *s)
     if (r3d->audio_channels)
         s->ctx_flags |= AVFMTCTX_NOHEADER;
 
-    s->internal->data_offset = avio_tell(s->pb);
-    av_log(s, AV_LOG_TRACE, "data offset %#"PRIx64"\n", s->internal->data_offset);
+    ffformatcontext(s)->data_offset = avio_tell(s->pb);
+    av_log(s, AV_LOG_TRACE, "data offset %#"PRIx64"\n", ffformatcontext(s)->data_offset);
     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
         return 0;
     // find REOB/REOF/REOS to load index
@@ -210,7 +210,7 @@  static int r3d_read_header(AVFormatContext *s)
     }
 
  out:
-    avio_seek(s->pb, s->internal->data_offset, SEEK_SET);
+    avio_seek(s->pb, ffformatcontext(s)->data_offset, SEEK_SET);
     return 0;
 }
 
diff --git a/libavformat/serdec.c b/libavformat/serdec.c
index fa2de32fd5..fe185cabd9 100644
--- a/libavformat/serdec.c
+++ b/libavformat/serdec.c
@@ -110,7 +110,7 @@  static int ser_read_packet(AVFormatContext *s, AVPacket *pkt)
         return AVERROR_EOF;
 
     ret = av_get_packet(s->pb, pkt, s->packet_size);
-    pkt->pts = pkt->dts = (pkt->pos - s->internal->data_offset) / s->packet_size;
+    pkt->pts = pkt->dts = (pkt->pos - ffformatcontext(s)->data_offset) / s->packet_size;
 
     pkt->stream_index = 0;
     if (ret < 0)
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index a96093b191..98436bd708 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -374,7 +374,7 @@  static int smacker_read_seek(AVFormatContext *s, int stream_index,
         return AVERROR(EINVAL);
     }
 
-    if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0)
+    if ((ret = avio_seek(s->pb, ffformatcontext(s)->data_offset, SEEK_SET)) < 0)
         return ret;
 
     smk->cur_frame = 0;
diff --git a/libavformat/svs.c b/libavformat/svs.c
index da63c8e370..e5300203f5 100644
--- a/libavformat/svs.c
+++ b/libavformat/svs.c
@@ -51,7 +51,6 @@  static int svs_read_header(AVFormatContext *s)
     pitch = avio_rl32(s->pb);
     avio_skip(s->pb, 12);
 
-    s->internal->data_offset     = avio_tell(s->pb);
     st->codecpar->codec_type     = AVMEDIA_TYPE_AUDIO;
     st->codecpar->codec_id       = AV_CODEC_ID_ADPCM_PSX;
     st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 67ec3384d0..58d4f09f35 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -135,7 +135,7 @@  void avpriv_stream_set_need_parsing(AVStream *st, enum AVStreamParseType type)
 
 void av_format_inject_global_side_data(AVFormatContext *s)
 {
-    s->internal->inject_global_side_data = 1;
+    ffformatcontext(s)->inject_global_side_data = 1;
     for (unsigned i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         st->internal->inject_global_side_data = 1;
@@ -371,6 +371,7 @@  static int init_input(AVFormatContext *s, const char *filename,
 
 int avformat_queue_attached_pictures(AVFormatContext *s)
 {
+    FFFormatContext *const si = ffformatcontext(s);
     int ret;
     for (unsigned i = 0; i < s->nb_streams; i++)
         if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
@@ -382,8 +383,8 @@  int avformat_queue_attached_pictures(AVFormatContext *s)
                 continue;
             }
 
-            ret = avpriv_packet_list_put(&s->internal->raw_packet_buffer,
-                                     &s->internal->raw_packet_buffer_end,
+            ret = avpriv_packet_list_put(&si->raw_packet_buffer,
+                                         &si->raw_packet_buffer_end,
                                      &s->streams[i]->attached_pic,
                                      av_packet_ref, 0);
             if (ret < 0)
@@ -457,14 +458,14 @@  int avformat_open_input(AVFormatContext **ps, const char *filename,
                         const AVInputFormat *fmt, AVDictionary **options)
 {
     AVFormatContext *s = *ps;
-    AVFormatInternal *si;
+    FFFormatContext *si;
     int ret = 0;
     AVDictionary *tmp = NULL;
     ID3v2ExtraMeta *id3v2_extra_meta = NULL;
 
     if (!s && !(s = avformat_alloc_context()))
         return AVERROR(ENOMEM);
-    si = s->internal;
+    si = ffformatcontext(s);
     if (!s->av_class) {
         av_log(NULL, AV_LOG_ERROR, "Input context has not been properly allocated by avformat_alloc_context() and is not NULL either\n");
         return AVERROR(EINVAL);
@@ -654,7 +655,7 @@  no_packet:
             }
         }
 
-        end=    s->internal->raw_packet_buffer_remaining_size <= 0
+        end = ffformatcontext(s)->raw_packet_buffer_remaining_size <= 0
                 || st->internal->probe_packets<= 0;
 
         if (end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) {
@@ -743,7 +744,7 @@  static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in
 
 int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     AVStream *st;
     int err;
 
@@ -960,7 +961,7 @@  static int has_decode_delay_been_guessed(AVStream *st)
 
 static PacketList *get_next_pkt(AVFormatContext *s, AVStream *st, PacketList *pktl)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     if (pktl->next)
         return pktl->next;
     if (pktl == si->packet_buffer_end)
@@ -1042,7 +1043,7 @@  static void update_dts_from_pts(AVFormatContext *s, int stream_index,
 static void update_initial_timestamps(AVFormatContext *s, int stream_index,
                                       int64_t dts, int64_t pts, AVPacket *pkt)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     AVStream *st       = s->streams[stream_index];
     PacketList *pktl = si->packet_buffer ? si->packet_buffer : si->parse_queue;
     PacketList *pktl_it;
@@ -1096,7 +1097,7 @@  static void update_initial_timestamps(AVFormatContext *s, int stream_index,
 static void update_initial_durations(AVFormatContext *s, AVStream *st,
                                      int stream_index, int64_t duration)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     PacketList *pktl = si->packet_buffer ? si->packet_buffer : si->parse_queue;
     int64_t cur_dts    = RELATIVE_TS_BASE;
 
@@ -1237,7 +1238,7 @@  static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
         }
     }
 
-    if (pkt->duration > 0 && (s->internal->packet_buffer || s->internal->parse_queue))
+    if (pkt->duration > 0 && (ffformatcontext(s)->packet_buffer || ffformatcontext(s)->parse_queue))
         update_initial_durations(s, st, pkt->stream_index, pkt->duration);
 
     /* Correct timestamps with byte offset if demuxers only have timestamps
@@ -1345,7 +1346,7 @@  static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
 static int parse_packet(AVFormatContext *s, AVPacket *pkt,
                         int stream_index, int flush)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     AVPacket *out_pkt = si->parse_pkt;
     AVStream *st = s->streams[stream_index];
     uint8_t *data = pkt->data;
@@ -1459,7 +1460,7 @@  static int64_t ts_to_samples(AVStream *st, int64_t ts)
 
 static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     int ret, got_packet = 0;
     AVDictionary *metadata = NULL;
 
@@ -1647,7 +1648,7 @@  static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
 
 int av_read_frame(AVFormatContext *s, AVPacket *pkt)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     const int genpts = s->flags & AVFMT_FLAG_GENPTS;
     int eof = 0;
     int ret;
@@ -1747,7 +1748,7 @@  return_packet:
 /* XXX: suppress the packet queue */
 static void flush_packet_queue(AVFormatContext *s)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     avpriv_packet_list_free(&si->parse_queue,       &si->parse_queue_end);
     avpriv_packet_list_free(&si->packet_buffer,     &si->packet_buffer_end);
     avpriv_packet_list_free(&si->raw_packet_buffer, &si->raw_packet_buffer_end);
@@ -1820,7 +1821,7 @@  void ff_read_frame_flush(AVFormatContext *s)
         for (int j = 0; j < MAX_REORDER_DELAY + 1; j++)
             st->internal->pts_buffer[j] = AV_NOPTS_VALUE;
 
-        if (s->internal->inject_global_side_data)
+        if (ffformatcontext(s)->inject_global_side_data)
             st->internal->inject_global_side_data = 1;
 
         st->internal->skip_samples = 0;
@@ -2191,7 +2192,7 @@  int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
     av_log(s, AV_LOG_TRACE, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts));
 
     if (ts_min == AV_NOPTS_VALUE) {
-        pos_min = s->internal->data_offset;
+        pos_min = ffformatcontext(s)->data_offset;
         ts_min  = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
         if (ts_min == AV_NOPTS_VALUE)
             return -1;
@@ -2287,7 +2288,7 @@  static int seek_frame_byte(AVFormatContext *s, int stream_index,
 {
     int64_t pos_min, pos_max;
 
-    pos_min = s->internal->data_offset;
+    pos_min = ffformatcontext(s)->data_offset;
     pos_max = avio_size(s->pb) - 1;
 
     if (pos < pos_min)
@@ -2319,7 +2320,7 @@  static int seek_frame_generic(AVFormatContext *s, int stream_index,
         return -1;
 
     if (index < 0 || index == st->internal->nb_index_entries - 1) {
-        AVPacket *pkt = s->internal->pkt;
+        AVPacket *pkt = ffformatcontext(s)->pkt;
         int nonkey = 0;
 
         if (st->internal->nb_index_entries) {
@@ -2330,7 +2331,7 @@  static int seek_frame_generic(AVFormatContext *s, int stream_index,
             s->io_repositioned = 1;
             avpriv_update_cur_dts(s, st, ie->timestamp);
         } else {
-            if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0)
+            if ((ret = avio_seek(s->pb, ffformatcontext(s)->data_offset, SEEK_SET)) < 0)
                 return ret;
             s->io_repositioned = 1;
         }
@@ -2670,8 +2671,8 @@  static void estimate_timings_from_bit_rate(AVFormatContext *ic)
     if (ic->duration == AV_NOPTS_VALUE &&
         ic->bit_rate != 0) {
         int64_t filesize = ic->pb ? avio_size(ic->pb) : 0;
-        if (filesize > ic->internal->data_offset) {
-            filesize -= ic->internal->data_offset;
+        if (filesize > ffformatcontext(ic)->data_offset) {
+            filesize -= ffformatcontext(ic)->data_offset;
             for (unsigned i = 0; i < ic->nb_streams; i++) {
                 AVStream *const st = ic->streams[i];
 
@@ -2696,7 +2697,7 @@  static void estimate_timings_from_bit_rate(AVFormatContext *ic)
 /* only usable for MPEG-PS streams */
 static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
 {
-    AVPacket *pkt = ic->internal->pkt;
+    AVPacket *pkt = ffformatcontext(ic)->pkt;
     int num, den, read_size, ret;
     int found_duration = 0;
     int is_end;
@@ -3444,7 +3445,7 @@  fail:
     return ret;
 }
 
-static int extract_extradata(AVFormatInternal *si, AVStream *st, const AVPacket *pkt)
+static int extract_extradata(FFFormatContext *si, AVStream *st, const AVPacket *pkt)
 {
     AVStreamInternal *sti = st->internal;
     AVPacket *pkt_ref = si->parse_pkt;
@@ -3508,7 +3509,7 @@  static int add_coded_side_data(AVStream *st, AVCodecContext *avctx)
 
 int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
 {
-    AVFormatInternal *const si = ic->internal;
+    FFFormatContext *const si = ffformatcontext(ic);
     int count = 0, ret = 0;
     int64_t read_size;
     AVPacket *pkt1 = si->pkt;
@@ -4259,11 +4260,11 @@  void ff_free_stream(AVFormatContext *s, AVStream *st)
 
 void avformat_free_context(AVFormatContext *s)
 {
-    AVFormatInternal *si;
+    FFFormatContext *si;
 
     if (!s)
         return;
-    si = s->internal;
+    si = ffformatcontext(s);
 
     if (s->oformat && s->oformat->deinit && si->initialized)
         s->oformat->deinit(s);
@@ -4298,7 +4299,6 @@  void avformat_free_context(AVFormatContext *s)
     av_packet_free(&si->parse_pkt);
     av_freep(&s->streams);
     flush_packet_queue(s);
-    av_freep(&s->internal);
     av_freep(&s->url);
     av_free(s);
 }
@@ -4399,7 +4399,7 @@  AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
 
     st->sample_aspect_ratio = (AVRational) { 0, 1 };
 
-    st->internal->inject_global_side_data = s->internal->inject_global_side_data;
+    st->internal->inject_global_side_data = ffformatcontext(s)->inject_global_side_data;
 
     st->internal->need_context_update = 1;
 
@@ -4444,7 +4444,7 @@  AVProgram *av_new_program(AVFormatContext *ac, int id)
 AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base,
                               int64_t start, int64_t end, const char *title)
 {
-    AVFormatInternal *const si = s->internal;
+    FFFormatContext *const si = ffformatcontext(s);
     AVChapter *chapter = NULL;
     int ret;
 
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index 08dba858b4..1810fca8b9 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -280,7 +280,7 @@  static int vqf_read_seek(AVFormatContext *s,
     st->internal->cur_dts = av_rescale(pos, st->time_base.den,
                              st->codecpar->bit_rate * (int64_t)st->time_base.num);
 
-    if ((ret = avio_seek(s->pb, ((pos-7) >> 3) + s->internal->data_offset, SEEK_SET)) < 0)
+    if ((ret = avio_seek(s->pb, ((pos-7) >> 3) + ffformatcontext(s)->data_offset, SEEK_SET)) < 0)
         return ret;
 
     c->remaining_bits = -7 - ((pos-7)&7);
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 30c9ac37f8..815d189671 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -549,7 +549,7 @@  static int wav_read_header(AVFormatContext *s)
         case MKTAG('I', 'D', '3', ' '):
         case MKTAG('i', 'd', '3', ' '): {
             ID3v2ExtraMeta *id3v2_extra_meta;
-            ff_id3v2_read_dict(pb, &s->internal->id3v2_meta, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
+            ff_id3v2_read_dict(pb, &ffformatcontext(s)->id3v2_meta, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
             if (id3v2_extra_meta) {
                 ff_id3v2_parse_apic(s, id3v2_extra_meta);
                 ff_id3v2_parse_chapters(s, id3v2_extra_meta);
diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c
index f4d0db83a4..24390e8e74 100644
--- a/libavformat/webm_chunk.c
+++ b/libavformat/webm_chunk.c
@@ -125,8 +125,8 @@  fail:
     // This ensures that the timestamps will already be properly shifted
     // when the packets arrive here, so we don't need to shift again.
     s->avoid_negative_ts  = oc->avoid_negative_ts;
-    s->internal->avoid_negative_ts_use_pts =
-        oc->internal->avoid_negative_ts_use_pts;
+    ffformatcontext(s)->avoid_negative_ts_use_pts =
+        ffformatcontext(oc)->avoid_negative_ts_use_pts;
     oc->avoid_negative_ts = 0;
 
     return 0;
diff --git a/libavformat/yop.c b/libavformat/yop.c
index 8ecdc654a9..f65e4f8b16 100644
--- a/libavformat/yop.c
+++ b/libavformat/yop.c
@@ -187,7 +187,7 @@  static int yop_read_seek(AVFormatContext *s, int stream_index,
     if (!stream_index)
         return -1;
 
-    pos_min        = s->internal->data_offset;
+    pos_min        = ffformatcontext(s)->data_offset;
     pos_max        = avio_size(s->pb) - yop->frame_size;
     frame_count    = (pos_max - pos_min) / yop->frame_size;
 
diff --git a/libavformat/yuv4mpegdec.c b/libavformat/yuv4mpegdec.c
index 69dd8a3165..b24275acc1 100644
--- a/libavformat/yuv4mpegdec.c
+++ b/libavformat/yuv4mpegdec.c
@@ -255,7 +255,7 @@  static int yuv4_read_header(AVFormatContext *s)
     s->packet_size = av_image_get_buffer_size(st->codecpar->format, width, height, 1) + Y4M_FRAME_MAGIC_LEN;
     if ((int) s->packet_size < 0)
         return s->packet_size;
-    s->internal->data_offset = data_offset = avio_tell(pb);
+    ffformatcontext(s)->data_offset = data_offset = avio_tell(pb);
 
     st->duration = (avio_size(pb) - data_offset) / s->packet_size;
 
@@ -293,7 +293,7 @@  static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
         return s->pb->eof_reached ? AVERROR_EOF : AVERROR(EIO);
     }
     pkt->stream_index = 0;
-    pkt->pts = (off - s->internal->data_offset) / s->packet_size;
+    pkt->pts = (off - ffformatcontext(s)->data_offset) / s->packet_size;
     pkt->duration = 1;
     return 0;
 }
@@ -309,7 +309,7 @@  static int yuv4_read_seek(AVFormatContext *s, int stream_index,
         return -1;
     pos = pts * s->packet_size;
 
-    if (avio_seek(s->pb, pos + s->internal->data_offset, SEEK_SET) < 0)
+    if (avio_seek(s->pb, pos + ffformatcontext(s)->data_offset, SEEK_SET) < 0)
         return -1;
     return 0;
 }