From patchwork Wed Jun 7 20:22:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 41994 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c526:b0:117:ac03:c9de with SMTP id gm38csp659143pzb; Wed, 7 Jun 2023 12:25:34 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6iF/hJVt5q10oQC2DPetg1rkAVs1nnfqJJakiXLdYPad4VX3yTO4M4XT2RtM2KTF9MVgMZ X-Received: by 2002:aa7:c1ce:0:b0:514:9929:1b01 with SMTP id d14-20020aa7c1ce000000b0051499291b01mr5647358edp.8.1686165934640; Wed, 07 Jun 2023 12:25:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686165934; cv=none; d=google.com; s=arc-20160816; b=E1Qi9q0O+ceL4BW/sJHBbcwZOFR3KUtmhlFAUe+oByXY9GFyWFIZXvUfHPWcF94LHf GU8q6UQxNTGxUcC4k3MUy3TMqSc0sGtjTBtSKXMuQwQXwS7Gugl5bGt00ihyUkSz/kgy 0oFNFYcOsvrxl718HokSGrmOzNJjr0Eyaab1NAqk7N12RO3P+gwukN/GZR6nZh6iBU6/ K/q87cUNEYjW9qU2u/L56iB22QtpRVpwa9KpwUPKJtH1nmSY/GSc4mcqIQ5eNy8FZ32y IOhGU06zjr6oUwVECspy20n38OPzuE83U7jGmwLOVLrISy925Vc7mI8WegUmN+BuRtYU SPOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to; bh=MFwL9wBedOiZLRwUhw9QI1A7xswLzjt43s5Cli7hvJk=; b=nbDp8Vn2ANZhwcAhEWDcUuVITFud+eOKSSDTlmraIV8cpZpQ9LzlhrX5l1fmE6Sp8h AIx6/x7iGaqZu9hY8UFbPnsyNVcKDXL9GD6YkDONXiQ9K3XwNtKOIVTAhvBEAcRAiasM /XPZgHB9qaXUNp4rc13bCwzMoUPAvyb63H9dOn+pCO00FePyc2+qjNEju7m6Da474y38 cRN0Fc1Y4IA27LcXA2InPhE5AVuusSDIeJ3ZmfVCd06XoC+9HwjQCCB1OSiWSjzSkI3v Ikp1JR5gGP/ky+lq9uQDFa6Rj+fFj/ydQlnGNRJwRPXwKDitDb72/TpNNagsOeVMdtv2 x/KA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@ltnglobal-com.20221208.gappssmtp.com header.s=20221208 header.b=uk+JbCKF; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id b24-20020aa7c6d8000000b00514a41ecf61si8365782eds.287.2023.06.07.12.25.34; Wed, 07 Jun 2023 12:25:34 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@ltnglobal-com.20221208.gappssmtp.com header.s=20221208 header.b=uk+JbCKF; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9C7C268C009; Wed, 7 Jun 2023 22:25:06 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qv1-f45.google.com (mail-qv1-f45.google.com [209.85.219.45]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8BCF068BFB1 for ; Wed, 7 Jun 2023 22:24:58 +0300 (EEST) Received: by mail-qv1-f45.google.com with SMTP id 6a1803df08f44-62b68ce199bso16794326d6.0 for ; Wed, 07 Jun 2023 12:24:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ltnglobal-com.20221208.gappssmtp.com; s=20221208; t=1686165897; x=1688757897; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=MH5dwzmpvhvqKsMsL8mih7xHRQtHmuak6dNwF3FlRjo=; b=uk+JbCKFLsJdOkHU1aatqz1VTBdq4rWSbiIh/Q7CPWc7d6udhTAuIRDTwWhzUPHoEr KmgFsPBeJuuakD/1SSjYkdP3lbUIOOgWu4WQrtMWfwFCRUTJiVt5YfCakzvSagwnJBhm cpZ/YrDx9ABU0mSstbRJy2oyxU+CSV+DNPVK2qXBCLS2Baj5gbQ3isFkgDq9nA2e6nNl 175hW0Q9r0ZURb+QAppF0vyZOrnOMvEMQthIHXFkCVsq4pamcZq+wxtDiBezflmNK4nC mtN2P/uYVaEpWp0DvwCLI6DUhPBHw0nUqGq2aGzqQ4fNHLzBcbOXsqfWpN8NBMlOQgG2 N5Rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686165897; x=1688757897; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=MH5dwzmpvhvqKsMsL8mih7xHRQtHmuak6dNwF3FlRjo=; b=XStUS88FT23npme+LneUN7Sx2SCEuRaipMaxw+sQTOy7GbbQ54ms58HkRTm0r8DrV1 1XJXRS+tk37BvPsq6kLJsTeA5CrXiFncb7OdQ0PtHKKqITZAjREkCSiQuh/GQNcjEN5M o/dtI/Gxct99a/NJ0JH2bRGbQ4vtyURnSwYKZRac+8kqzV3dhSgooa19B86Odh26p2G3 GCNsTnoMfdaQnHKG+oUwhJkKaZh7uXAw9G4sE6AfxgXGBDwz1ScRpUTe5jE1EudlHtit WUPKPwvUlYz1bPrWv+bCLBjIIEsWvInRo2dbLbN4DtNrdUlAj2SGlrHHakPbufcq0XQZ KTZQ== X-Gm-Message-State: AC+VfDzdtA3D9jhU3xrsxWiNQ/WaBPKsn6IAb7AI0hVLN+2yOKcHl7TZ KDWtDA5sQ8bnpZjLqDV88qHxLx5zT9oT721hbKI= X-Received: by 2002:a05:6214:1d0a:b0:625:aa49:9aba with SMTP id e10-20020a0562141d0a00b00625aa499abamr5153847qvd.62.1686165897035; Wed, 07 Jun 2023 12:24:57 -0700 (PDT) Received: from ltnt-nyc-580testdevin.livetimenet.com (pool-71-105-132-214.nycmny.fios.verizon.net. [71.105.132.214]) by smtp.gmail.com with ESMTPSA id j18-20020a0cf512000000b006261c80d76dsm133643qvm.71.2023.06.07.12.24.56 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Jun 2023 12:24:56 -0700 (PDT) From: Devin Heitmueller X-Google-Original-From: Devin Heitmueller To: ffmpeg-devel@ffmpeg.org Date: Wed, 7 Jun 2023 16:22:24 -0400 Message-Id: <1686169347-28987-5-git-send-email-dheitmueller@ltnglobal.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1686169347-28987-1-git-send-email-dheitmueller@ltnglobal.com> References: <1686169347-28987-1-git-send-email-dheitmueller@ltnglobal.com> Subject: [FFmpeg-devel] [PATCH 4/7] libavfilter: Add filter to insert AFD/bar data X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Devin Heitmueller MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: +nof34Pe6Mr0 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 --- 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 9179c20..18aa998 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -21208,6 +21208,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. +@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: + +@table @option + +@item afd +This parameters dictates whether AFD side data will be injected. It is +enabled by default. + +@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. + +@item bardata +This parameter dictates whether bar data will be injected. It is +disabled by default. + +@item top +@item bottom +@item left +@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). + +@end table + +@subsection Examples + +@itemize +@item +Set the AFD value to 0x08 +@example +ffmpeg -i INPUT -vf setafd=code=0x08 OUTPUT +@end example +@item +Set the Bar data to a top width of 100 and a bottom width of 120 +@example +ffmpeg -i INPUT -vf setafd=afd=0:bardata=1:top=100:bottom=120 OUTPUT +@end example + +@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 18935b1..30954e1 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -467,6 +467,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 f1f7811..2ec9487 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -437,6 +437,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 + * + * 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), +};