summaryrefslogtreecommitdiff
path: root/libavutil/frame.c
diff options
context:
space:
mode:
authorwm4 <nfxjfg@googlemail.com>2018-03-01 15:57:01 +0100
committerwm4 <nfxjfg@googlemail.com>2018-03-18 12:36:24 +0100
commit4b86ac27a017ccd1d166f0bdd38c08720c561f7d (patch)
tree3ea45580ee0063a44dc2c2e76413dd6bda564c95 /libavutil/frame.c
parent36855abc0eb96d5caa992304f3417a0f8a62960c (diff)
lavu/frame: add QP side data
This adds a way for an API user to transfer QP data and metadata without having to keep the reference to AVFrame, and without having to explicitly care about QP APIs. It might also provide a way to finally remove the deprecated QP related fields. In the end, the QP table should be handled in a very similar way to e.g. AV_FRAME_DATA_MOTION_VECTORS. There are two side data types, because I didn't care about having to repack the QP data so the table and the metadata are in a single AVBufferRef. Otherwise it would have either required a copy on decoding (extra slowdown for something as obscure as the QP data), or would have required making intrusive changes to the codecs which support export of this data. The new side data types are added under deprecation guards, because I don't intend to change the status of the QP export as being deprecated (as it was before this patch too).
Diffstat (limited to 'libavutil/frame.c')
-rw-r--r--libavutil/frame.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 0db2a2d57b..ea13cd3ed6 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -46,8 +46,17 @@ 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 {
+ int stride;
+ int type;
+};
+
int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type)
{
+ struct qp_properties *p;
+ AVFrameSideData *sd;
+ AVBufferRef *ref;
+
FF_DISABLE_DEPRECATION_WARNINGS
av_buffer_unref(&f->qp_table_buf);
@@ -57,20 +66,56 @@ FF_DISABLE_DEPRECATION_WARNINGS
f->qscale_type = qp_type;
FF_ENABLE_DEPRECATION_WARNINGS
+ av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES);
+ av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE_DATA);
+
+ ref = av_buffer_ref(buf);
+ if (!av_frame_new_side_data_from_buf(f, AV_FRAME_DATA_QP_TABLE_DATA, ref)) {
+ av_buffer_unref(&ref);
+ return AVERROR(ENOMEM);
+ }
+
+ sd = av_frame_new_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES,
+ sizeof(struct qp_properties));
+ if (!sd)
+ return AVERROR(ENOMEM);
+
+ p = (struct qp_properties *)sd->data;
+ p->stride = stride;
+ p->type = qp_type;
+
return 0;
}
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_PROPERTIES);
+ if (!sd)
+ return NULL;
+ p = (struct qp_properties *)sd->data;
+ sd = av_frame_get_side_data(f, AV_FRAME_DATA_QP_TABLE_DATA);
+ if (!sd)
+ return NULL;
+ *stride = p->stride;
+ *type = p->type;
+ buf = sd->buf;
+ }
+
+ return buf ? buf->data : NULL;
}
#endif
@@ -787,6 +832,8 @@ 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_PROPERTIES: return "QP table properties";
+ case AV_FRAME_DATA_QP_TABLE_DATA: return "QP table data";
}
return NULL;
}