diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 372c04295d..254677a331 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -365,7 +365,7 @@ static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *trac
 }
 
 struct eac3_info {
-    AVPacket pkt;
+    AVPacket *pkt;
     uint8_t ec3_done;
     uint8_t num_blocks;
 
@@ -407,6 +407,9 @@ static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
         return AVERROR(ENOMEM);
     info = track->eac3_priv;
 
+    if (!info->pkt && !(info->pkt = av_packet_alloc()))
+        return AVERROR(ENOMEM);
+
     if (avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) < 0) {
         /* drop the packets until we see a good one */
         if (!track->entry) {
@@ -511,20 +514,20 @@ concatenate:
     }
 
     if (!info->num_blocks) {
-        ret = av_packet_ref(&info->pkt, pkt);
+        ret = av_packet_ref(info->pkt, pkt);
         if (!ret)
             info->num_blocks = num_blocks;
         goto end;
     } else {
-        if ((ret = av_grow_packet(&info->pkt, pkt->size)) < 0)
+        if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
             goto end;
-        memcpy(info->pkt.data + info->pkt.size - pkt->size, pkt->data, pkt->size);
+        memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
         info->num_blocks += num_blocks;
-        info->pkt.duration += pkt->duration;
+        info->pkt->duration += pkt->duration;
         if (info->num_blocks != 6)
             goto end;
         av_packet_unref(pkt);
-        av_packet_move_ref(pkt, &info->pkt);
+        av_packet_move_ref(pkt, info->pkt);
         info->num_blocks = 0;
     }
     ret = pkt->size;
@@ -5303,16 +5306,17 @@ static int mov_flush_fragment(AVFormatContext *s, int force)
     for (i = 0; i < s->nb_streams; i++) {
         MOVTrack *track = &mov->tracks[i];
         if (!track->end_reliable) {
-            AVPacket pkt;
-            if (!ff_interleaved_peek(s, i, &pkt, 1)) {
+            AVPacket *pkt = mov->pkt;
+            if (!ff_interleaved_peek(s, i, pkt, 1)) {
                 if (track->dts_shift != AV_NOPTS_VALUE)
-                    pkt.dts += track->dts_shift;
-                track->track_duration = pkt.dts - track->start_dts;
-                if (pkt.pts != AV_NOPTS_VALUE)
-                    track->end_pts = pkt.pts;
+                    pkt->dts += track->dts_shift;
+                track->track_duration = pkt->dts - track->start_dts;
+                if (pkt->pts != AV_NOPTS_VALUE)
+                    track->end_pts = pkt->pts;
                 else
-                    track->end_pts = pkt.dts;
+                    track->end_pts = pkt->dts;
             }
+            av_packet_unref(pkt);
         }
     }
 
@@ -5965,20 +5969,20 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
 static int mov_write_subtitle_end_packet(AVFormatContext *s,
                                          int stream_index,
                                          int64_t dts) {
-    AVPacket end;
+    MOVMuxContext *mov = s->priv_data;
+    AVPacket *end = mov->pkt;
     uint8_t data[2] = {0};
     int ret;
 
-    av_init_packet(&end);
-    end.size = sizeof(data);
-    end.data = data;
-    end.pts = dts;
-    end.dts = dts;
-    end.duration = 0;
-    end.stream_index = stream_index;
+    end->size = sizeof(data);
+    end->data = data;
+    end->pts = dts;
+    end->dts = dts;
+    end->duration = 0;
+    end->stream_index = stream_index;
 
-    ret = mov_write_single_packet(s, &end);
-    av_packet_unref(&end);
+    ret = mov_write_single_packet(s, end);
+    av_packet_unref(end);
 
     return ret;
 }
@@ -6091,7 +6095,7 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
 
     MOVMuxContext *mov = s->priv_data;
     MOVTrack *track = &mov->tracks[tracknum];
-    AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
+    AVPacket *pkt = mov->pkt;
     int i, len;
 
     track->mode = mov->mode;
@@ -6153,13 +6157,16 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
     }
 #endif
 
+    pkt->stream_index = tracknum;
+    pkt->flags = AV_PKT_FLAG_KEY;
+
     for (i = 0; i < s->nb_chapters; i++) {
         AVChapter *c = s->chapters[i];
         AVDictionaryEntry *t;
 
         int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE});
-        pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE});
-        pkt.duration = end - pkt.dts;
+        pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE});
+        pkt->duration = end - pkt->dts;
 
         if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
             static const char encd[12] = {
@@ -6167,18 +6174,22 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
                 'e',  'n',  'c',  'd',
                 0x00, 0x00, 0x01, 0x00 };
             len      = strlen(t->value);
-            pkt.size = len + 2 + 12;
-            pkt.data = av_malloc(pkt.size);
-            if (!pkt.data)
+            pkt->size = len + 2 + 12;
+            pkt->data = av_malloc(pkt->size);
+            if (!pkt->data) {
+                av_packet_unref(pkt);
                 return AVERROR(ENOMEM);
-            AV_WB16(pkt.data, len);
-            memcpy(pkt.data + 2, t->value, len);
-            memcpy(pkt.data + len + 2, encd, sizeof(encd));
-            ff_mov_write_packet(s, &pkt);
-            av_freep(&pkt.data);
+            }
+            AV_WB16(pkt->data, len);
+            memcpy(pkt->data + 2, t->value, len);
+            memcpy(pkt->data + len + 2, encd, sizeof(encd));
+            ff_mov_write_packet(s, pkt);
+            av_freep(&pkt->data);
         }
     }
 
+    av_packet_unref(mov->pkt);
+
     return 0;
 }
 
@@ -6198,9 +6209,9 @@ static int mov_create_timecode_track(AVFormatContext *s, int index, int src_inde
     MOVTrack *track     = &mov->tracks[index];
     AVStream *src_st    = s->streams[src_index];
     uint8_t data[4];
-    AVPacket pkt    = { .data = data, .stream_index = index,
-                        .flags = AV_PKT_FLAG_KEY, .size = 4 };
+    AVPacket *pkt = mov->pkt;
     AVRational rate = find_fps(s, src_st);
+    int ret;
 
     /* tmcd track based on video stream */
     track->mode      = mov->mode;
@@ -6222,8 +6233,14 @@ static int mov_create_timecode_track(AVFormatContext *s, int index, int src_inde
     track->st->avg_frame_rate = av_inv_q(rate);
 
     /* the tmcd track just contains one packet with the frame number */
-    AV_WB32(pkt.data, tc.start);
-    return ff_mov_write_packet(s, &pkt);
+    pkt->data = data;
+    pkt->stream_index = index;
+    pkt->flags = AV_PKT_FLAG_KEY;
+    pkt->size = 4;
+    AV_WB32(pkt->data, tc.start);
+    ret = ff_mov_write_packet(s, pkt);
+    av_packet_unref(pkt);
+    return ret;
 }
 
 /*
@@ -6284,6 +6301,8 @@ static void mov_free(AVFormatContext *s)
     MOVMuxContext *mov = s->priv_data;
     int i;
 
+    av_packet_free(&mov->pkt);
+
     if (!mov->tracks)
         return;
 
@@ -6302,7 +6321,7 @@ static void mov_free(AVFormatContext *s)
 
         if (mov->tracks[i].eac3_priv) {
             struct eac3_info *info = mov->tracks[i].eac3_priv;
-            av_packet_unref(&info->pkt);
+            av_packet_free(&info->pkt);
             av_freep(&mov->tracks[i].eac3_priv);
         }
         if (mov->tracks[i].vos_len)
@@ -6531,6 +6550,10 @@ static int mov_init(AVFormatContext *s)
         mov->nb_streams += mov->nb_meta_tmcd;
     }
 
+    mov->pkt = av_packet_alloc();
+    if (!mov->pkt)
+        return AVERROR(ENOMEM);
+
     // Reserve an extra stream for chapters for the case where chapters
     // are written in the trailer
     mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks));
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 997b2d61c0..f27edb667b 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -215,6 +215,8 @@ typedef struct MOVMuxContext {
     int per_stream_grouping;
     AVFormatContext *fc;
 
+    AVPacket *pkt;
+
     int use_editlist;
     float gamma;
 
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index 964026ec71..47276091f3 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -408,7 +408,7 @@ int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
     uint8_t *buf = NULL;
     int size;
     AVIOContext *hintbuf = NULL;
-    AVPacket hint_pkt;
+    AVPacket *hint_pkt = mov->pkt;
     int ret = 0, count;
 
     if (!rtp_ctx)
@@ -437,21 +437,22 @@ int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
     /* Open a buffer for writing the hint */
     if ((ret = avio_open_dyn_buf(&hintbuf)) < 0)
         goto done;
-    av_init_packet(&hint_pkt);
-    count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt.dts);
+    av_packet_unref(hint_pkt);
+    count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt->dts);
     av_freep(&buf);
 
     /* Write the hint data into the hint track */
-    hint_pkt.size = size = avio_close_dyn_buf(hintbuf, &buf);
-    hint_pkt.data = buf;
-    hint_pkt.pts  = hint_pkt.dts;
-    hint_pkt.stream_index = track_index;
+    hint_pkt->size = size = avio_close_dyn_buf(hintbuf, &buf);
+    hint_pkt->data = buf;
+    hint_pkt->pts  = hint_pkt->dts;
+    hint_pkt->stream_index = track_index;
     if (pkt->flags & AV_PKT_FLAG_KEY)
-        hint_pkt.flags |= AV_PKT_FLAG_KEY;
+        hint_pkt->flags |= AV_PKT_FLAG_KEY;
     if (count > 0)
-        ff_mov_write_packet(s, &hint_pkt);
+        ff_mov_write_packet(s, hint_pkt);
 done:
     av_free(buf);
+    av_packet_unref(hint_pkt);
     sample_queue_retain(&trk->sample_queue);
     return ret;
 }
diff --git a/libavformat/mux.c b/libavformat/mux.c
index ce9724e834..3600e74a50 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -1052,7 +1052,9 @@ int ff_interleaved_peek(AVFormatContext *s, int stream,
     AVPacketList *pktl = s->internal->packet_buffer;
     while (pktl) {
         if (pktl->pkt.stream_index == stream) {
-            *pkt = pktl->pkt;
+            int ret = av_packet_ref(pkt, &pktl->pkt);
+            if (ret < 0)
+                return ret;
             if (add_offset) {
                 AVStream *st = s->streams[pkt->stream_index];
                 int64_t offset = st->internal->mux_ts_offset;
