diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 0da2fa4fb70053039ec4aa6477a1fb91f6528157..f5455448a801196c1283a916413b7b1677e482de 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -129,6 +129,8 @@ struct AVCodecDefault {
     const uint8_t *value;
 };
 
+extern const uint8_t ff_log2_run[41];
+
 /**
  * Return the hardware accelerated codec for codec codec_id and
  * pixel format pix_fmt.
@@ -251,6 +253,9 @@ int ff_set_dimensions(AVCodecContext *s, int width, int height);
 int ff_side_data_update_matrix_encoding(AVFrame *frame,
                                         enum AVMatrixEncoding matrix_encoding);
 
-extern const uint8_t ff_log2_run[41];
+/**
+ * Set various frame properties from the codec context / packet data.
+ */
+int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame);
 
 #endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index 007674ec38bdef9874d208a4205913661d3e835f..85a69e91a5ac14306a3a9e1274adfeed5f76090a 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -209,8 +209,11 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
 
     frame->pict_type        = AV_PICTURE_TYPE_I;
     frame->key_frame        = 1;
-    frame->reordered_opaque = avctx->reordered_opaque;
-    frame->pkt_pts          = avctx->internal->pkt->pts;
+
+    res = ff_decode_frame_props(avctx, frame);
+    if (res < 0)
+        return res;
+
     av_frame_set_pkt_pos     (frame, avctx->internal->pkt->pos);
     av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration);
 
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 7ffe6c652445f705ac68dabd944661a54d88afb6..e7cca9646eaacb952437c2b03c4b13278712e8de 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -827,6 +827,35 @@ static void compat_release_buffer(void *opaque, uint8_t *data)
 FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
+int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
+{
+    AVPacket *pkt = avctx->internal->pkt;
+    uint8_t *packet_sd;
+    int size;
+    AVFrameSideData *frame_sd;
+
+
+    frame->reordered_opaque = avctx->reordered_opaque;
+    if (!pkt) {
+        frame->pkt_pts = AV_NOPTS_VALUE;
+        return 0;
+    }
+
+    frame->pkt_pts = pkt->pts;
+
+    /* copy the replaygain data to the output frame */
+    packet_sd = av_packet_get_side_data(pkt, AV_PKT_DATA_REPLAYGAIN, &size);
+    if (packet_sd) {
+        frame_sd = av_frame_new_side_data(frame, AV_FRAME_DATA_REPLAYGAIN, size);
+        if (!frame_sd)
+            return AVERROR(ENOMEM);
+
+        memcpy(frame_sd->data, packet_sd, size);
+    }
+
+    return 0;
+}
+
 static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
 {
     int override_dimensions = 1;
@@ -845,6 +874,9 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
             override_dimensions = 0;
         }
     }
+    ret = ff_decode_frame_props(avctx, frame);
+    if (ret < 0)
+        return ret;
     if ((ret = ff_init_buffer_info(avctx, frame)) < 0)
         return ret;
 
@@ -1001,11 +1033,8 @@ static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame)
     if (!frame->data[0])
         return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
 
-    if (av_frame_is_writable(frame)) {
-        frame->pkt_pts = avctx->internal->pkt ? avctx->internal->pkt->pts : AV_NOPTS_VALUE;
-        frame->reordered_opaque = avctx->reordered_opaque;
-        return 0;
-    }
+    if (av_frame_is_writable(frame))
+        return ff_decode_frame_props(avctx, frame);
 
     tmp = av_frame_alloc();
     if (!tmp)