--- 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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".