[FFmpeg-devel] [PATCH v2 03/18] cbs: Add interface for manipulating metadata in fragments
Mark Thompson
sw at jkqxz.net
Sun Feb 21 21:51:10 EET 2021
---
libavcodec/Makefile | 2 +-
libavcodec/cbs_internal.h | 17 ++++++
libavcodec/cbs_metadata.c | 110 ++++++++++++++++++++++++++++++++++++++
libavcodec/cbs_metadata.h | 94 ++++++++++++++++++++++++++++++++
4 files changed, 222 insertions(+), 1 deletion(-)
create mode 100644 libavcodec/cbs_metadata.c
create mode 100644 libavcodec/cbs_metadata.h
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 6ec1d360ac..43a54caba8 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -69,7 +69,7 @@ OBJS-$(CONFIG_AUDIODSP) += audiodsp.o
OBJS-$(CONFIG_BLOCKDSP) += blockdsp.o
OBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o
OBJS-$(CONFIG_CABAC) += cabac.o
-OBJS-$(CONFIG_CBS) += cbs.o cbs_bsf.o
+OBJS-$(CONFIG_CBS) += cbs.o cbs_bsf.o cbs_metadata.o
OBJS-$(CONFIG_CBS_AV1) += cbs_av1.o
OBJS-$(CONFIG_CBS_H264) += cbs_h2645.o cbs_sei.o h2645_parse.o
OBJS-$(CONFIG_CBS_H265) += cbs_h2645.o cbs_sei.o h2645_parse.o
diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h
index a392880036..6aa2c62bc2 100644
--- a/libavcodec/cbs_internal.h
+++ b/libavcodec/cbs_internal.h
@@ -83,6 +83,8 @@ typedef const struct CodedBitstreamUnitTypeDescriptor {
int (*content_clone)(AVBufferRef **ref, CodedBitstreamUnit *unit);
} CodedBitstreamUnitTypeDescriptor;
+enum CBSMetadataType;
+
typedef struct CodedBitstreamType {
enum AVCodecID codec_id;
@@ -128,6 +130,21 @@ typedef struct CodedBitstreamType {
// Free the codec internal state.
void (*close)(CodedBitstreamContext *ctx);
+
+ // Insert metadata to fragment.
+ int (*insert_metadata)(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type, const void *data);
+
+ // Remove metadata from fragment.
+ int (*remove_metadata)(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type);
+
+ // Extract metadata from fragment.
+ int (*extract_metadata)(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type, void *data);
} CodedBitstreamType;
diff --git a/libavcodec/cbs_metadata.c b/libavcodec/cbs_metadata.c
new file mode 100644
index 0000000000..4dc0243998
--- /dev/null
+++ b/libavcodec/cbs_metadata.c
@@ -0,0 +1,110 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/film_grain_params.h"
+#include "libavutil/mastering_display_metadata.h"
+#include "libavutil/stereo3d.h"
+
+#include "cbs.h"
+#include "cbs_internal.h"
+#include "cbs_metadata.h"
+
+static const CBSMetadataTypeDescriptor cbs_metadata_types[] = {
+ {
+ CBS_METADATA_MASTERING_DISPLAY,
+ "Mastering Display",
+ 1, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA,
+ 1, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
+ },
+ {
+ CBS_METADATA_CONTENT_LIGHT_LEVEL,
+ "Content Light Level",
+ 1, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
+ 1, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
+ },
+ {
+ CBS_METADATA_DISPLAY_MATRIX,
+ "Display Matrix",
+ 1, AV_FRAME_DATA_DISPLAYMATRIX,
+ 1, AV_PKT_DATA_DISPLAYMATRIX,
+ },
+ {
+ CBS_METADATA_STEREO3D,
+ "Stereo 3D",
+ 1, AV_FRAME_DATA_STEREO3D,
+ 1, AV_PKT_DATA_STEREO3D,
+ },
+};
+
+const CBSMetadataTypeDescriptor *ff_cbs_metadata_find_type(enum CBSMetadataType type)
+{
+ for (int i = 0; i < FF_ARRAY_ELEMS(cbs_metadata_types); i++) {
+ if (cbs_metadata_types[i].type == type)
+ return &cbs_metadata_types[i];
+ }
+ return NULL;
+}
+
+void *ff_cbs_alloc_metadata(enum CBSMetadataType type, size_t *size)
+{
+ switch (type) {
+ case CBS_METADATA_MASTERING_DISPLAY:
+ if (size)
+ *size = sizeof(AVMasteringDisplayMetadata);
+ return av_mastering_display_metadata_alloc();
+ case CBS_METADATA_CONTENT_LIGHT_LEVEL:
+ return av_content_light_metadata_alloc(size);
+ case CBS_METADATA_DISPLAY_MATRIX:
+ if (size)
+ *size = 9 * sizeof(int32_t);
+ return av_mallocz(9 * sizeof(int32_t));
+ case CBS_METADATA_STEREO3D:
+ if (size)
+ *size = sizeof(AVStereo3D);
+ return av_stereo3d_alloc();
+ default:
+ return NULL;
+ }
+}
+
+int ff_cbs_insert_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type, const void *data)
+{
+ if (!ctx->codec->insert_metadata)
+ return AVERROR(ENOSYS);
+ return ctx->codec->insert_metadata(ctx, frag, type, data);
+}
+
+int ff_cbs_remove_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type)
+{
+ if (!ctx->codec->remove_metadata)
+ return AVERROR(ENOSYS);
+ return ctx->codec->remove_metadata(ctx, frag, type);
+}
+
+int ff_cbs_extract_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type, void *data)
+{
+ if (!ctx->codec->extract_metadata)
+ return AVERROR(ENOSYS);
+ return ctx->codec->extract_metadata(ctx, frag, type, data);
+}
diff --git a/libavcodec/cbs_metadata.h b/libavcodec/cbs_metadata.h
new file mode 100644
index 0000000000..79ba6f4e26
--- /dev/null
+++ b/libavcodec/cbs_metadata.h
@@ -0,0 +1,94 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_CBS_METADATA_H
+#define AVCODEC_CBS_METADATA_H
+
+#include "libavutil/frame.h"
+
+#include "cbs.h"
+#include "packet.h"
+
+
+enum CBSMetadataType {
+ // List sentinel element.
+ CBS_METADATA_NONE,
+ // AVMasteringDisplayMetadata.
+ CBS_METADATA_MASTERING_DISPLAY,
+ // AVContentLightMetadata.
+ CBS_METADATA_CONTENT_LIGHT_LEVEL,
+ // int32_t matrix[9].
+ CBS_METADATA_DISPLAY_MATRIX,
+ // AVStereo3D.
+ CBS_METADATA_STEREO3D,
+};
+
+typedef struct CBSMetadataTypeDescriptor {
+ enum CBSMetadataType type;
+ const char *name;
+
+ // Matching frame and packet side data types, if available.
+ int has_frame_side_data;
+ enum AVFrameSideDataType frame_side_data_type;
+ int has_packet_side_data;
+ enum AVPacketSideDataType packet_side_data_type;
+} CBSMetadataTypeDescriptor;
+
+/**
+ * Retrieve the descriptor for the given metadata type.
+ */
+const CBSMetadataTypeDescriptor *ff_cbs_metadata_find_type(enum CBSMetadataType type);
+
+/**
+ * Allocates an object for the given metadata type.
+ *
+ * If not null, size is written with the size of the object returned.
+ */
+void *ff_cbs_alloc_metadata(enum CBSMetadataType type, size_t *size);
+
+/**
+ * Insert metadata into a fragment.
+ *
+ * type is a CBS_METADATA_* value. data must be a pointer to a filled
+ * structure matching the specified type.
+ */
+int ff_cbs_insert_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type, const void *data);
+
+/**
+ * Remove metadata from a fragment.
+ *
+ * Remove all metadata of the given CBS_METADATA_* type.
+ */
+int ff_cbs_remove_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type);
+
+/**
+ * Extract metadata from a fragment.
+ *
+ * type is a CBS_METADATA_* value. data must be a pointer to an empty
+ * structure matching the specified type, which will be filled on
+ * success.
+ */
+int ff_cbs_extract_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type, void *data);
+
+#endif /* AVCODEC_CBS_METADATA_H */
--
2.30.0
More information about the ffmpeg-devel
mailing list