diff --git a/ffmpeg.c b/ffmpeg.c
index a19c81667b5ff4e34200ecb07641908255aa3936..d4c6ec8420f8f9906ffe6356dd4260974a59e39a 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -3507,7 +3507,6 @@ static void *input_thread(void *arg)
             av_thread_message_queue_set_err_recv(f->in_thread_queue, ret);
             break;
         }
-        av_dup_packet(&pkt);
         ret = av_thread_message_queue_send(f->in_thread_queue, &pkt, flags);
         if (flags && ret == AVERROR(EAGAIN)) {
             flags = 0;
diff --git a/ffplay.c b/ffplay.c
index 37db374b6706aeac8c603240bf0791b3779634ed..e0bcc7c392a758763e63c81abfacd31b0414ab81 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -427,10 +427,6 @@ static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
 {
     int ret;
 
-    /* duplicate the packet */
-    if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
-        return -1;
-
     SDL_LockMutex(q->mutex);
     ret = packet_queue_put_private(q, pkt);
     SDL_UnlockMutex(q->mutex);
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 689473e9fb5a0df589b62d757daabc7a46b43dc0..3b6530f4ca0df20fa002057660668d5d4e085498 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -683,6 +683,14 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
             continue;
         }
 
+        if (!pkt->buf) {
+            AVPacket tmp = { 0 };
+            ret = av_packet_ref(&tmp, pkt);
+            if (ret < 0)
+                return ret;
+            *pkt = tmp;
+        }
+
         if ((s->flags & AVFMT_FLAG_DISCARD_CORRUPT) &&
             (pkt->flags & AV_PKT_FLAG_CORRUPT)) {
             av_log(s, AV_LOG_WARNING,