diff --git a/libavutil/frame.c b/libavutil/frame.c
index 0db2a2d57b..b349ff84fe 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -46,8 +46,28 @@ MAKE_ACCESSORS(AVFrame, frame, enum AVColorRange, color_range)
                av_get_channel_layout_nb_channels((frame)->channel_layout))
 
 #if FF_API_FRAME_QP
+struct qp_properties {
+    AVBufferRef *buf;
+    int stride;
+    int type;
+};
+
+// Free the qp_properties struct and the QP data buffer
+// To be used as the free() function for the side data buffer.
+static void frame_qp_free(void *opaque, uint8_t *data)
+{
+    struct qp_properties *p = (struct qp_properties *)data;
+
+    av_buffer_unref(&p->buf);
+    av_free(data);
+}
+
 int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type)
 {
+    struct qp_properties *p = NULL;
+    AVFrameSideData *sd;
+    AVBufferRef *sd_buf = NULL, *ref = NULL;
+
 FF_DISABLE_DEPRECATION_WARNINGS
     av_buffer_unref(&f->qp_table_buf);
 
@@ -57,20 +77,69 @@ FF_DISABLE_DEPRECATION_WARNINGS
     f->qscale_type  = qp_type;
 FF_ENABLE_DEPRECATION_WARNINGS
 
+    av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE);
+
+    // Create a new QP data table ref for the side data
+    ref = av_buffer_ref(buf);
+    if (!ref)
+        return AVERROR(ENOMEM);
+
+    // Alloc the qp_properties struct
+    p = av_malloc(sizeof(struct qp_properties));
+    if (!p)
+        goto fail;
+
+    // Create a buffer to be used in side data, containing the qp_properties struct.
+    // Use a custom free() function to properly unref the QP table buffer when the side data
+    // is removed.
+    sd_buf = av_buffer_create((uint8_t *)p, sizeof(struct qp_properties), frame_qp_free, NULL, 0);
+    if (!sd_buf)
+        goto fail;
+
+    // Add the buffer containing the qp_properties struct as side data
+    sd = av_frame_new_side_data_from_buf(f, AV_FRAME_DATA_QP_TABLE, sd_buf);
+    if (!sd)
+        goto fail;
+
+    // Fill the prop fields and the QP table buffer.
+    p->stride = stride;
+    p->type = qp_type;
+    p->buf = ref;
+
     return 0;
+fail:
+    av_buffer_unref(&ref);
+    av_buffer_unref(&sd_buf);
+    av_free(p);
+    return AVERROR(ENOMEM);
 }
 
 int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type)
 {
-FF_DISABLE_DEPRECATION_WARNINGS
-    *stride = f->qstride;
-    *type   = f->qscale_type;
+    AVBufferRef *buf = NULL;
 
-    if (!f->qp_table_buf)
-        return NULL;
+    *stride = 0;
+    *type   = 0;
 
-    return f->qp_table_buf->data;
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (f->qp_table_buf) {
+        *stride = f->qstride;
+        *type   = f->qscale_type;
+        buf     = f->qp_table_buf;
 FF_ENABLE_DEPRECATION_WARNINGS
+    } else {
+        AVFrameSideData *sd;
+        struct qp_properties *p;
+        sd = av_frame_get_side_data(f, AV_FRAME_DATA_QP_TABLE);
+        if (!sd)
+            return NULL;
+        p = (struct qp_properties *)sd->data;
+        *stride = p->stride;
+        *type   = p->type;
+        buf     = p->buf;
+    }
+
+    return buf ? buf->data : NULL;
 }
 #endif
 
@@ -787,6 +856,7 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type)
     case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL:         return "Content light level metadata";
     case AV_FRAME_DATA_GOP_TIMECODE:                return "GOP timecode";
     case AV_FRAME_DATA_ICC_PROFILE:                 return "ICC profile";
+    case AV_FRAME_DATA_QP_TABLE:                    return "QP table";
     }
     return NULL;
 }
diff --git a/libavutil/frame.h b/libavutil/frame.h
index ddbac3156d..dd1917882b 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -141,6 +141,16 @@ enum AVFrameSideDataType {
      * metadata key entry "name".
      */
     AV_FRAME_DATA_ICC_PROFILE,
+
+#if FF_API_FRAME_QP
+    /**
+     * QP table data.
+     * The contents of this side data are undocumented and internal; use
+     * av_frame_set_qp_table() and av_frame_get_qp_table() to access this in a
+     * meaningful way instead.
+     */
+    AV_FRAME_DATA_QP_TABLE,
+#endif
 };
 
 enum AVActiveFormatDescription {
