From patchwork Fri Jun 30 21:38:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 42353 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:3b1e:b0:12b:9ae3:586d with SMTP id c30csp2791424pzh; Fri, 30 Jun 2023 13:41:50 -0700 (PDT) X-Google-Smtp-Source: APBJJlHFqAwsKW80Aurrc9H9A3BZmchTIzBO7zGJjD7r/9wMf+DP0xKsRkV4L6DPYbk/jTKhb+Ku X-Received: by 2002:a17:906:fb1a:b0:98d:63c5:d132 with SMTP id lz26-20020a170906fb1a00b0098d63c5d132mr2725758ejb.72.1688157710643; Fri, 30 Jun 2023 13:41:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688157710; cv=none; d=google.com; s=arc-20160816; b=K3y5EzLY9w2AFmAJvu/jSE/+dHnSeUJkcg0WxKy2o26ebuw0/CdX8JYUWT9yqsl/hH M9dZUrATbH3emdmo6CToXPiKejCvvtqOK0OPc0Pb3rhh5J6EboMUJ6lP5d5Z5MSnVYi+ NpVayvkt0MlvsIP/EpncuK4tzuuRkerAmuHqWYgtF6tZ1Vbd6IvHpzm+R8yieC/BqVKF VtLwDpyvkI5PRiHQiYT1dhYbfV3k9yE06u8cmr0G7r+lhq26TVr6Z5e1227K/hZuOutA 7dyzmST5eC/V06/ukAuxird0Vt52mmlOj9kTmTQd/sPrcvrXyBz/SABAuiGKnyP6D6Eg ajWA== 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=oJX3FIFJT6ZEFhyIugCcGeVk/GwutZTP6wEwU500aJ8=; fh=pXLAZvRiz3/uELcsWNfKAkJPgyV9/rr3Mrznj9KeXEo=; b=c+MTGpXv9iYb9xtBC7FycIQ5Z2wUg7ygDdtDnhII0P1gCYIGPzbm0doI5xIvwU2wj4 50Vb7+iFSuaXuGi4nLSyl7xbx7tknZPSOnskMyNyMBkWxzqu+3x18HHbVbm76ff8QE97 3B+WVJIw6/cVz++7e7C9+Na2ghmxtumZ227OJE+GUTWRrsu3rVK/JrgfNQbLDQyt5Q8u J1IAUjF4D0ec/31iRzABjG/LZDhTCaehqkgHIPT7R+yAqdD0X1PTOJzVknIugE/c7cXk wSWg0ptUOrKEl0WxsAIH07xkQYWebMhOH1TkmWSBxCUOhgwHeTENTKrIbXlAYrXtfivj ZwJg== 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=YzQ3vCEL; 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 os5-20020a170906af6500b00992efdbb3b6si955739ejb.160.2023.06.30.13.41.50; Fri, 30 Jun 2023 13:41:50 -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=YzQ3vCEL; 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 28C8968C48A; Fri, 30 Jun 2023 23:41:15 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f180.google.com (mail-qt1-f180.google.com [209.85.160.180]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C7B6768C414 for ; Fri, 30 Jun 2023 23:41:06 +0300 (EEST) Received: by mail-qt1-f180.google.com with SMTP id d75a77b69052e-40339da998eso13385201cf.0 for ; Fri, 30 Jun 2023 13:41:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ltnglobal-com.20221208.gappssmtp.com; s=20221208; t=1688157665; x=1690749665; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=uiQF1aLl5HySEjehe2AO68RwYIXC61DmjKh7BiNYGks=; b=YzQ3vCELLxx2MXQthmNINEw9bn8rz1uk50mhd9QhjaR8YGU7HcWrWb0Xu6d1t6EjAN fRbbaamyO/KnXM5i1KUXSAZUdOX7Q9iEZ4TDhsh918hxEDTzbcQVVcncxIUumOluLN38 +EwiQBM4SnSHidldpDxBtm1htfFkQUurazyd1Np6YJZlQBAQtbbvM7DFjVn8lBOAhQx0 DIwibRu42TEa5vRHi4Pzjei74wix4h4f8jJE/w78P4VeiGE6zGMU4icL3I5Q3R6mhggo FIMfiNplwGdIAihVb2V24j5xfSuLKDoAveKVdbp6t14+ZzaR7xdSNHIo2CxeO9ngz4I4 dsdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688157665; x=1690749665; 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=uiQF1aLl5HySEjehe2AO68RwYIXC61DmjKh7BiNYGks=; b=JAInizdw2SvejjUfZm4+uOkivfKh8emVUXKNkqYhbvOG+rrgqipUwuKkjW6IuFJXVG rnBKIM5NbTjstXLBdyRLbKrg9kKNH40xfrWP3ME+Dpmaf/4SVDvUt8/9414tOEOHUISR 4uUsKu///ZKtI7EtLRPYrU0hiLPeG4Gcm/n+fbbeu3kKUrzeOFdZ/85z8cQwucwgBVf2 grqfxRyZaThcU54Mb8MsRfHGiTLxEwnsz7nPj4kI7xive720+8ny26+JZjmrO4fa8rnQ FkVfl2rac8TgO8HGZUCzuvIYYz7R1QrQSjdoQ4F1PSPKVGCBRMsezx8yd9bSIOd8EN5k XeaA== X-Gm-Message-State: AC+VfDzAksFA2zvrnL5kkfPL+Kif4EvQHvVCKtFtHy6lqbixPW19uG2f bPuYkYdA1jbHv4opbDXS8q/o3uY3bLRx2wCMuf8= X-Received: by 2002:a05:622a:94:b0:3f6:b923:b58d with SMTP id o20-20020a05622a009400b003f6b923b58dmr4523177qtw.27.1688157665375; Fri, 30 Jun 2023 13:41:05 -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 bq8-20020a05622a1c0800b003e0945575dasm4409885qtb.1.2023.06.30.13.41.04 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Jun 2023 13:41:05 -0700 (PDT) From: Devin Heitmueller X-Google-Original-From: Devin Heitmueller To: ffmpeg-devel@ffmpeg.org Date: Fri, 30 Jun 2023 17:38:52 -0400 Message-Id: <1688161135-11774-5-git-send-email-dheitmueller@ltnglobal.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1688161135-11774-1-git-send-email-dheitmueller@ltnglobal.com> References: <1688161135-11774-1-git-send-email-dheitmueller@ltnglobal.com> Subject: [FFmpeg-devel] [PATCH v2 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: Ok0l9hu11Y5U 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 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. +@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 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 + * + * 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), +};