--- libavcodec/cbs_h2645.c | 8 ++++ libavcodec/cbs_sei.c | 94 ++++++++++++++++++++++++++++++++++++++++++ libavcodec/cbs_sei.h | 35 ++++++++++++++++ 3 files changed, 137 insertions(+)
diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index a00bc27370..42b614034e 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1478,6 +1478,10 @@ const CodedBitstreamType ff_cbs_type_h264 = { .flush = &cbs_h264_flush, .close = &cbs_h264_close, + + .insert_metadata = &ff_cbs_sei_insert_metadata, + .remove_metadata = &ff_cbs_sei_remove_metadata, + .extract_metadata = &ff_cbs_sei_extract_metadata, }; const CodedBitstreamType ff_cbs_type_h265 = { @@ -1494,6 +1498,10 @@ const CodedBitstreamType ff_cbs_type_h265 = { .flush = &cbs_h265_flush, .close = &cbs_h265_close, + + .insert_metadata = &ff_cbs_sei_insert_metadata, + .remove_metadata = &ff_cbs_sei_remove_metadata, + .extract_metadata = &ff_cbs_sei_extract_metadata, }; static const SEIMessageTypeDescriptor cbs_sei_common_types[] = { diff --git a/libavcodec/cbs_sei.c b/libavcodec/cbs_sei.c index 323997b600..e5f9e3e403 100644 --- a/libavcodec/cbs_sei.c +++ b/libavcodec/cbs_sei.c @@ -21,6 +21,7 @@ #include "cbs_h264.h" #include "cbs_h265.h" #include "cbs_sei.h" +#include "cbs_metadata.h" static void cbs_free_user_data_registered(void *opaque, uint8_t *data) { @@ -367,3 +368,96 @@ void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx, } } } + +typedef struct SEIMetadata { + enum CBSMetadataType cbs_type; + int sei_type; +} SEIMetadata; + +static const SEIMetadata cbs_sei_metadata[] = { +}; + +static const SEIMessageTypeDescriptor *cbs_sei_find_type_from_metadata + (CodedBitstreamContext *ctx, enum CBSMetadataType metadata_type) +{ + const SEIMetadata *metadata; + + metadata = NULL; + for (int i = 0; i < FF_ARRAY_ELEMS(cbs_sei_metadata); i++) { + if (metadata_type == cbs_sei_metadata[i].cbs_type) { + metadata = &cbs_sei_metadata[i]; + break; + } + } + if (metadata) + return ff_cbs_sei_find_type(ctx, metadata->sei_type); + else + return NULL; +} + +int ff_cbs_sei_insert_metadata(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + enum CBSMetadataType metadata_type, + const void *data) +{ + const SEIMessageTypeDescriptor *desc; + AVBufferRef *payload_buf; + int err; + + desc = cbs_sei_find_type_from_metadata(ctx, metadata_type); + if (!desc || !desc->fill) + return AVERROR(EINVAL); + + payload_buf = av_buffer_alloc(desc->size); + if (!payload_buf) + return AVERROR(ENOMEM); + + desc->fill(payload_buf->data, data); + + // All the metadata SEI messages must be unique in an access unit, + // so delete any existing ones of the given type. + ff_cbs_sei_delete_message_type(ctx, au, desc->type); + + err = ff_cbs_sei_add_message(ctx, au, desc->prefix, desc->type, + payload_buf->data, payload_buf); + av_buffer_unref(&payload_buf); + return err; +} + +int ff_cbs_sei_remove_metadata(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + enum CBSMetadataType metadata_type) +{ + const SEIMessageTypeDescriptor *desc; + + desc = cbs_sei_find_type_from_metadata(ctx, metadata_type); + if (!desc) + return AVERROR(EINVAL); + + ff_cbs_sei_delete_message_type(ctx, au, desc->type); + return 0; +} + +int ff_cbs_sei_extract_metadata(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + enum CBSMetadataType metadata_type, + void *data) +{ + const SEIMessageTypeDescriptor *desc; + SEIRawMessage *message; + int err; + + desc = cbs_sei_find_type_from_metadata(ctx, metadata_type); + if (!desc || !desc->extract) + return AVERROR(EINVAL); + + message = NULL; + err = ff_cbs_sei_find_message(ctx, au, desc->type, &message); + if (err < 0) { + // No message of the given type found. + return err; + } + + desc->extract(data, message->payload); + return 0; +} diff --git a/libavcodec/cbs_sei.h b/libavcodec/cbs_sei.h index 5ce4ad3ccd..16fd29265e 100644 --- a/libavcodec/cbs_sei.h +++ b/libavcodec/cbs_sei.h @@ -226,6 +226,8 @@ typedef int (*SEIMessageWriteFunction)(CodedBitstreamContext *ctx, void *current, SEIMessageState *sei); +typedef void (*SEIConvertFunction)(void *dst, const void *src); + typedef struct SEIMessageTypeDescriptor { // Payload type for the message. (-1 in this field ends a list.) int type; @@ -239,6 +241,10 @@ typedef struct SEIMessageTypeDescriptor { SEIMessageReadFunction read; // Write bitstream from SEI message. SEIMessageWriteFunction write; + // Fill SEI structure from AV metadata. + SEIConvertFunction fill; + // Extract SEI metadata to AV structure. + SEIConvertFunction extract; } SEIMessageTypeDescriptor; // Macro for the read/write pair. The clumsy cast is needed because the @@ -248,6 +254,10 @@ typedef struct SEIMessageTypeDescriptor { .read = (SEIMessageReadFunction) cbs_ ## codec ## _read_ ## name, \ .write = (SEIMessageWriteFunction)cbs_ ## codec ## _write_ ## name +#define SEI_MESSAGE_FE(codec, name) \ + .fill = (SEIConvertFunction)cbs_ ## codec ## _fill_ ## name, \ + .extract = (SEIConvertFunction)cbs_ ## codec ## _extract_ ## name + // End-of-list sentinel element. #define SEI_MESSAGE_TYPE_END { .type = -1 } @@ -305,6 +315,8 @@ int ff_cbs_sei_find_message(CodedBitstreamContext *ctx, uint32_t payload_type, SEIRawMessage **message); +enum CBSMetadataType; + /** * Delete all messages with the given payload type from an access unit. */ @@ -312,4 +324,27 @@ void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, uint32_t payload_type); +/** + * Insert metadata into an access unit. + */ +int ff_cbs_sei_insert_metadata(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + enum CBSMetadataType type, + const void *data); + +/** + * Remove metadata from an access unit. + */ +int ff_cbs_sei_remove_metadata(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + enum CBSMetadataType type); + +/** + * Extract metadata from an access unit. + */ +int ff_cbs_sei_extract_metadata(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + enum CBSMetadataType type, + void *data); + #endif /* AVCODEC_CBS_SEI_H */ -- 2.29.2 _______________________________________________ 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".