diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 00085c3b4dcc8d1605c58eaf9798edfc3f90ca60..b02278d3a68bc3959e9d1810c4fae8872dbf723b 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -99,6 +99,14 @@ fail2:
     return 0;
 }
 
+static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt)
+{
+    av_packet_unref(avci->last_pkt_props);
+    if (pkt)
+        return av_packet_copy_props(avci->last_pkt_props, pkt);
+    return 0;
+}
+
 static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
 {
     int ret;
@@ -304,7 +312,10 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
         return AVERROR(ENOSYS);
     }
 
-    avctx->internal->pkt = avpkt;
+    ret = extract_packet_props(avci, avpkt);
+    if (ret < 0)
+        return ret;
+
     ret = apply_param_change(avctx, avpkt);
     if (ret < 0)
         return ret;
@@ -368,7 +379,9 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
         return AVERROR(ENOSYS);
     }
 
-    avctx->internal->pkt = avpkt;
+    ret = extract_packet_props(avci, avpkt);
+    if (ret < 0)
+        return ret;
 
     if (!avpkt->data && avpkt->size) {
         av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
@@ -408,7 +421,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
 {
     int ret;
 
-    avctx->internal->pkt = avpkt;
+    ret = extract_packet_props(avctx->internal, avpkt);
+    if (ret < 0)
+        return ret;
+
     *got_sub_ptr = 0;
     ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt);
     if (*got_sub_ptr)
@@ -739,7 +755,7 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags
 
 int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
 {
-    AVPacket *pkt = avctx->internal->pkt;
+    AVPacket *pkt = avctx->internal->last_pkt_props;
     int i;
     struct {
         enum AVPacketSideDataType packet;
@@ -759,15 +775,6 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
     frame->chroma_location = avctx->chroma_sample_location;
 
     frame->reordered_opaque = avctx->reordered_opaque;
-    if (!pkt) {
-#if FF_API_PKT_PTS
-FF_DISABLE_DEPRECATION_WARNINGS
-        frame->pkt_pts = AV_NOPTS_VALUE;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-        frame->pts     = AV_NOPTS_VALUE;
-        return 0;
-    }
 
 #if FF_API_PKT_PTS
 FF_DISABLE_DEPRECATION_WARNINGS
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 4bde09ab8adc2351a38667bdda2a7217b726bc13..2ca7a45e811b8a5eefc01cddfda54c40c57d95fb 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -131,10 +131,10 @@ typedef struct AVCodecInternal {
     void *thread_ctx;
 
     /**
-     * Current packet as passed into the decoder, to avoid having to pass the
-     * packet into every function.
+     * Properties (timestamps+side data) extracted from the last packet passed
+     * for decoding.
      */
-    AVPacket *pkt;
+    AVPacket *last_pkt_props;
 
     /**
      * hwaccel-specific private data
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 2736a81efea77617f28952d8080c31f4a7cce86f..75f4ff46247fdb87e83c001d58500f6e68921434 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -656,7 +656,7 @@ int ff_frame_thread_init(AVCodecContext *avctx)
         }
         *copy->internal = *src->internal;
         copy->internal->thread_ctx = p;
-        copy->internal->pkt = &p->avpkt;
+        copy->internal->last_pkt_props = &p->avpkt;
 
         if (!i) {
             src = copy;
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 5350eb819a9203cbbd6f8adc2043cb78ddd5fd81..b569b48f7a8435f2139c9c0dc03576058b4ba475 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -433,6 +433,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
         goto free_and_end;
     }
 
+    avctx->internal->last_pkt_props = av_packet_alloc();
+    if (!avctx->internal->last_pkt_props) {
+        ret = AVERROR(ENOMEM);
+        goto free_and_end;
+    }
+
     if (codec->priv_data_size > 0) {
         if (!avctx->priv_data) {
             avctx->priv_data = av_mallocz(codec->priv_data_size);
@@ -713,6 +719,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
         av_frame_free(&avctx->internal->to_free);
         av_frame_free(&avctx->internal->buffer_frame);
         av_packet_free(&avctx->internal->buffer_pkt);
+        av_packet_free(&avctx->internal->last_pkt_props);
         av_freep(&avctx->internal->pool);
     }
     av_freep(&avctx->internal);
@@ -753,6 +760,7 @@ av_cold int avcodec_close(AVCodecContext *avctx)
         av_frame_free(&avctx->internal->to_free);
         av_frame_free(&avctx->internal->buffer_frame);
         av_packet_free(&avctx->internal->buffer_pkt);
+        av_packet_free(&avctx->internal->last_pkt_props);
         for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)
             av_buffer_pool_uninit(&pool->pools[i]);
         av_freep(&avctx->internal->pool);