[FFmpeg-devel] [PATCH v2 08/18] cbs_av1: Implement metadata manipulation
Mark Thompson
sw at jkqxz.net
Sun Feb 21 21:51:15 EET 2021
---
libavcodec/cbs_av1.c | 142 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 142 insertions(+)
diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c
index 302e1f38f5..0c958c81c2 100644
--- a/libavcodec/cbs_av1.c
+++ b/libavcodec/cbs_av1.c
@@ -22,6 +22,7 @@
#include "cbs.h"
#include "cbs_internal.h"
+#include "cbs_metadata.h"
#include "cbs_av1.h"
#include "internal.h"
@@ -1267,6 +1268,143 @@ static void cbs_av1_close(CodedBitstreamContext *ctx)
av_buffer_unref(&priv->frame_header_ref);
}
+static int cbs_av1_find_metadata_unit(CodedBitstreamFragment *tu,
+ uint64_t metadata_type,
+ CodedBitstreamUnit **iter)
+{
+ int i, found;
+
+ found = 0;
+ for (i = 0; i < tu->nb_units; i++) {
+ CodedBitstreamUnit *unit = &tu->units[i];
+ AV1RawOBU *obu = unit->content;
+
+ if (!obu)
+ continue;
+
+ if (obu->header.obu_type == AV1_OBU_METADATA) {
+ if (!*iter || found) {
+ *iter = unit;
+ return 0;
+ }
+ if (unit == *iter)
+ found = 1;
+ }
+ }
+
+ return AVERROR(ENOENT);
+}
+
+static uint64_t cbs_av1_find_metadata_type(enum CBSMetadataType type)
+{
+ struct {
+ enum CBSMetadataType cbs_type;
+ uint64_t av1_type;
+ } map[] = {
+ };
+
+ for (int i = 0; i < FF_ARRAY_ELEMS(map); i++) {
+ if (map[i].cbs_type == type)
+ return map[i].av1_type;
+ }
+ return 0;
+}
+
+static void cbs_av1_delete_metadata_type(CodedBitstreamFragment *tu,
+ uint64_t metadata_type)
+{
+ int err;
+ while (1) {
+ CodedBitstreamUnit *unit = NULL;
+ err = cbs_av1_find_metadata_unit(tu, metadata_type, &unit);
+ if (err < 0)
+ break;
+ ff_cbs_delete_unit(tu, unit - tu->units);
+ }
+}
+
+static int cbs_av1_remove_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *tu,
+ enum CBSMetadataType type)
+{
+ uint64_t metadata_type;
+
+ metadata_type = cbs_av1_find_metadata_type(type);
+ if (metadata_type == 0)
+ return AVERROR(EINVAL);
+
+ cbs_av1_delete_metadata_type(tu, metadata_type);
+ return 0;
+}
+
+static int cbs_av1_insert_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *tu,
+ enum CBSMetadataType type,
+ const void *data)
+{
+ AVBufferRef *md_buf;
+ AV1RawOBU *obu;
+ uint64_t metadata_type;
+ int err;
+
+ metadata_type = cbs_av1_find_metadata_type(type);
+ if (metadata_type == 0)
+ return AVERROR(EINVAL);
+
+ md_buf = av_buffer_allocz(sizeof(AV1RawOBU));
+ if (!md_buf)
+ return AVERROR(ENOMEM);
+
+ obu = (AV1RawOBU*)md_buf->data;
+
+ obu->header = (AV1RawOBUHeader) {
+ .obu_type = AV1_OBU_METADATA,
+ };
+ obu->obu.metadata.metadata_type = metadata_type;
+
+ switch (metadata_type) {
+ default:
+ av_assert0(0);
+ }
+
+ cbs_av1_delete_metadata_type(tu, metadata_type);
+
+ err = ff_cbs_insert_unit_content(tu, -1, AV1_OBU_METADATA,
+ obu, md_buf);
+ av_buffer_unref(&md_buf);
+ return err;
+}
+
+static int cbs_av1_extract_metadata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *tu,
+ enum CBSMetadataType type,
+ void *data)
+{
+ CodedBitstreamUnit *unit;
+ AV1RawOBU *obu;
+ uint64_t metadata_type;
+ int err;
+
+ metadata_type = cbs_av1_find_metadata_type(type);
+ if (metadata_type == 0)
+ return AVERROR(EINVAL);
+
+ unit = NULL;
+ err = cbs_av1_find_metadata_unit(tu, metadata_type, &unit);
+ if (err < 0) {
+ // No metadata with that type found.
+ return err;
+ }
+ obu = unit->content;
+
+ switch (metadata_type) {
+ default:
+ av_assert0(0);
+ }
+
+ return 0;
+}
+
static void cbs_av1_free_metadata(void *unit, uint8_t *content)
{
AV1RawOBU *obu = (AV1RawOBU*)content;
@@ -1333,4 +1471,8 @@ const CodedBitstreamType ff_cbs_type_av1 = {
.flush = &cbs_av1_flush,
.close = &cbs_av1_close,
+
+ .insert_metadata = &cbs_av1_insert_metadata,
+ .remove_metadata = &cbs_av1_remove_metadata,
+ .extract_metadata = &cbs_av1_extract_metadata,
};
--
2.30.0
More information about the ffmpeg-devel
mailing list