[FFmpeg-devel] [PATCH v2 10/18] cbs: Add interface to allow BSFs easy access to metadata manipulation
Mark Thompson
sw at jkqxz.net
Sun Feb 21 21:51:17 EET 2021
---
libavcodec/cbs_bsf.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
libavcodec/cbs_bsf.h | 6 ++++
2 files changed, 79 insertions(+)
diff --git a/libavcodec/cbs_bsf.c b/libavcodec/cbs_bsf.c
index 9b521cf111..4f8f7f499d 100644
--- a/libavcodec/cbs_bsf.c
+++ b/libavcodec/cbs_bsf.c
@@ -18,6 +18,7 @@
#include "bsf_internal.h"
#include "cbs_bsf.h"
+#include "cbs_metadata.h"
static int cbs_bsf_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
{
@@ -157,3 +158,75 @@ void ff_cbs_bsf_generic_close(AVBSFContext *bsf)
ff_cbs_close(&ctx->input);
ff_cbs_close(&ctx->output);
}
+
+int ff_cbs_bsf_apply_metadata(AVBSFContext *bsf,
+ AVPacket *pkt,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type, int action)
+{
+ CBSBSFContext *ctx = bsf->priv_data;
+ const CBSMetadataTypeDescriptor *desc;
+ uint8_t *side_data;
+ size_t size;
+ int err, ignored;
+
+ desc = ff_cbs_metadata_find_type(type);
+ if (!desc)
+ return AVERROR(EINVAL);
+ if (!desc->has_packet_side_data)
+ return AVERROR(EINVAL);
+
+ switch (action) {
+ case BSF_ELEMENT_PASS:
+ // Nothing to do.
+ return 0;
+
+ case BSF_ELEMENT_REMOVE:
+ // Remove all existing instances of the metadata.
+ err = ff_cbs_remove_metadata(ctx->output, frag, type);
+ if (err < 0) {
+ av_log(bsf, AV_LOG_ERROR, "Failed to remove %s metadata "
+ "from %s.\n", desc->name, ctx->type->fragment_name);
+ }
+ return err;
+
+ case BSF_ELEMENT_INSERT:
+ // Insert matching side-data to replace existing metadata.
+ side_data = av_packet_get_side_data(pkt,
+ desc->packet_side_data_type,
+ &ignored);
+ if (!side_data) {
+ // No side data of this type.
+ return 0;
+ }
+ err = ff_cbs_insert_metadata(ctx->output, frag, type, side_data);
+ if (err < 0) {
+ av_log(bsf, AV_LOG_ERROR, "Failed to insert %s metadata "
+ "into %s.\n", desc->name, ctx->type->fragment_name);
+ }
+
+ case BSF_ELEMENT_EXTRACT:
+ // Extract the metadata and attach it to the packet as side-data.
+ side_data = ff_cbs_alloc_metadata(type, &size);
+ if (!side_data)
+ return AVERROR(ENOMEM);
+ err = ff_cbs_extract_metadata(ctx->output, frag, type, side_data);
+ if (err == AVERROR(ENOENT)) {
+ // No metadata of that type.
+ return 0;
+ }
+ if (err < 0) {
+ av_log(bsf, AV_LOG_ERROR, "Failed to extract %s metadata "
+ "from %s.\n", desc->name, ctx->type->fragment_name);
+ return err;
+ }
+ err = av_packet_add_side_data(pkt, desc->packet_side_data_type,
+ side_data, size);
+ if (err < 0)
+ av_free(side_data);
+ return err;
+
+ default:
+ return AVERROR(EINVAL);
+ }
+}
diff --git a/libavcodec/cbs_bsf.h b/libavcodec/cbs_bsf.h
index 6be95abc3f..7027c20746 100644
--- a/libavcodec/cbs_bsf.h
+++ b/libavcodec/cbs_bsf.h
@@ -86,6 +86,12 @@ void ff_cbs_bsf_generic_close(AVBSFContext *bsf);
*/
int ff_cbs_bsf_generic_filter(AVBSFContext *bsf, AVPacket *pkt);
+enum CBSMetadataType;
+
+int ff_cbs_bsf_apply_metadata(AVBSFContext *bsf,
+ AVPacket *pkt,
+ CodedBitstreamFragment *frag,
+ enum CBSMetadataType type, int action);
// Options for element manipulation.
enum {
--
2.30.0
More information about the ffmpeg-devel
mailing list