[FFmpeg-devel] [PATCH 20/27] cbs: Add interface to allow BSFs easy access to metadata manipulation
Mark Thompson
sw at jkqxz.net
Fri Jan 1 23:35:30 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 429f360014..fe6304a0d4 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 ff_cbs_bsf_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
{
@@ -159,3 +160,75 @@ void ff_cbs_bsf_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 8cab3f144c..95cae316b2 100644
--- a/libavcodec/cbs_bsf.h
+++ b/libavcodec/cbs_bsf.h
@@ -55,6 +55,12 @@ int ff_cbs_bsf_filter(AVBSFContext *bsf, AVPacket *pkt);
int ff_cbs_bsf_init(AVBSFContext *bsf, const CBSBSFType *type);
void ff_cbs_bsf_close(AVBSFContext *bsf);
+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.29.2
More information about the ffmpeg-devel
mailing list