[FFmpeg-devel] [PATCH v2 4/7] libavfilter: Add filter to insert AFD/bar data
Devin Heitmueller
devin.heitmueller at ltnglobal.com
Sat Jul 1 00:38:52 EEST 2023
Introduce a new filter which allows the user to manually set the
AFD or bar data side data on AVFrames.
Signed-off-by: Devin Heitmueller <dheitmueller at ltnglobal.com>
---
doc/filters.texi | 52 ++++++++++++++++++
libavfilter/Makefile | 1 +
libavfilter/allfilters.c | 1 +
libavfilter/vf_afd.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 187 insertions(+)
create mode 100644 libavfilter/vf_afd.c
diff --git a/doc/filters.texi b/doc/filters.texi
index 793868b..ae74b4c 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -21338,6 +21338,58 @@ This filter use field-dominance information in frame to decide which
of each pair of fields to place first in the output.
If it gets it wrong use @ref{setfield} filter before @code{separatefields} filter.
+ at section setafd
+
+The @code{setafd} filter sets the Aspect Ratio Description side data for the
+output video.
+
+This filter allows configuration of AFD metadata (conforming to
+ETSI TS 101 154 or SMPTE ST2016-1), as well as Bar Data (conforming to
+SMPTE 2016-1, ATSC A/53, and SCTE 128-1)
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item afd
+This parameters dictates whether AFD side data will be injected. It is
+enabled by default.
+
+ at item code
+If AFD output is enabled, this parameter will specify the AFD code to
+insert into the video stream. Valid values are from 0x00 to 0x0f.
+
+ at item bardata
+This parameter dictates whether bar data will be injected. It is
+disabled by default.
+
+ at item top
+ at item bottom
+ at item left
+ at item right
+If bardata output is enabled, These parameters specify the dimensions
+of the bar data. Typically only top/bottom or left/right would be specified.
+If either top or bottom are specified, the bar data inserted will be for those
+parameters (even if left/right are also specified).
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Set the AFD value to 0x08
+ at example
+ffmpeg -i INPUT -vf setafd=code=0x08 OUTPUT
+ at end example
+ at item
+Set the Bar data to a top width of 100 and a bottom width of 120
+ at example
+ffmpeg -i INPUT -vf setafd=afd=0:bardata=1:top=100:bottom=120 OUTPUT
+ at end example
+
+ at end itemize
+
@section setdar, setsar
The @code{setdar} filter sets the Display Aspect Ratio for the filter
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 9b78135..6153fac 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -469,6 +469,7 @@ OBJS-$(CONFIG_SELECTIVECOLOR_FILTER) += vf_selectivecolor.o
OBJS-$(CONFIG_SENDCMD_FILTER) += f_sendcmd.o
OBJS-$(CONFIG_SEPARATEFIELDS_FILTER) += vf_separatefields.o
OBJS-$(CONFIG_SETDAR_FILTER) += vf_aspect.o
+OBJS-$(CONFIG_SETAFD_FILTER) += vf_afd.o
OBJS-$(CONFIG_SETFIELD_FILTER) += vf_setparams.o
OBJS-$(CONFIG_SETPARAMS_FILTER) += vf_setparams.o
OBJS-$(CONFIG_SETPTS_FILTER) += setpts.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 9a7fadc..7d2114c 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -438,6 +438,7 @@ extern const AVFilter ff_vf_select;
extern const AVFilter ff_vf_selectivecolor;
extern const AVFilter ff_vf_sendcmd;
extern const AVFilter ff_vf_separatefields;
+extern const AVFilter ff_vf_setafd;
extern const AVFilter ff_vf_setdar;
extern const AVFilter ff_vf_setfield;
extern const AVFilter ff_vf_setparams;
diff --git a/libavfilter/vf_afd.c b/libavfilter/vf_afd.c
new file mode 100644
index 0000000..a6120c8
--- /dev/null
+++ b/libavfilter/vf_afd.c
@@ -0,0 +1,133 @@
+/*
+ * AFD and Bardata Insertion Filter
+ * Copyright (c) 2023 LTN Global Communications
+ *
+ * Author: Devin Heitmueller <dheitmueller at ltnglobal.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Active Format Description and Bar Data Insertion Filter
+ */
+
+#include "libavcodec/defs.h"
+#include "libavutil/common.h"
+#include "libavutil/opt.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct AFDContext {
+ const AVClass *class;
+ int enable_afd;
+ int afd_code;
+ int enable_bardata;
+ int top;
+ int bottom;
+ int left;
+ int right;
+} AFDContext;
+
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
+{
+ AFDContext *s = link->dst->priv;
+ AVFrameSideData *side_data;
+ AVBarData *bar_data;
+
+ /* Insert/tweak the side-data for AFD */
+ if (s->enable_afd) {
+ /* Insert/tweak the side-data for Bar Data */
+ side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_AFD);
+ if (!side_data) {
+ side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_AFD, sizeof(unsigned char));
+ if (side_data == NULL)
+ return -ENOMEM;
+ }
+ side_data->data[0] = s->afd_code;
+ }
+
+ if (s->enable_bardata) {
+ /* Insert/tweak the side-data for Bar Data */
+ side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_BARDATA);
+ if (!side_data) {
+ side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_BARDATA, sizeof(AVBarData));
+ if (side_data == NULL)
+ return -ENOMEM;
+ }
+ bar_data = (AVBarData *) side_data->data;
+ if (s->top || s->bottom) {
+ bar_data->top_bottom = 1;
+ bar_data->top = s->top;
+ bar_data->bottom = s->bottom;
+ bar_data->left = 0;
+ bar_data->right = 0;
+ } else {
+ bar_data->top_bottom = 0;
+ bar_data->top = 0;
+ bar_data->bottom = 0;
+ bar_data->left = s->left;
+ bar_data->right = s->right;
+ }
+ }
+
+ return ff_filter_frame(link->dst->outputs[0], frame);
+}
+
+#define OFFSET(x) offsetof(AFDContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption setafd_options[] = {
+ /* AFD Options */
+ { "afd", "Enable AFD insertion", OFFSET(enable_afd), AV_OPT_TYPE_BOOL, { .i64 = 1}, 0, 1, .flags = FLAGS },
+ { "code", "AFD code to insert", OFFSET(afd_code), AV_OPT_TYPE_INT, {.i64=0}, 0, 0x0F, FLAGS },
+
+ /* Bar data Options */
+ { "bardata","Enable Bar Data insertion", OFFSET(enable_bardata), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, .flags = FLAGS },
+ { "top", "top bar position", OFFSET(top), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
+ { "bottom","bottom bar position", OFFSET(bottom), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
+ { "left", "left bar position", OFFSET(left), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
+ { "right", "right bar position", OFFSET(right), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(setafd);
+
+static const AVFilterPad avfilter_vf_setafd_inputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .filter_frame = filter_frame,
+ },
+};
+
+static const AVFilterPad avfilter_vf_setafd_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ },
+};
+
+const AVFilter ff_vf_setafd = {
+ .name = "setafd",
+ .description = NULL_IF_CONFIG_SMALL("Set AFD and/or Bar Data for video frames"),
+ .priv_size = sizeof(AFDContext),
+ .priv_class = &setafd_class,
+ .flags = AVFILTER_FLAG_METADATA_ONLY,
+ FILTER_INPUTS(avfilter_vf_setafd_inputs),
+ FILTER_OUTPUTS(avfilter_vf_setafd_outputs),
+};
--
1.8.3.1
More information about the ffmpeg-devel
mailing list