From patchwork Sun Aug 23 22:33:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 21856 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 474A044B129 for ; Mon, 24 Aug 2020 01:35:31 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1F023689EEC; Mon, 24 Aug 2020 01:35:31 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CBA606880C4 for ; Mon, 24 Aug 2020 01:35:24 +0300 (EEST) Received: by mail-wr1-f53.google.com with SMTP id l2so6859815wrc.7 for ; Sun, 23 Aug 2020 15:35:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=pOguBebGLCMhDSIi0NCPDs0dCl57Y0+L6hQqmB8CUG0=; b=lRCfS8Qn8uyufX+Xr0KMkiQN98XB5PIAGH8vXwgCJAiFShQJgPnN2Z39Fk1ZOyvain mdOqrmnZ/1K6elDH0QkDtte/YKY9k6DfsC+UAHnrrZoWeLmoEvPjkYQbHKUCnyzkbZKs XwxkNZE2xVrBeUQCPAiGQShwUrQahTlL8H4LmOoiMaulodKzx2uPS7Qr2sfQYCBYeMKv Ap9wz+WCb879kbuZSYzXcAvBRyAS1EDqYmQBIhLe1TvF3GRMXgWBk8Ch2/sBBZpR/mJt +93yblmwbiWxoDa6rgIi2+ZtiBhZ0q/1Vx8FriO7587CKovxLiWLWF/hGf8BLevMFQvC Ey/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=pOguBebGLCMhDSIi0NCPDs0dCl57Y0+L6hQqmB8CUG0=; b=FIhCcrDq3+2RAeIN+g8zNsTuoU7MDK/N6j0X96+K1lAv+Cte4r/w1Ifo1svp/S300j BGKFVBpX4aaRb51Vw0PGEAIu8PSV3w71Pz/dIv2GPVa321vrUW2NHO3G/DzLvMoSlCTh NR7lv+qyTm04UD1Exi4NXmDi/HpdWi2dHtu7dnd6GLV2dxj2qhVIYjP5IThq2fTgpx0c BlUOyIESvENSRaO6TaRsZGw6HtT1itqmkGijYiTLfBQvDZ6167bhNvu4hfBQzTlw0Hoo iKTxjxa7lueblcS0IlbpBUFDh4X0tlF5ZCtzYy7JdXmjFsiwAxm2HDXoJWzsy9BX1yfU n5zA== X-Gm-Message-State: AOAM533AlBKbv5adKCuCaP8Zb+RBYx2OX13mgLwKwrtr7zmXb0cmY/z6 6QxBqp0+7p/aYQXe+sxfds/pMYffzDUUQA== X-Google-Smtp-Source: ABdhPJz/Ix6WU5oz26ENdaCr2vxPeO2/Mv/MIItWnSkxeNRF50REEv5hC9/FvGjZtUkoxRg+PYNuEw== X-Received: by 2002:adf:82f6:: with SMTP id 109mr3315696wrc.25.1598222123412; Sun, 23 Aug 2020 15:35:23 -0700 (PDT) Received: from localhost.localdomain (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id f10sm11216852wmj.37.2020.08.23.15.35.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2020 15:35:22 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 23 Aug 2020 23:33:03 +0100 Message-Id: <20200823223310.233061-1-sw@jkqxz.net> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/8] cbs: Implement common parts of cbs-based bitstream filters separately X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- This series depends on the CBS unit table rewrite and following cleanups. Since comments on that series seem to have dried up, I will apply it in a few days if nothing further comes up. libavcodec/Makefile | 2 +- libavcodec/cbs_bsf.c | 161 +++++++++++++++++++++++++++++++++++++++++++ libavcodec/cbs_bsf.h | 100 +++++++++++++++++++++++++++ 3 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 libavcodec/cbs_bsf.c create mode 100644 libavcodec/cbs_bsf.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 9ef87198f1..dc41c35c8f 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -69,7 +69,7 @@ OBJS-$(CONFIG_AUDIODSP) += audiodsp.o OBJS-$(CONFIG_BLOCKDSP) += blockdsp.o OBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o OBJS-$(CONFIG_CABAC) += cabac.o -OBJS-$(CONFIG_CBS) += cbs.o +OBJS-$(CONFIG_CBS) += cbs.o cbs_bsf.o OBJS-$(CONFIG_CBS_AV1) += cbs_av1.o OBJS-$(CONFIG_CBS_H264) += cbs_h2645.o cbs_h264.o h2645_parse.o OBJS-$(CONFIG_CBS_H265) += cbs_h2645.o cbs_h265.o h2645_parse.o diff --git a/libavcodec/cbs_bsf.c b/libavcodec/cbs_bsf.c new file mode 100644 index 0000000000..429f360014 --- /dev/null +++ b/libavcodec/cbs_bsf.c @@ -0,0 +1,161 @@ +/* + * 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 + */ + +#include "bsf_internal.h" +#include "cbs_bsf.h" + +static int ff_cbs_bsf_update_side_data(AVBSFContext *bsf, AVPacket *pkt) +{ + CBSBSFContext *ctx = bsf->priv_data; + CodedBitstreamFragment *frag = &ctx->fragment; + uint8_t *side_data; + int side_data_size; + int err; + + side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, + &side_data_size); + if (!side_data_size) + return 0; + + err = ff_cbs_read(ctx->input, frag, side_data, side_data_size); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, + "Failed to read extradata from packet side data.\n"); + return err; + } + + err = ctx->type->update_fragment(bsf, NULL, frag); + if (err < 0) + goto fail; + + err = ff_cbs_write_fragment_data(ctx->output, frag); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, + "Failed to write extradata into packet side data.\n"); + return err; + } + + side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, + frag->data_size); + if (!side_data) + return AVERROR(ENOMEM); + memcpy(side_data, frag->data, frag->data_size); + + err = 0; +fail: + ff_cbs_fragment_reset(frag); + return err; +} + +int ff_cbs_bsf_filter(AVBSFContext *bsf, AVPacket *pkt) +{ + CBSBSFContext *ctx = bsf->priv_data; + CodedBitstreamFragment *frag = &ctx->fragment; + int err; + + err = ff_bsf_get_packet_ref(bsf, pkt); + if (err < 0) + return err; + + err = ff_cbs_bsf_update_side_data(bsf, pkt); + if (err < 0) + goto fail; + + err = ff_cbs_read_packet(ctx->input, frag, pkt); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to read %s from packet.\n", + ctx->type->fragment_name); + goto fail; + } + + if (frag->nb_units == 0) { + av_log(bsf, AV_LOG_ERROR, "No %s found in packet.\n", + ctx->type->unit_name); + err = AVERROR_INVALIDDATA; + goto fail; + } + + err = ctx->type->update_fragment(bsf, pkt, frag); + if (err < 0) + goto fail; + + err = ff_cbs_write_packet(ctx->output, pkt, frag); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to write %s into packet.\n", + ctx->type->fragment_name); + goto fail; + } + + err = 0; +fail: + ff_cbs_fragment_reset(frag); + + if (err < 0) + av_packet_unref(pkt); + + return err; +} + +int ff_cbs_bsf_init(AVBSFContext *bsf, const CBSBSFType *type) +{ + CBSBSFContext *ctx = bsf->priv_data; + CodedBitstreamFragment *frag = &ctx->fragment; + int err; + + ctx->type = type; + + err = ff_cbs_init(&ctx->input, type->codec_id, bsf); + if (err < 0) + return err; + + err = ff_cbs_init(&ctx->output, type->codec_id, bsf); + if (err < 0) + return err; + + if (bsf->par_in->extradata) { + err = ff_cbs_read_extradata(ctx->input, frag, bsf->par_in); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); + goto fail; + } + + err = type->update_fragment(bsf, NULL, frag); + if (err < 0) + goto fail; + + err = ff_cbs_write_extradata(ctx->output, bsf->par_out, frag); + if (err < 0) { + av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); + goto fail; + } + } + + err = 0; +fail: + ff_cbs_fragment_reset(frag); + return err; +} + +void ff_cbs_bsf_close(AVBSFContext *bsf) +{ + CBSBSFContext *ctx = bsf->priv_data; + + ff_cbs_fragment_free(&ctx->fragment); + ff_cbs_close(&ctx->input); + ff_cbs_close(&ctx->output); +} diff --git a/libavcodec/cbs_bsf.h b/libavcodec/cbs_bsf.h new file mode 100644 index 0000000000..8cab3f144c --- /dev/null +++ b/libavcodec/cbs_bsf.h @@ -0,0 +1,100 @@ +/* + * 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 + */ + +#ifndef AVCODEC_CBS_BSF_H +#define AVCODEC_CBS_BSF_H + +#include "cbs.h" + + +typedef struct CBSBSFType { + enum AVCodecID codec_id; + + // Name of a frame fragment in this codec (e.g. "access unit", + // "temporal unit"). + const char *fragment_name; + + // Name of a unit for this BSF, for use in error messages (e.g. + // "NAL unit", "OBU"). + const char *unit_name; + + // Update the content of a fragment with whatever metadata changes + // are desired. The associated AVPacket is provided so that any side + // data associated with the fragment can be inspected or edited. If + // pkt is NULL, then an extradata header fragment is being updated. + int (*update_fragment)(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *frag); +} CBSBSFType; + +typedef struct CBSBSFContext { + const AVClass *class; + const CBSBSFType *type; + + CodedBitstreamContext *input; + CodedBitstreamContext *output; + CodedBitstreamFragment fragment; +} CBSBSFContext; + + +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); + + +// Options for element manipulation. +enum { + // Pass this element through unchanged. + BSF_ELEMENT_PASS, + // Insert this element, replacing any existing instances of it. + // Associated values may be provided explicitly (as addtional options) + // or implicitly (either as side data or deduced from other parts of + // the stream). + BSF_ELEMENT_INSERT, + // Remove this element if it appears in the stream. + BSF_ELEMENT_REMOVE, + // Extract this element to side data, so that further manipulation + // can happen elsewhere. + BSF_ELEMENT_EXTRACT, +}; + +#define BSF_ELEMENT_OPTIONS_PIR(name, help, field, unit_name) \ + { name, help, OFFSET(field), AV_OPT_TYPE_INT, \ + { .i64 = BSF_ELEMENT_PASS }, \ + BSF_ELEMENT_PASS, BSF_ELEMENT_REMOVE, FLAGS, unit_name }, \ + { "pass", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_PASS }, .flags = FLAGS, .unit = unit_name }, \ + { "insert", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_INSERT }, .flags = FLAGS, .unit = unit_name }, \ + { "remove", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_REMOVE }, .flags = FLAGS, .unit = unit_name } + +#define BSF_ELEMENT_OPTIONS_PIRE(name, help, field, unit_name) \ + { name, help, OFFSET(field), AV_OPT_TYPE_INT, \ + { .i64 = BSF_ELEMENT_PASS }, \ + BSF_ELEMENT_PASS, BSF_ELEMENT_EXTRACT, FLAGS, unit_name }, \ + { "pass", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_PASS }, .flags = FLAGS, .unit = unit_name }, \ + { "insert", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_INSERT }, .flags = FLAGS, .unit = unit_name }, \ + { "remove", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_REMOVE }, .flags = FLAGS, .unit = unit_name }, \ + { "extract", NULL, 0, AV_OPT_TYPE_CONST, \ + { .i64 = BSF_ELEMENT_EXTRACT }, .flags = FLAGS, .unit = unit_name } \ + + +#endif /* AVCODEC_CBS_BSF_H */ From patchwork Sun Aug 23 22:33:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 21857 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 62C7A44B129 for ; Mon, 24 Aug 2020 01:35:32 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4C04468A188; Mon, 24 Aug 2020 01:35:32 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 364056880C4 for ; Mon, 24 Aug 2020 01:35:25 +0300 (EEST) Received: by mail-wm1-f66.google.com with SMTP id k20so6492423wmi.5 for ; Sun, 23 Aug 2020 15:35:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=rMrAc6kurnwPws7PLywSbKXkJGzb/QtzAi1iCN3gqgc=; b=dLIPB6zQvlL++9fnvEsM8W2Vm/7peOisjGZ5ybMNCKxbJF0QQDm+/Ue2tE2a9EmPNM ZUYr8sbM49sw2YkEPNxUsb8OyuDsbgUJ7aXadaWq0tHcc0F4VChI4byTvI5J/UOLKYk+ UasbfPfH+y7sKH0BRR+OQnPvONs0ADQMQB+TE/bpcsdlkx4EkwhyNlvaIPOu7HM2wuVA eT9cteFxcIOmtBGJKFC3ThWSXiAM/rUZlMNwTaSwwjIQT6GbwPo+t6r79eVJf8pSzAGD 8v8GdFprNd4+RSC59d0VbYEhxFiGg1snT0w5bpWq44PaUUK84MB1NPxOIu8RSqXvkgx2 Qc8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rMrAc6kurnwPws7PLywSbKXkJGzb/QtzAi1iCN3gqgc=; b=nrepkqvJYa2HgWtwTImU1EIvGCYxsTzuOBvC6tslhRq1nsFGCKORBuOPz613t2xmM8 YdBOa7f6Xbu/k1yDlRkwYKg8fMOeWzGPR6Ae6XSOiZBfNO6Xi5Wvw2g79xITEtqQ7Z5h GxMkLBTJeQeOj2VX3JVUnxujkrwUyorEEz991WqAxGgOHc/RFrI8PsbJUYuUz9ICnMtM 1b4Jj99ZhQE31hyR6Il4WBXjOQ8YV7H/118SnYkHwCjP//+aGM0t8H42KjssB8dnXdBM 9D6G+85I2NOgE7U+qCeKmHIpJucBtfOc3PhBRkjag6uTX4/AU7+XiLLB/cQXPrTTfsb6 xJ4Q== X-Gm-Message-State: AOAM530f4Edna6WHhuJFSNPf42ebYTIWZu5RlSkuyKvsKUF9XBj76o0x vZEHpUtJFgtUoggm/GOOZHdN/qZhsQbuAg== X-Google-Smtp-Source: ABdhPJwBIpkiTImK7y4U6f82+7FcSw2vcI5o/2sQwnHhugsAZwmhJGmZnRBugAR/i8UTZA/U4ytMnQ== X-Received: by 2002:a1c:7407:: with SMTP id p7mr2916983wmc.117.1598222124204; Sun, 23 Aug 2020 15:35:24 -0700 (PDT) Received: from localhost.localdomain (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id f10sm11216852wmj.37.2020.08.23.15.35.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2020 15:35:23 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 23 Aug 2020 23:33:04 +0100 Message-Id: <20200823223310.233061-2-sw@jkqxz.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200823223310.233061-1-sw@jkqxz.net> References: <20200823223310.233061-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/8] h264_metadata_bsf: Use common cbs bsf implementation X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/h264_metadata_bsf.c | 225 +++++++-------------------------- 1 file changed, 45 insertions(+), 180 deletions(-) diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c index 7d6d871240..4243a8da98 100644 --- a/libavcodec/h264_metadata_bsf.c +++ b/libavcodec/h264_metadata_bsf.c @@ -22,20 +22,13 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_h264.h" #include "h264.h" #include "h264_levels.h" #include "h264_sei.h" -enum { - PASS, - INSERT, - REMOVE, - EXTRACT, -}; - enum { FLIP_HORIZONTAL = 1, FLIP_VERTICAL = 2, @@ -47,11 +40,7 @@ enum { }; typedef struct H264MetadataContext { - const AVClass *class; - - CodedBitstreamContext *input; - CodedBitstreamContext *output; - CodedBitstreamFragment access_unit; + CBSBSFContext common; int done_first_au; @@ -332,49 +321,6 @@ static int h264_metadata_update_sps(AVBSFContext *bsf, return 0; } -static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) -{ - H264MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - uint8_t *side_data; - int side_data_size; - int err, i; - - side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, - &side_data_size); - if (!side_data_size) - return 0; - - err = ff_cbs_read(ctx->input, au, side_data, side_data_size); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n"); - return err; - } - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_SPS) { - err = h264_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - return err; - } - } - - err = ff_cbs_write_fragment_data(ctx->output, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n"); - return err; - } - - side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, au->data_size); - if (!side_data) - return AVERROR(ENOMEM); - memcpy(side_data, au->data, au->data_size); - - ff_cbs_fragment_reset(au); - - return 0; -} - static int h264_metadata_handle_display_orientation(AVBSFContext *bsf, AVPacket *pkt, CodedBitstreamFragment *au, @@ -398,8 +344,8 @@ static int h264_metadata_handle_display_orientation(AVBSFContext *bsf, continue; disp = &sei->payload[j].payload.display_orientation; - if (ctx->display_orientation == REMOVE || - ctx->display_orientation == INSERT) { + if (ctx->display_orientation == BSF_ELEMENT_REMOVE || + ctx->display_orientation == BSF_ELEMENT_INSERT) { ff_cbs_h264_delete_sei_message(au, &au->units[i], j); continue; } @@ -428,7 +374,7 @@ static int h264_metadata_handle_display_orientation(AVBSFContext *bsf, } } - if (ctx->display_orientation == INSERT) { + if (ctx->display_orientation == BSF_ELEMENT_INSERT) { H264RawSEIPayload payload = { .payload_type = H264_SEI_TYPE_DISPLAY_ORIENTATION, }; @@ -517,41 +463,21 @@ static int h264_metadata_handle_display_orientation(AVBSFContext *bsf, return 0; } -static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) +static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *au) { H264MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; int err, i, j, has_sps, seek_point; - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = h264_metadata_update_side_data(bsf, pkt); - if (err < 0) - goto fail; - - err = ff_cbs_read_packet(ctx->input, au, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } - - if (au->nb_units == 0) { - av_log(bsf, AV_LOG_ERROR, "No NAL units in packet.\n"); - err = AVERROR_INVALIDDATA; - goto fail; - } - // If an AUD is present, it must be the first NAL unit. if (au->units[0].type == H264_NAL_AUD) { - if (ctx->aud == REMOVE) + if (ctx->aud == BSF_ELEMENT_REMOVE) ff_cbs_delete_unit(au, 0); } else { - if (ctx->aud == INSERT) { + if (ctx->aud == BSF_ELEMENT_INSERT && pkt) { err = h264_metadata_insert_aud(bsf, au); if (err < 0) - goto fail; + return err; } } @@ -560,25 +486,29 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (au->units[i].type == H264_NAL_SPS) { err = h264_metadata_update_sps(bsf, au->units[i].content); if (err < 0) - goto fail; + return err; has_sps = 1; } } - // The current packet should be treated as a seek point for metadata - // insertion if any of: - // - It is the first packet in the stream. - // - It contains an SPS, indicating that a sequence might start here. - // - It is marked as containing a key frame. - seek_point = !ctx->done_first_au || has_sps || - (pkt->flags & AV_PKT_FLAG_KEY); + if (pkt) { + // The current packet should be treated as a seek point for metadata + // insertion if any of: + // - It is the first packet in the stream. + // - It contains an SPS, indicating that a sequence might start here. + // - It is marked as containing a key frame. + seek_point = !ctx->done_first_au || has_sps || + (pkt->flags & AV_PKT_FLAG_KEY); + } else { + seek_point = 0; + } if (ctx->sei_user_data && seek_point) { err = ff_cbs_h264_add_sei_message(au, &ctx->sei_user_data_payload); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI " "message to access unit.\n"); - goto fail; + return err; } } @@ -603,41 +533,33 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) } } - if (ctx->display_orientation != PASS) { + if (ctx->display_orientation != BSF_ELEMENT_PASS) { err = h264_metadata_handle_display_orientation(bsf, pkt, au, seek_point); if (err < 0) - goto fail; + return err; } - err = ff_cbs_write_packet(ctx->output, pkt, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - ctx->done_first_au = 1; - - err = 0; -fail: - ff_cbs_fragment_reset(au); - - if (err < 0) - av_packet_unref(pkt); - - return err; + if (pkt) + ctx->done_first_au = 1; + return 0; } +static const CBSBSFType h264_metadata_type = { + .codec_id = AV_CODEC_ID_H264, + .fragment_name = "access unit", + .unit_name = "NAL unit", + .update_fragment = &h264_metadata_update_fragment, +}; + static int h264_metadata_init(AVBSFContext *bsf) { H264MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - int err, i; if (ctx->sei_user_data) { H264RawSEIUserDataUnregistered *udu = &ctx->sei_user_data_payload.payload.user_data_unregistered; - int j; + int i, j; ctx->sei_user_data_payload.payload_type = H264_SEI_TYPE_USER_DATA_UNREGISTERED; @@ -667,67 +589,18 @@ static int h264_metadata_init(AVBSFContext *bsf) } else { av_log(bsf, AV_LOG_ERROR, "Invalid user data: " "must be \"UUID+string\".\n"); - err = AVERROR(EINVAL); - goto fail; - } - } - - err = ff_cbs_init(&ctx->input, AV_CODEC_ID_H264, bsf); - if (err < 0) - return err; - err = ff_cbs_init(&ctx->output, AV_CODEC_ID_H264, bsf); - if (err < 0) - return err; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_SPS) { - err = h264_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - goto fail; - } - } - - err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; + return AVERROR(EINVAL); } } - err = 0; -fail: - ff_cbs_fragment_reset(au); - return err; -} - -static void h264_metadata_close(AVBSFContext *bsf) -{ - H264MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(&ctx->access_unit); - ff_cbs_close(&ctx->input); - ff_cbs_close(&ctx->output); + return ff_cbs_bsf_init(bsf, &h264_metadata_type); } #define OFFSET(x) offsetof(H264MetadataContext, x) #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) static const AVOption h264_metadata_options[] = { - { "aud", "Access Unit Delimiter NAL units", - OFFSET(aud), AV_OPT_TYPE_INT, - { .i64 = PASS }, PASS, REMOVE, FLAGS, "aud" }, - { "pass", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = PASS }, .flags = FLAGS, .unit = "aud" }, - { "insert", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = INSERT }, .flags = FLAGS, .unit = "aud" }, - { "remove", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = REMOVE }, .flags = FLAGS, .unit = "aud" }, + BSF_ELEMENT_OPTIONS_PIR("aud", "Access Unit Delimiter NAL units", + aud, "aud"), { "sample_aspect_ratio", "Set sample aspect ratio (table E-1)", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, @@ -783,17 +656,9 @@ static const AVOption h264_metadata_options[] = { { "delete_filler", "Delete all filler (both NAL and SEI)", OFFSET(delete_filler), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS}, - { "display_orientation", "Display orientation SEI", - OFFSET(display_orientation), AV_OPT_TYPE_INT, - { .i64 = PASS }, PASS, EXTRACT, FLAGS, "disp_or" }, - { "pass", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = PASS }, .flags = FLAGS, .unit = "disp_or" }, - { "insert", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = INSERT }, .flags = FLAGS, .unit = "disp_or" }, - { "remove", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = REMOVE }, .flags = FLAGS, .unit = "disp_or" }, - { "extract", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = EXTRACT }, .flags = FLAGS, .unit = "disp_or" }, + BSF_ELEMENT_OPTIONS_PIRE("display_orientation", + "Display orientation SEI", + display_orientation, "disp_or"), { "rotate", "Set rotation in display orientation SEI (anticlockwise angle in degrees)", OFFSET(rotate), AV_OPT_TYPE_DOUBLE, @@ -857,7 +722,7 @@ const AVBitStreamFilter ff_h264_metadata_bsf = { .priv_data_size = sizeof(H264MetadataContext), .priv_class = &h264_metadata_class, .init = &h264_metadata_init, - .close = &h264_metadata_close, - .filter = &h264_metadata_filter, + .close = &ff_cbs_bsf_close, + .filter = &ff_cbs_bsf_filter, .codec_ids = h264_metadata_codec_ids, }; From patchwork Sun Aug 23 22:33:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 21858 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id A80DD44B129 for ; Mon, 24 Aug 2020 01:35:34 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 80F0E68A5CC; Mon, 24 Aug 2020 01:35:34 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id DF633689AE3 for ; Mon, 24 Aug 2020 01:35:25 +0300 (EEST) Received: by mail-wr1-f68.google.com with SMTP id c15so6828947wrs.11 for ; Sun, 23 Aug 2020 15:35:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=9O8BRxB0SLDnnsGvWHYnlbv8hei4rrwc7GWX3553h/U=; b=gWlwOSMcJgAt9cZ3VZOEN7dTRYzyCmPxqwFQUN5Qrn/7S8pql5CX+sEzjpinBbqgBE 9UhI8CKg9n4KKVlC/a6JK5DK6dyydq4CN3BR666raMCmkUStgjg3/lD3VTH0f9mwmGur 3CiAL5KOZq7WShh2o3Rj4+Rp+NqRfphcn33cQxL4l5pRYZK2vKu9oA4iYWpkUyxXLxpx RCtYL0KQSGrJddOY7BFhaRn8BeGHirEXwzJIWNdWk+U8izPGHBQbks/x25ijQ6ZGS1dV RLBXcXGvXf3+Mf/BFrW3Nb7Zf6x9YQylUKY9mLzqZ2x43LfgF79Er+4d+EvkQPcXW9oV aNmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9O8BRxB0SLDnnsGvWHYnlbv8hei4rrwc7GWX3553h/U=; b=cDrNrpHujhGfVmI9JkPef8+P5fmCxpOc7QMgwUKz2mkqYJwaKecKjMcM5hzD49cvM2 Pugrt60OTHZP0aXonjZL6wYoPJOVqjJxXfgX5b+yT1r84glc79kUig+ku3xienbGEOTa iTc4cYxtyuueQ37UbuGnTejALBLsVnuHSo71Ni3uBkxmVMIsDkf2BJl6fpySUEhbUK9X woG/gQ93azw7dFx7WnSd1/T7iUg8VwZwjzTf4Z0LibkP/khMnZbCuOvRCEqMJTjXUxpa 1IzgxztBsytr+oYvMaFrcTmM5xGifTxvdQqI3Q2wSMtRQtl7tWjnZM9TGsdiyRCp6zMD A2pQ== X-Gm-Message-State: AOAM533pjPKXUq61JR+BwZm+ejPvPI9Bdz8vVsqsCjFf2dWWid3L/zcT BTHsw1gHh9eXSyhLxlIW3qFF8BJFAZRIyQ== X-Google-Smtp-Source: ABdhPJxt4wDc7hW8Uc0tGtDnEFIORC7rBrg47eaJxnYYs9P7V1Y9gLK4njABNI+W6vEaZyWqIc5T7Q== X-Received: by 2002:a5d:42cc:: with SMTP id t12mr3007056wrr.214.1598222124926; Sun, 23 Aug 2020 15:35:24 -0700 (PDT) Received: from localhost.localdomain (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id f10sm11216852wmj.37.2020.08.23.15.35.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2020 15:35:24 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 23 Aug 2020 23:33:05 +0100 Message-Id: <20200823223310.233061-3-sw@jkqxz.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200823223310.233061-1-sw@jkqxz.net> References: <20200823223310.233061-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/8] h265_metadata_bsf: Use common cbs bsf implementation X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/h265_metadata_bsf.c | 191 ++++----------------------------- 1 file changed, 22 insertions(+), 169 deletions(-) diff --git a/libavcodec/h265_metadata_bsf.c b/libavcodec/h265_metadata_bsf.c index 504a75dac2..c3eadee92b 100644 --- a/libavcodec/h265_metadata_bsf.c +++ b/libavcodec/h265_metadata_bsf.c @@ -20,29 +20,19 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_h265.h" #include "hevc.h" #include "h265_profile_level.h" -enum { - PASS, - INSERT, - REMOVE, -}; - enum { LEVEL_UNSET = -2, LEVEL_AUTO = -1, }; typedef struct H265MetadataContext { - const AVClass *class; - - CodedBitstreamContext *input; - CodedBitstreamContext *output; - CodedBitstreamFragment access_unit; + CBSBSFContext common; H265RawAUD aud_nal; @@ -338,89 +328,18 @@ static int h265_metadata_update_sps(AVBSFContext *bsf, return 0; } -static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) -{ - H265MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - uint8_t *side_data; - int side_data_size; - int err, i; - - side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, - &side_data_size); - if (!side_data_size) - return 0; - - err = ff_cbs_read(ctx->input, au, side_data, side_data_size); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n"); - return err; - } - - if (ctx->level == LEVEL_AUTO && !ctx->level_guess) - h265_metadata_guess_level(bsf, au); - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == HEVC_NAL_VPS) { - err = h265_metadata_update_vps(bsf, au->units[i].content); - if (err < 0) - return err; - } - if (au->units[i].type == HEVC_NAL_SPS) { - err = h265_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - return err; - } - } - - err = ff_cbs_write_fragment_data(ctx->output, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n"); - return err; - } - - side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, au->data_size); - if (!side_data) - return AVERROR(ENOMEM); - memcpy(side_data, au->data, au->data_size); - - ff_cbs_fragment_reset(au); - - return 0; -} - -static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) +static int h265_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *au) { H265MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; int err, i; - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = h265_metadata_update_side_data(bsf, pkt); - if (err < 0) - goto fail; - - err = ff_cbs_read_packet(ctx->input, au, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } - - if (au->nb_units == 0) { - av_log(bsf, AV_LOG_ERROR, "No NAL units in packet.\n"); - err = AVERROR_INVALIDDATA; - goto fail; - } - // If an AUD is present, it must be the first NAL unit. if (au->units[0].type == HEVC_NAL_AUD) { - if (ctx->aud == REMOVE) + if (ctx->aud == BSF_ELEMENT_REMOVE) ff_cbs_delete_unit(au, 0); } else { - if (ctx->aud == INSERT) { + if (pkt && ctx->aud == BSF_ELEMENT_INSERT) { H265RawAUD *aud = &ctx->aud_nal; int pic_type = 0, temporal_id = 8, layer_id = 0; @@ -453,7 +372,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) err = ff_cbs_insert_unit_content(au, 0, HEVC_NAL_AUD, aud, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n"); - goto fail; + return err; } } } @@ -465,101 +384,35 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (au->units[i].type == HEVC_NAL_VPS) { err = h265_metadata_update_vps(bsf, au->units[i].content); if (err < 0) - goto fail; + return err; } if (au->units[i].type == HEVC_NAL_SPS) { err = h265_metadata_update_sps(bsf, au->units[i].content); if (err < 0) - goto fail; + return err; } } - err = ff_cbs_write_packet(ctx->output, pkt, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - err = 0; -fail: - ff_cbs_fragment_reset(au); - - if (err < 0) - av_packet_unref(pkt); - - return err; + return 0; } -static int h265_metadata_init(AVBSFContext *bsf) -{ - H265MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - int err, i; - - err = ff_cbs_init(&ctx->input, AV_CODEC_ID_HEVC, bsf); - if (err < 0) - return err; - err = ff_cbs_init(&ctx->output, AV_CODEC_ID_HEVC, bsf); - if (err < 0) - return err; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - if (ctx->level == LEVEL_AUTO) - h265_metadata_guess_level(bsf, au); - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == HEVC_NAL_VPS) { - err = h265_metadata_update_vps(bsf, au->units[i].content); - if (err < 0) - goto fail; - } - if (au->units[i].type == HEVC_NAL_SPS) { - err = h265_metadata_update_sps(bsf, au->units[i].content); - if (err < 0) - goto fail; - } - } - - err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; - } - } - - err = 0; -fail: - ff_cbs_fragment_reset(au); - return err; -} +static const CBSBSFType h265_metadata_type = { + .codec_id = AV_CODEC_ID_HEVC, + .fragment_name = "access unit", + .unit_name = "NAL unit", + .update_fragment = &h265_metadata_update_fragment, +}; -static void h265_metadata_close(AVBSFContext *bsf) +static int h265_metadata_init(AVBSFContext *bsf) { - H265MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(&ctx->access_unit); - ff_cbs_close(&ctx->input); - ff_cbs_close(&ctx->output); + return ff_cbs_bsf_init(bsf, &h265_metadata_type); } #define OFFSET(x) offsetof(H265MetadataContext, x) #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) static const AVOption h265_metadata_options[] = { - { "aud", "Access Unit Delimiter NAL units", - OFFSET(aud), AV_OPT_TYPE_INT, - { .i64 = PASS }, PASS, REMOVE, FLAGS, "aud" }, - { "pass", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = PASS }, .flags = FLAGS, .unit = "aud" }, - { "insert", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = INSERT }, .flags = FLAGS, .unit = "aud" }, - { "remove", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = REMOVE }, .flags = FLAGS, .unit = "aud" }, + BSF_ELEMENT_OPTIONS_PIR("aud", "Access Unit Delimiter NAL units", + aud, "aud"), { "sample_aspect_ratio", "Set sample aspect ratio (table E-1)", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, @@ -650,7 +503,7 @@ const AVBitStreamFilter ff_hevc_metadata_bsf = { .priv_data_size = sizeof(H265MetadataContext), .priv_class = &h265_metadata_class, .init = &h265_metadata_init, - .close = &h265_metadata_close, - .filter = &h265_metadata_filter, + .close = &ff_cbs_bsf_close, + .filter = &ff_cbs_bsf_filter, .codec_ids = h265_metadata_codec_ids, }; From patchwork Sun Aug 23 22:33:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 21859 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 241DF44B129 for ; Mon, 24 Aug 2020 01:35:36 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1030B680632; Mon, 24 Aug 2020 01:35:36 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C3CC968A0EA for ; Mon, 24 Aug 2020 01:35:26 +0300 (EEST) Received: by mail-wr1-f46.google.com with SMTP id d16so6848722wrq.9 for ; Sun, 23 Aug 2020 15:35:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=qEW+AdiULEPX8QQ0OsusX3DLTu0yTwVpkZ9sBsQ1FtU=; b=aX9u6xgUwQCv9GtSayvJEV+8hRYq+2MPh1ZxwCyrHwzb2916obRme/0gFrXqtMBFnq C80whd8jFbO9B8Tx6d2KfrIQV4PoZCXXiunCRCAhRxmSYdxXzuxtZW8DZ+BsZKiTaRsf aIs2EbyKNXw/Ts0KOzt1riMZXroAgBNJGI1ywBivWTeQuEv2HEVMBpLl6WXfgaXhJu65 1hwIs+SwmTOd2AcbMWRU8c8H+AH0cvdCmOKpQcwQqTlQ3fl4ppDzeOOfJqy0Elk2CqqQ V5cFBqtkcwQN0sFDosRf2YooGA+Q1QCtCurYqNKWfq3jw/KEcWhDOTJFvR6g0/MiPGWf m4Sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qEW+AdiULEPX8QQ0OsusX3DLTu0yTwVpkZ9sBsQ1FtU=; b=cE+7gU6vqDfqHxRBBAMbMo8i5YmOZvZbUYo1LPqTj9ySanjYqMBEPOAo6yd8yHu+ak Dt4C86S68oN8QkYrfwO2oML3KWyCRGMdyKFuNFQ+kkGKuAitGV8oPBXjWKeEighMWdqv opIDLRhR+Qt1Lsv20XGUlMHs4bOgOOAI+mPXFEBmBso9LIjUZORs5XbU6WARKoGVJquQ 5HwaB9c5UrNLG2JIQVvcXyNU/yw1PEmxSmhuGxtJtTy3H/7WU1nDGmUTIE1alV2AKs7S Y1vn1sLK1UpPi3sn61XkuTIQz8RjoAMjZDUlKq35jwagJVg+WpOqyEDgUx5pYrwnGMb3 6aXA== X-Gm-Message-State: AOAM5311tZjUrZpJK0I6ULvo/6znL2on2EbH/Wrmm2mYffIaoRpam1Mn PN9AVEh1tmfcscR4ZpzPTrFGX89bFvRwXw== X-Google-Smtp-Source: ABdhPJzAVGuc23TR5UD6Le82W2uWShCmQCBuLwG6IBXCZqKHO3oBRH9gv+tfZzmdkfS//N5/VJ5zfg== X-Received: by 2002:a5d:4210:: with SMTP id n16mr3195246wrq.426.1598222125859; Sun, 23 Aug 2020 15:35:25 -0700 (PDT) Received: from localhost.localdomain (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id f10sm11216852wmj.37.2020.08.23.15.35.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2020 15:35:25 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 23 Aug 2020 23:33:06 +0100 Message-Id: <20200823223310.233061-4-sw@jkqxz.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200823223310.233061-1-sw@jkqxz.net> References: <20200823223310.233061-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 4/8] mpeg2_metadata_bsf: Use common cbs bsf implementation X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This adds support for updating new extradata. --- libavcodec/mpeg2_metadata_bsf.c | 94 +++++---------------------------- 1 file changed, 12 insertions(+), 82 deletions(-) diff --git a/libavcodec/mpeg2_metadata_bsf.c b/libavcodec/mpeg2_metadata_bsf.c index d0048c0e25..367aa1f9f5 100644 --- a/libavcodec/mpeg2_metadata_bsf.c +++ b/libavcodec/mpeg2_metadata_bsf.c @@ -21,16 +21,13 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_mpeg2.h" #include "mpeg12.h" typedef struct MPEG2MetadataContext { - const AVClass *class; - - CodedBitstreamContext *cbc; - CodedBitstreamFragment fragment; + CBSBSFContext common; MPEG2RawExtensionData sequence_display_extension; @@ -48,6 +45,7 @@ typedef struct MPEG2MetadataContext { static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, + AVPacket *pkt, CodedBitstreamFragment *frag) { MPEG2MetadataContext *ctx = bsf->priv_data; @@ -170,49 +168,16 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, return 0; } -static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) -{ - MPEG2MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->fragment; - int err; - - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = ff_cbs_read_packet(ctx->cbc, frag, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } - - err = mpeg2_metadata_update_fragment(bsf, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to update frame fragment.\n"); - goto fail; - } - - err = ff_cbs_write_packet(ctx->cbc, pkt, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - err = 0; -fail: - ff_cbs_fragment_reset(frag); - - if (err < 0) - av_packet_unref(pkt); - - return err; -} +static const CBSBSFType mpeg2_metadata_type = { + .codec_id = AV_CODEC_ID_MPEG2VIDEO, + .fragment_name = "frame", + .unit_name = "start code", + .update_fragment = &mpeg2_metadata_update_fragment, +}; static int mpeg2_metadata_init(AVBSFContext *bsf) { MPEG2MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->fragment; - int err; #define VALIDITY_CHECK(name) do { \ if (!ctx->name) { \ @@ -226,42 +191,7 @@ static int mpeg2_metadata_init(AVBSFContext *bsf) VALIDITY_CHECK(matrix_coefficients); #undef VALIDITY_CHECK - err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_MPEG2VIDEO, bsf); - if (err < 0) - return err; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - err = mpeg2_metadata_update_fragment(bsf, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to update metadata fragment.\n"); - goto fail; - } - - err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; - } - } - - err = 0; -fail: - ff_cbs_fragment_reset(frag); - return err; -} - -static void mpeg2_metadata_close(AVBSFContext *bsf) -{ - MPEG2MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(&ctx->fragment); - ff_cbs_close(&ctx->cbc); + return ff_cbs_bsf_init(bsf, &mpeg2_metadata_type); } #define OFFSET(x) offsetof(MPEG2MetadataContext, x) @@ -307,7 +237,7 @@ const AVBitStreamFilter ff_mpeg2_metadata_bsf = { .priv_data_size = sizeof(MPEG2MetadataContext), .priv_class = &mpeg2_metadata_class, .init = &mpeg2_metadata_init, - .close = &mpeg2_metadata_close, - .filter = &mpeg2_metadata_filter, + .close = &ff_cbs_bsf_close, + .filter = &ff_cbs_bsf_filter, .codec_ids = mpeg2_metadata_codec_ids, }; From patchwork Sun Aug 23 22:33:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 21860 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 5453F44B129 for ; Mon, 24 Aug 2020 01:35:37 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3F0F868A353; Mon, 24 Aug 2020 01:35:37 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C15C7689EA6 for ; Mon, 24 Aug 2020 01:35:27 +0300 (EEST) Received: by mail-wr1-f41.google.com with SMTP id p17so1184760wrj.8 for ; Sun, 23 Aug 2020 15:35:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=npdy+Bc9beRYqcn1kp8bjzI66JfZcYs8HskxinO7xrM=; b=OeJeL7y0WpnuTfhYHj0hInggu1CWTRqshvfDO+uil+fK2YYIRFh74rRSTWvxHhWYzX SUtc9iIlbHj5dlbDAuV3iQcL2Xn+FPno4ozS3C88L3xUNenKo+mmqMe68FUv966ghdyo veaobUK6T8IqD/zJLEPZLzLhF/XBE3p5vRZ5p8+QmHUrN0ESrQs3JCgiQRx/nxTHHiOm M6jYSOUIOXjETLeb4HGh03PtSLO3HO4ig4YJ3BUHUJkBE9UrkhRMpvuV2/DcM+9B6Pwz 8oSkP9nxs1e1MfiekhVHIFCCocIuPTEYwANSvYp2sf0K070XrgB03ydQUJWuhYE4WpJO StOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=npdy+Bc9beRYqcn1kp8bjzI66JfZcYs8HskxinO7xrM=; b=iHE6QsaS0FzOEb0g+RkufYSiVQDpdmhzdL4f8YjyJPnOkvU6J0Wkc6vDeJwloi8gr+ KxJGiYmD2KUVvdPGYeE6IQaHOlArg4ykpdUjUD/luqpf6lQcxalqMKOQBczPmgqotiQP 05P6gtKuI4I08nlG46u/WW3KtRvUhk6xtHNfIB8GgZF5Q7iKz19FwYOxhTsMialeTe5Q YV1MLp8rWAvFDGCYbNX0lr/PfSnJpF0qd2se+KIp+SnOrGGOO/coWIih4oZL/Ozo2Rbl DwKs90BiA1+QUMH2mUIzEDPukUNr+urDI3/U/eAM3rm71sxxbMhCR6FlZM7MIZnSbxKU CAXA== X-Gm-Message-State: AOAM533TjYXlzefOsBZYnn9B6wQ+UH7mlSZ/c7Ya+IzrasCKXZgyOaK7 BH6he5Nx//LlOk0oBXLHfQiuD7Nt4zgkfQ== X-Google-Smtp-Source: ABdhPJyPfrfFsCGLqxWzwxDIhJ1VUftv38/jjLZO/Mv6DiabscU2sNF8spBfmqZYNTODPg21VcPl7Q== X-Received: by 2002:adf:ea0b:: with SMTP id q11mr2266454wrm.285.1598222126862; Sun, 23 Aug 2020 15:35:26 -0700 (PDT) Received: from localhost.localdomain (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id f10sm11216852wmj.37.2020.08.23.15.35.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2020 15:35:26 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 23 Aug 2020 23:33:07 +0100 Message-Id: <20200823223310.233061-5-sw@jkqxz.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200823223310.233061-1-sw@jkqxz.net> References: <20200823223310.233061-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 5/8] vp9_metadata_bsf: Use common cbs bsf implementation X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/vp9_metadata_bsf.c | 61 +++++++++-------------------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/libavcodec/vp9_metadata_bsf.c b/libavcodec/vp9_metadata_bsf.c index 00a5580c4d..1d82a401d5 100644 --- a/libavcodec/vp9_metadata_bsf.c +++ b/libavcodec/vp9_metadata_bsf.c @@ -21,15 +21,12 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_vp9.h" typedef struct VP9MetadataContext { - const AVClass *class; - - CodedBitstreamContext *cbc; - CodedBitstreamFragment fragment; + CBSBSFContext common; int color_space; int color_range; @@ -38,21 +35,11 @@ typedef struct VP9MetadataContext { } VP9MetadataContext; -static int vp9_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) +static int vp9_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *frag) { VP9MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->fragment; - int err, i; - - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = ff_cbs_read_packet(ctx->cbc, frag, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } + int i; for (i = 0; i < frag->nb_units; i++) { VP9RawFrame *frame = frag->units[i].content; @@ -90,35 +77,19 @@ static int vp9_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_packet(ctx->cbc, pkt, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - err = 0; -fail: - ff_cbs_fragment_reset(frag); - - if (err < 0) - av_packet_unref(pkt); - - return err; + return 0; } -static int vp9_metadata_init(AVBSFContext *bsf) -{ - VP9MetadataContext *ctx = bsf->priv_data; - - return ff_cbs_init(&ctx->cbc, AV_CODEC_ID_VP9, bsf); -} +static const CBSBSFType vp9_metadata_type = { + .codec_id = AV_CODEC_ID_VP9, + .fragment_name = "superframe", + .unit_name = "frame", + .update_fragment = &vp9_metadata_update_fragment, +}; -static void vp9_metadata_close(AVBSFContext *bsf) +static int vp9_metadata_init(AVBSFContext *bsf) { - VP9MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(&ctx->fragment); - ff_cbs_close(&ctx->cbc); + return ff_cbs_bsf_init(bsf, &vp9_metadata_type); } #define OFFSET(x) offsetof(VP9MetadataContext, x) @@ -169,7 +140,7 @@ const AVBitStreamFilter ff_vp9_metadata_bsf = { .priv_data_size = sizeof(VP9MetadataContext), .priv_class = &vp9_metadata_class, .init = &vp9_metadata_init, - .close = &vp9_metadata_close, - .filter = &vp9_metadata_filter, + .close = &ff_cbs_bsf_close, + .filter = &ff_cbs_bsf_filter, .codec_ids = vp9_metadata_codec_ids, }; From patchwork Sun Aug 23 22:33:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 21861 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 20EC244B129 for ; Mon, 24 Aug 2020 01:35:38 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0A12F68A8E9; Mon, 24 Aug 2020 01:35:38 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A43F3688084 for ; Mon, 24 Aug 2020 01:35:28 +0300 (EEST) Received: by mail-wm1-f67.google.com with SMTP id c19so4959729wmd.1 for ; Sun, 23 Aug 2020 15:35:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=OmnwwKYsNxl37uqT/4A6GZ1bWpDDA4XOEXvjld669DU=; b=tyI/71ra77H/iLUnAk/TYaBrg4RyyklHa35yIq/BArln5hxdI7nIqYoUA28DEYhGgx SkMKMdwaG3gnd/tZ8D2LePiHd0Lwd9B1WGtOvj9SehAeaYplw2nXutt6p4Cjq68iEyU8 yTZtKRCR10l3dIl1/vZ7hpvsV1sHL4WCo6okZOYu2xk/tPCbmE9H+2Ei39Jc5SsoAUh6 MSgs4yd2LBubKMNRR3banbLygtyiNNoaz8GFz9PG+F0rBNSAiD/WowZCY5eUYJukzO2a 5svwGBEV9LdFiPX+iSNnotpuXvrJq8JRMFyDluePe3Q94oi+4Q9/AiHdtvDrQRdcUplf YNNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OmnwwKYsNxl37uqT/4A6GZ1bWpDDA4XOEXvjld669DU=; b=ISbWbRU+/8Rps+RKpnLJga2Hf2yltWfieE06zGjEFYQxkLC2UGCJpHVGSINN95XNlZ WYRV6WfPqNz5HZWv9RrdxCZjozxItqp3KwObQq9UN1/JCWqUi2NTp50d2fLtJ0bK+PZd XiGbujv1YzLhCArLu2X8Q8Smas7+NFuMGMeAtkQyYi0+OqyPU7tm5GhAGMB8MaZS99Fv M0i4HBaITFOiTqFVpHB0k8MX2MgEG53XZ+tKnZ0RXtjRL0Zm9ShXv1sRjobYgsnAiDsf vV9NmEHBrIcKUINP9ZsXs0jLZduLF+AXdeBCWpVuMQgj2ii68oEM5HhtC5CHeAXi2JAA QEpg== X-Gm-Message-State: AOAM532IwBOdbesKINexC7DiPo4BIk1EtqyEDfXUYiN6PLYxUtOrp3jj +cd6arcAO+rl8AjhUwdOAF5NZE9wOIPhjg== X-Google-Smtp-Source: ABdhPJzn2gVLMSdmSElh3QkW9go/o0XTTzhORrENv0JFZtcA1Dzqnd53ExFJOvUF5QAunDDpjcJ/Sg== X-Received: by 2002:a1c:720d:: with SMTP id n13mr2880262wmc.103.1598222127648; Sun, 23 Aug 2020 15:35:27 -0700 (PDT) Received: from localhost.localdomain (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id f10sm11216852wmj.37.2020.08.23.15.35.26 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2020 15:35:27 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 23 Aug 2020 23:33:08 +0100 Message-Id: <20200823223310.233061-6-sw@jkqxz.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200823223310.233061-1-sw@jkqxz.net> References: <20200823223310.233061-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 6/8] av1_metadata_bsf: Use common cbs bsf implementation X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/av1_metadata_bsf.c | 176 ++++------------------------------ 1 file changed, 21 insertions(+), 155 deletions(-) diff --git a/libavcodec/av1_metadata_bsf.c b/libavcodec/av1_metadata_bsf.c index 3158ba995b..31fd4f0f41 100644 --- a/libavcodec/av1_metadata_bsf.c +++ b/libavcodec/av1_metadata_bsf.c @@ -20,22 +20,12 @@ #include "libavutil/opt.h" #include "bsf.h" -#include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_av1.h" -enum { - PASS, - INSERT, - REMOVE, -}; - typedef struct AV1MetadataContext { - const AVClass *class; - - CodedBitstreamContext *input; - CodedBitstreamContext *output; - CodedBitstreamFragment access_unit; + CBSBSFContext common; int td; @@ -113,91 +103,27 @@ static int av1_metadata_update_sequence_header(AVBSFContext *bsf, return 0; } -static int av1_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) +static int av1_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *frag) { AV1MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->access_unit; - uint8_t *side_data; - int side_data_size; - int err, i; - - side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, - &side_data_size); - if (!side_data_size) - return 0; - - err = ff_cbs_read(ctx->input, frag, side_data, side_data_size); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n"); - return err; - } - - for (i = 0; i < frag->nb_units; i++) { - if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) { - AV1RawOBU *obu = frag->units[i].content; - err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header); - if (err < 0) - return err; - } - } - - err = ff_cbs_write_fragment_data(ctx->output, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n"); - return err; - } - - side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, frag->data_size); - if (!side_data) - return AVERROR(ENOMEM); - memcpy(side_data, frag->data, frag->data_size); - - ff_cbs_fragment_reset(frag); - - return 0; -} - -static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) -{ - AV1MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->access_unit; AV1RawOBU td, *obu; int err, i; - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = av1_metadata_update_side_data(bsf, pkt); - if (err < 0) - goto fail; - - err = ff_cbs_read_packet(ctx->input, frag, pkt); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); - goto fail; - } - - if (frag->nb_units == 0) { - av_log(bsf, AV_LOG_ERROR, "No OBU in packet.\n"); - err = AVERROR_INVALIDDATA; - goto fail; - } - for (i = 0; i < frag->nb_units; i++) { if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) { obu = frag->units[i].content; err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header); if (err < 0) - goto fail; + return err; } } // If a Temporal Delimiter is present, it must be the first OBU. if (frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) { - if (ctx->td == REMOVE) + if (ctx->td == BSF_ELEMENT_REMOVE) ff_cbs_delete_unit(frag, 0); - } else if (ctx->td == INSERT) { + } else if (pkt && ctx->td == BSF_ELEMENT_INSERT) { td = (AV1RawOBU) { .header.obu_type = AV1_OBU_TEMPORAL_DELIMITER, }; @@ -206,7 +132,7 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) &td, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to insert Temporal Delimiter.\n"); - goto fail; + return err; } } @@ -217,86 +143,26 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_packet(ctx->output, pkt, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); - goto fail; - } - - err = 0; -fail: - ff_cbs_fragment_reset(frag); - - if (err < 0) - av_packet_unref(pkt); - - return err; + return 0; } -static int av1_metadata_init(AVBSFContext *bsf) -{ - AV1MetadataContext *ctx = bsf->priv_data; - CodedBitstreamFragment *frag = &ctx->access_unit; - AV1RawOBU *obu; - int err, i; - - err = ff_cbs_init(&ctx->input, AV_CODEC_ID_AV1, bsf); - if (err < 0) - return err; - err = ff_cbs_init(&ctx->output, AV_CODEC_ID_AV1, bsf); - if (err < 0) - return err; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->input, frag, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - for (i = 0; i < frag->nb_units; i++) { - if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) { - obu = frag->units[i].content; - err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header); - if (err < 0) - goto fail; - } - } - - err = ff_cbs_write_extradata(ctx->output, bsf->par_out, frag); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; - } - } - - err = 0; -fail: - ff_cbs_fragment_reset(frag); - return err; -} +static const CBSBSFType av1_metadata_type = { + .codec_id = AV_CODEC_ID_AV1, + .fragment_name = "temporal unit", + .unit_name = "OBU", + .update_fragment = &av1_metadata_update_fragment, +}; -static void av1_metadata_close(AVBSFContext *bsf) +static int av1_metadata_init(AVBSFContext *bsf) { - AV1MetadataContext *ctx = bsf->priv_data; - - ff_cbs_fragment_free(&ctx->access_unit); - ff_cbs_close(&ctx->input); - ff_cbs_close(&ctx->output); + return ff_cbs_bsf_init(bsf, &av1_metadata_type); } #define OFFSET(x) offsetof(AV1MetadataContext, x) #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) static const AVOption av1_metadata_options[] = { - { "td", "Temporal Delimiter OBU", - OFFSET(td), AV_OPT_TYPE_INT, - { .i64 = PASS }, PASS, REMOVE, FLAGS, "td" }, - { "pass", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = PASS }, .flags = FLAGS, .unit = "td" }, - { "insert", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = INSERT }, .flags = FLAGS, .unit = "td" }, - { "remove", NULL, 0, AV_OPT_TYPE_CONST, - { .i64 = REMOVE }, .flags = FLAGS, .unit = "td" }, + BSF_ELEMENT_OPTIONS_PIR("td", "Temporal Delimiter OBU", + td, "td"), { "color_primaries", "Set color primaries (section 6.4.2)", OFFSET(color_primaries), AV_OPT_TYPE_INT, @@ -356,7 +222,7 @@ const AVBitStreamFilter ff_av1_metadata_bsf = { .priv_data_size = sizeof(AV1MetadataContext), .priv_class = &av1_metadata_class, .init = &av1_metadata_init, - .close = &av1_metadata_close, - .filter = &av1_metadata_filter, + .close = &ff_cbs_bsf_close, + .filter = &ff_cbs_bsf_filter, .codec_ids = av1_metadata_codec_ids, }; From patchwork Sun Aug 23 22:33:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 21862 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 5557144B129 for ; Mon, 24 Aug 2020 01:35:39 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 34C6568A584; Mon, 24 Aug 2020 01:35:39 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 69D71689CFA for ; Mon, 24 Aug 2020 01:35:29 +0300 (EEST) Received: by mail-wm1-f67.google.com with SMTP id k20so6492477wmi.5 for ; Sun, 23 Aug 2020 15:35:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=NQvh0kci7BDmK3Jfb2DZVzMh9N5f8FVMjGA7aYorYdo=; b=DrclqBjGJ4OTTIFuJzXZA79uhB7Wf1JIMl5OBVznPo0Ls73L7fRrKvOD4hhRrX4g/Z vSqOLOdxn72BedxFLNc2Kx+HdewKDRv899sb5tAEHGNWtPXiI4vYvlsCZ3qPYUqY+ES5 TOb3YyCJu+7r5/VqtOReRMVPf8b+e8UyU5XPl8SHyenl+t/eZ1fERc4izzSbKNODRcbh DgInID4KSlj50vlBpyxAQx/r4DlXCqgJXNPGec+HuhfIDVj9LfJ1nunODitEkJ3mEzdS T4ePldgDSqAX7bdps6HgwvvoLsgPHw7+1t4oYMzs80Go40E+DfO6W155LOhtQ/7IwMP3 tl2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NQvh0kci7BDmK3Jfb2DZVzMh9N5f8FVMjGA7aYorYdo=; b=kcP/+QS26BFD4q6kcoYu//j5bi0PZReZMKJmhHpDNmsl7Hc5HJNwHNbLGmQaT+PRZX 5V0TaR62tgwuwBeDrXBkKVJZGFRHuoskQtoHSY4xoVFbvgRgmT+twdpgB8jCGSnp/BYB CblR8ICkHBASBQKlVa7KoGJGhSGoRqSSWqeFRmyAAJOEN1xEr7izG3owBa3om7gaF8th YwkndJXSeRpFXEf5FGhhPeA6rglHEkWOg98YwQrNMjqXQ2HzIwuMy6Pvgw5C/SlvOVk5 OILKBO4d2Cj5e+9UvRioPQsoEctF+RJjcjj34/K/suSNACaYlQDWHdUowshmZGHmE0tm csZQ== X-Gm-Message-State: AOAM533VV/bwC02qVEFpfUtC1mfOgQb6l5thckPpZYBVg6rbntL+uK+2 AKrdNwCotQAeKpsYKmUvvsTSdMST16TZpw== X-Google-Smtp-Source: ABdhPJxhdcS/tcBXmagFjRH3tFmnY1y6RP57p3W3XfbHuLrbvFWom8t6KFO7Hs2XK8MBXI/BNVfyFw== X-Received: by 2002:a7b:cf29:: with SMTP id m9mr2877397wmg.88.1598222128560; Sun, 23 Aug 2020 15:35:28 -0700 (PDT) Received: from localhost.localdomain (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id f10sm11216852wmj.37.2020.08.23.15.35.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2020 15:35:27 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 23 Aug 2020 23:33:09 +0100 Message-Id: <20200823223310.233061-7-sw@jkqxz.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200823223310.233061-1-sw@jkqxz.net> References: <20200823223310.233061-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 7/8] h264_redundant_pps_bsf: Use common cbs bsf implementation X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/h264_redundant_pps_bsf.c | 99 ++++++----------------------- 1 file changed, 21 insertions(+), 78 deletions(-) diff --git a/libavcodec/h264_redundant_pps_bsf.c b/libavcodec/h264_redundant_pps_bsf.c index cf41abe96c..fb91227eec 100644 --- a/libavcodec/h264_redundant_pps_bsf.c +++ b/libavcodec/h264_redundant_pps_bsf.c @@ -24,15 +24,13 @@ #include "bsf.h" #include "bsf_internal.h" #include "cbs.h" +#include "cbs_bsf.h" #include "cbs_h264.h" #include "h264.h" typedef struct H264RedundantPPSContext { - CodedBitstreamContext *input; - CodedBitstreamContext *output; - - CodedBitstreamFragment access_unit; + CBSBSFContext common; int global_pic_init_qp; int current_pic_init_qp; @@ -49,7 +47,7 @@ static int h264_redundant_pps_fixup_pps(H264RedundantPPSContext *ctx, // The changes we are about to perform affect the parsing process, // so we must make sure that the PPS is writable, otherwise the // parsing of future slices will be incorrect and even raise errors. - err = ff_cbs_make_unit_writable(ctx->input, unit); + err = ff_cbs_make_unit_writable(ctx->common.input, unit); if (err < 0) return err; pps = unit->content; @@ -78,21 +76,14 @@ static int h264_redundant_pps_fixup_slice(H264RedundantPPSContext *ctx, return 0; } -static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt) +static int h264_redundant_pps_update_fragment(AVBSFContext *bsf, + AVPacket *pkt, + CodedBitstreamFragment *au) { H264RedundantPPSContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; int au_has_sps; int err, i; - err = ff_bsf_get_packet_ref(bsf, pkt); - if (err < 0) - return err; - - err = ff_cbs_read_packet(ctx->input, au, pkt); - if (err < 0) - goto fail; - au_has_sps = 0; for (i = 0; i < au->nb_units; i++) { CodedBitstreamUnit *nal = &au->units[i]; @@ -102,7 +93,7 @@ static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt) if (nal->type == H264_NAL_PPS) { err = h264_redundant_pps_fixup_pps(ctx, nal); if (err < 0) - goto fail; + return err; if (!au_has_sps) { av_log(bsf, AV_LOG_VERBOSE, "Deleting redundant PPS " "at %"PRId64".\n", pkt->pts); @@ -118,62 +109,7 @@ static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_packet(ctx->output, pkt, au); - if (err < 0) - goto fail; - - err = 0; -fail: - ff_cbs_fragment_reset(au); - if (err < 0) - av_packet_unref(pkt); - - return err; -} - -static int h264_redundant_pps_init(AVBSFContext *bsf) -{ - H264RedundantPPSContext *ctx = bsf->priv_data; - CodedBitstreamFragment *au = &ctx->access_unit; - int err, i; - - err = ff_cbs_init(&ctx->input, AV_CODEC_ID_H264, bsf); - if (err < 0) - return err; - - err = ff_cbs_init(&ctx->output, AV_CODEC_ID_H264, bsf); - if (err < 0) - return err; - - ctx->global_pic_init_qp = 26; - - if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); - goto fail; - } - - for (i = 0; i < au->nb_units; i++) { - if (au->units[i].type == H264_NAL_PPS) { - err = h264_redundant_pps_fixup_pps(ctx, &au->units[i]); - if (err < 0) - goto fail; - } - } - - ctx->extradata_pic_init_qp = ctx->current_pic_init_qp; - err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); - goto fail; - } - } - - err = 0; -fail: - ff_cbs_fragment_reset(au); - return err; + return 0; } static void h264_redundant_pps_flush(AVBSFContext *bsf) @@ -182,13 +118,20 @@ static void h264_redundant_pps_flush(AVBSFContext *bsf) ctx->current_pic_init_qp = ctx->extradata_pic_init_qp; } -static void h264_redundant_pps_close(AVBSFContext *bsf) +static const CBSBSFType h264_redundant_pps_type = { + .codec_id = AV_CODEC_ID_H264, + .fragment_name = "access unit", + .unit_name = "NAL unit", + .update_fragment = &h264_redundant_pps_update_fragment, +}; + +static int h264_redundant_pps_init(AVBSFContext *bsf) { H264RedundantPPSContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(&ctx->access_unit); - ff_cbs_close(&ctx->input); - ff_cbs_close(&ctx->output); + ctx->global_pic_init_qp = 26; + + return ff_cbs_bsf_init(bsf, &h264_redundant_pps_type); } static const enum AVCodecID h264_redundant_pps_codec_ids[] = { @@ -200,7 +143,7 @@ const AVBitStreamFilter ff_h264_redundant_pps_bsf = { .priv_data_size = sizeof(H264RedundantPPSContext), .init = &h264_redundant_pps_init, .flush = &h264_redundant_pps_flush, - .close = &h264_redundant_pps_close, - .filter = &h264_redundant_pps_filter, + .close = &ff_cbs_bsf_close, + .filter = &ff_cbs_bsf_filter, .codec_ids = h264_redundant_pps_codec_ids, }; From patchwork Sun Aug 23 22:33:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 21863 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 36C2644B129 for ; Mon, 24 Aug 2020 01:35:40 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 225A168AA85; Mon, 24 Aug 2020 01:35:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id DE42468044F for ; Mon, 24 Aug 2020 01:35:30 +0300 (EEST) Received: by mail-wm1-f68.google.com with SMTP id s20so1577209wmj.1 for ; Sun, 23 Aug 2020 15:35:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=3rJqc7kGbhrKHM/SU6DakDJWbVBXOarr/SZ8jcdrPzo=; b=T6hcjzQQSXTdvwziZcwy2/Lx7pZ1mIcOnmQjAcBFE2S+BU8lZdDz+Hs1gfJCLy6bFn oN0PiWirq8ns5TjuBaH94lt8b6Ipe3Rb8Cx6cswwNDCMcoIJ2r+hovAv/jFkUn10s+Hd DbqoK/jn09nrzLKSRF3YF9ty5SROpvO6XIi25BT5PvPNnmTUygOYJZcT1MFsOkBquW2s AfotXhLvhZ+Ktq01bj0PMEt+ksR88Zz5lBHB6HbNORwvQAH3BudUh3PHXWF3q3DYUBSP FpniWny62ZdFQUG9uh6qKBQ7ijU26YdO8+JixH2pvwuOvIvmmbx6t1zN8WJ2O54A8+Zj Kv5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3rJqc7kGbhrKHM/SU6DakDJWbVBXOarr/SZ8jcdrPzo=; b=AqhyiKfyLn2LOfPszFsJxV0AsbFEOlI4YA8bG8RtVXjhT4PHE/z4cfgfLSmmChyWbx m6yxVF73XZGZYNx8h/1VZs4c9lrl4ngME7YEiVTWbkEua2q3EoPbwUzQ4gyK/ZGx2+nV y0Rbf6j+gAl5gLuPxYiFjpB0+RxyaSSx7qyV/lFg8OcJkqVs4hUMwXI3jLBEuj7pZgcR EvhhhPAy2I5wCI2TDfk61zZlMUuhs121sUmyjd5xy2j8Cy2K76phz4eOHz2LAy4j0j6E Sdcu8/ant72sE4srSv9cbTvaSN9JwpJpVfI32QqpQv628qAePpfua93bmTGmGdzgLwiV 4BIg== X-Gm-Message-State: AOAM531tCmszoHnozMKe5VMtbEaMzaMgDbrB7t61FtprsVC8L9ePCgUJ zpFuyWH/QKjk4/LbsYQ8ivz+vbjZU1MOgA== X-Google-Smtp-Source: ABdhPJxkwbBdTlxQrtzsvTQBHi2Dud+/fWHJITKTNn/gNsdqf2zzLbh2Sc9yml/TgXBanxX5CSTBxQ== X-Received: by 2002:a7b:c5c1:: with SMTP id n1mr2764933wmk.125.1598222129661; Sun, 23 Aug 2020 15:35:29 -0700 (PDT) Received: from localhost.localdomain (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id f10sm11216852wmj.37.2020.08.23.15.35.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Aug 2020 15:35:28 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 23 Aug 2020 23:33:10 +0100 Message-Id: <20200823223310.233061-8-sw@jkqxz.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200823223310.233061-1-sw@jkqxz.net> References: <20200823223310.233061-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 8/8] RFC: editing HDR properties in H.265 metadata BSF X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- Setting HDR properties is a useful feature, but it's very unclear what we want it to actually look like to the user. Not all encoders and decoders support it, so it's essentially required that the implementation happen at the bitstream filter level so that we can support all codecs in the same way. This is several patches mashed together to invite comments on a bitstream filter approach. It modifies hevc_metadata to allow inserting both explicit values as well as ones derived from existing side-data. Example: hevc_metadata=mastering_display_colour_volume=insert:x265_master_display=G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1):content_light_level_information=insert:x265_max_cll=1000,400 * I don't see a nice answer as to what form explicit values should take. This copies the options from x265 precisely and gives them names including "x265_" to indicate that, but it seems like we should allow a more flexible format (in particular: the units are from the H.265 SEI message and are therefore a bit silly for humans, and also you might want to edit /only some/ of the values from the source). Maybe each value could be specified as a separate argument, but given the interdependencies between them that would somewhat more complex to deal with. It would be helpful to be able to set multiple values together as well, like colour_primaries=BT709 or white_point=D65 rather than setting each coordinate individually. Obviously if we go this single-codec route then it would need to be duplicated (possibly with some parts suitably abstracted) in other codecs - H.264 and AV1 both want it too. To avoid this, rather than passing explicit values to codec-specific filters we could instead have a generic bitstream filter which only edits side-data. Then the codec-specific filters would insert side-data themselves. Comibining those, an exmaple to edit some fields would be something like: hevc_metadata=mastering_display_colour_volume=extract,side_data=max_luminance=9100:min_luminance=300,hevc_metadata=mastering_display_colour_volume=insert Or maybe some combination of those, so you have both the generic filter and the codec-specific filters accept the value options too? Thoughts invited on any of this. Thanks, - Mark * This doesn't actually work on the ffmpeg command-line because there is no way to escape the commas in the -bsf:v argument. Splicing in the code works, but that should probably be fixed. libavcodec/cbs_h2645.c | 4 +- libavcodec/cbs_h265.c | 190 +++++++++++++++++++++++++ libavcodec/cbs_h265.h | 50 +++++++ libavcodec/h265_metadata_bsf.c | 248 ++++++++++++++++++++++++++++++++- 4 files changed, 489 insertions(+), 3 deletions(-) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 1677731db9..b9f219cdf7 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1386,7 +1386,7 @@ static const CodedBitstreamUnitTypeDescriptor cbs_h264_unit_types[] = { CBS_UNIT_TYPE_END_OF_LIST }; -static void cbs_h265_free_sei_payload(H265RawSEIPayload *payload) +void ff_cbs_h265_free_sei_payload(H265RawSEIPayload *payload) { switch (payload->payload_type) { case HEVC_SEI_TYPE_BUFFERING_PERIOD: @@ -1420,7 +1420,7 @@ static void cbs_h265_free_sei(void *opaque, uint8_t *content) H265RawSEI *sei = (H265RawSEI*)content; int i; for (i = 0; i < sei->payload_count; i++) - cbs_h265_free_sei_payload(&sei->payload[i]); + ff_cbs_h265_free_sei_payload(&sei->payload[i]); av_freep(&content); } diff --git a/libavcodec/cbs_h265.c b/libavcodec/cbs_h265.c index f6226d8743..3d2c99af03 100644 --- a/libavcodec/cbs_h265.c +++ b/libavcodec/cbs_h265.c @@ -20,8 +20,145 @@ #include "libavutil/mastering_display_metadata.h" #include "cbs_h265.h" +#include "cbs_internal.h" +int ff_cbs_h265_find_sei_message(CodedBitstreamFragment *au, + int type, + H265RawSEIPayload **message) +{ + H265RawSEI *sei; + int i, j, found_message; + + found_message = !*message; + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type != HEVC_NAL_SEI_PREFIX && + au->units[i].type != HEVC_NAL_SEI_SUFFIX) + continue; + sei = au->units[i].content; + + for (j = 0; j < sei->payload_count; j++) { + if (sei->payload[j].payload_type == type) { + if (found_message) { + *message = &sei->payload[j]; + return 0; + } else { + if (&sei->payload[j] == *message) + found_message = 1; + } + } + } + } + + *message = NULL; + return AVERROR(ENOENT); +} + +int ff_cbs_h265_add_sei_message(CodedBitstreamFragment *au, + H265RawSEIPayload *payload, int prefix) +{ + H265RawSEI *sei = NULL; + int sei_type = prefix ? HEVC_NAL_SEI_PREFIX + : HEVC_NAL_SEI_SUFFIX; + int err, i; + + // Find an existing SEI NAL unit to add to. + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type == sei_type) { + sei = au->units[i].content; + if (sei->payload_count < H265_MAX_SEI_PAYLOADS) + break; + + sei = NULL; + } + } + + if (!sei) { + // Need to make a new SEI NAL unit. Insert it before the VCL if + // prefix, or after if suffix. + CodedBitstreamUnit *unit; + int position = -1; + + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type <= HEVC_NAL_RSV_VCL31) { + if (prefix) { + position = i; + break; + } else { + position = i + 1; + } + } + } + + err = ff_cbs_insert_unit(au, position); + if (err < 0) + goto fail; + unit = &au->units[position]; + unit->type = sei_type; + + // Needs a context for the type information but we don't have + // one, so forge one containing only the type information. + err = ff_cbs_alloc_unit_content2(&(CodedBitstreamContext) { + .codec = &ff_cbs_type_h265 }, unit); + if (err < 0) { + ff_cbs_delete_unit(au, i); + goto fail; + } + sei = unit->content; + + *sei = (H265RawSEI) { + .nal_unit_header = { + .nal_unit_type = sei_type, + }, + }; + } + + memcpy(&sei->payload[sei->payload_count], payload, sizeof(*payload)); + ++sei->payload_count; + + return 0; +fail: + ff_cbs_h265_free_sei_payload(payload); + return err; +} + +void ff_cbs_h265_delete_sei_message(CodedBitstreamFragment *au, + H265RawSEIPayload *message) +{ + H265RawSEI *sei; + int i, j, position; + + position = -1; + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type != HEVC_NAL_SEI_PREFIX && + au->units[i].type != HEVC_NAL_SEI_SUFFIX) + continue; + sei = au->units[i].content; + for (j = 0; j < sei->payload_count; j++) { + if (&sei->payload[j] == message) { + position = j; + break; + } + } + if (position >= 0) + break; + } + // Message not found in this access unit. + av_assert0(position >= 0); + + if (position == 0 && sei->payload_count == 1) { + // Deleting NAL unit entirely. + ff_cbs_delete_unit(au, i); + } else { + ff_cbs_h265_free_sei_payload(&sei->payload[position]); + + --sei->payload_count; + memmove(sei->payload + position, + sei->payload + position + 1, + (sei->payload_count - position) * sizeof(*sei->payload)); + } +} + static uint32_t rescale_clip(AVRational value, uint32_t scale, uint32_t min, uint32_t max) { @@ -93,3 +230,56 @@ void ff_cbs_h265_fill_sei_content_light_level(H265RawSEIContentLightLevelInfo *c cll->max_content_light_level = av_clip_uintp2(clm->MaxCLL, 16); cll->max_pic_average_light_level = av_clip_uintp2(clm->MaxFALL, 16); } + + +void ff_cbs_h265_extract_sei_mastering_display(AVMasteringDisplayMetadata *mdm, + const H265RawSEIMasteringDisplayColourVolume *mdcv) +{ +#define IN_RANGE(v, min, max) ((v) >= (min) && (v) <= (max)) +#define IS_VALID_COORD(x, y) (IN_RANGE(x, 5, 37000) && IN_RANGE(y, 5, 42000)) + int valid_chromaticity = 1; + for (int a = 0; a < 3; a++) { + if (!IS_VALID_COORD(mdcv->display_primaries_x[a], + mdcv->display_primaries_y[a])) + valid_chromaticity = 0; + } + if (!IS_VALID_COORD(mdcv->white_point_x, mdcv->white_point_y)) + valid_chromaticity = 0; + + memset(mdm, 0, sizeof(*mdm)); + + if (valid_chromaticity) { + for (int a = 0; a < 3; a++) { + // SEI message in GBR order, but metadata structure in RGB order. + static const uint8_t mapping[] = { 2, 0, 1 }; + int b = mapping[a]; + + mdm->display_primaries[a][0] = + av_make_q(mdcv->display_primaries_x[b], 50000); + mdm->display_primaries[a][1] = + av_make_q(mdcv->display_primaries_y[b], 50000); + } + + mdm->white_point[0] = av_make_q(mdcv->white_point_x, 50000); + mdm->white_point[1] = av_make_q(mdcv->white_point_y, 50000); + + mdm->has_primaries = 1; + } + + if (IN_RANGE(mdcv->min_display_mastering_luminance, 1, 50000) && + IN_RANGE(mdcv->max_display_mastering_luminance, 50000, 100000000)) { + mdm->min_luminance = av_make_q(mdcv->min_display_mastering_luminance, 10000); + mdm->max_luminance = av_make_q(mdcv->max_display_mastering_luminance, 10000); + + mdm->has_luminance = 1; + } +#undef IN_RANGE +#undef IS_VALID_COORD +} + +void ff_cbs_h265_extract_sei_content_light_level(AVContentLightMetadata *clm, + const H265RawSEIContentLightLevelInfo *cll) +{ + clm->MaxCLL = cll->max_content_light_level; + clm->MaxFALL = cll->max_pic_average_light_level; +} diff --git a/libavcodec/cbs_h265.h b/libavcodec/cbs_h265.h index 999353f607..eb6d4b0702 100644 --- a/libavcodec/cbs_h265.h +++ b/libavcodec/cbs_h265.h @@ -22,6 +22,7 @@ #include #include +#include "cbs.h" #include "cbs_h2645.h" #include "hevc.h" @@ -747,6 +748,42 @@ typedef struct CodedBitstreamH265Context { } CodedBitstreamH265Context; +/** + * Free an SEI payload structure. + */ +void ff_cbs_h265_free_sei_payload(H265RawSEIPayload *payload); + +/** + * Find an SEI message of the given type within an access unit. + * + * If message is already set, only looks after it - this can be used to + * iterate over all messages of a given type. + */ +int ff_cbs_h265_find_sei_message(CodedBitstreamFragment *au, + int type, + H265RawSEIPayload **message); + +/** + * Add an SEI message to an access unit. + * + * Adds at the end of an existing SEI NAL unit of the appropriate type + * (PREFIX_SEI if prefix is set, otherwise SUFFIX_SEI), otherwise creates + * a new NAL unit to contain the message. + */ +int ff_cbs_h265_add_sei_message(CodedBitstreamFragment *au, + H265RawSEIPayload *payload, + int prefix); + +/** + * Delete an SEI message from an access unit. + * + * Deletes the given message from the NAL Unit containing it. If it is + * the last message in the NAL unit, also deletes it from the access unit. + */ +void ff_cbs_h265_delete_sei_message(CodedBitstreamFragment *au, + H265RawSEIPayload *message); + + struct AVMasteringDisplayMetadata; struct AVContentLightMetadata; @@ -764,5 +801,18 @@ void ff_cbs_h265_fill_sei_mastering_display(H265RawSEIMasteringDisplayColourVolu void ff_cbs_h265_fill_sei_content_light_level(H265RawSEIContentLightLevelInfo *cll, const struct AVContentLightMetadata *clm); +/** + * Fill an AVMasteringDisplayMetadata side-data structure with values + * derived from the SEI Mastering Display Colour Volume structure. + */ +void ff_cbs_h265_extract_sei_mastering_display(struct AVMasteringDisplayMetadata *mdm, + const H265RawSEIMasteringDisplayColourVolume *mdcv); + +/** + * Fill an AVContentLightMetadata structure with values derived from + * the SEI Content Light Level Information structure. + */ +void ff_cbs_h265_extract_sei_content_light_level(struct AVContentLightMetadata *clm, + const H265RawSEIContentLightLevelInfo *cll); #endif /* AVCODEC_CBS_H265_H */ diff --git a/libavcodec/h265_metadata_bsf.c b/libavcodec/h265_metadata_bsf.c index c3eadee92b..8e18e88a3d 100644 --- a/libavcodec/h265_metadata_bsf.c +++ b/libavcodec/h265_metadata_bsf.c @@ -17,6 +17,7 @@ */ #include "libavutil/common.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/opt.h" #include "bsf.h" @@ -24,6 +25,7 @@ #include "cbs_bsf.h" #include "cbs_h265.h" #include "hevc.h" +#include "hevc_sei.h" #include "h265_profile_level.h" enum { @@ -34,6 +36,8 @@ enum { typedef struct H265MetadataContext { CBSBSFContext common; + int done_first_au; + H265RawAUD aud_nal; int aud; @@ -60,6 +64,18 @@ typedef struct H265MetadataContext { int level; int level_guess; int level_warned; + + int mdcv_sei; + int mdcv_multiple_warned; + AVMasteringDisplayMetadata mdcv_side_data; + H265RawSEIMasteringDisplayColourVolume mdcv_x265; + const char *mdcv_x265_str; + + int cll_sei; + int cll_multiple_warned; + AVContentLightMetadata cll_side_data; + H265RawSEIContentLightLevelInfo cll_x265; + const char *cll_x265_str; } H265MetadataContext; @@ -328,11 +344,157 @@ static int h265_metadata_update_sps(AVBSFContext *bsf, return 0; } +static int h265_metadata_update_mdcv(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *au, + int seek_point) +{ + H265MetadataContext *ctx = bsf->priv_data; + H265RawSEIPayload *message = NULL; + AVMasteringDisplayMetadata *mdm; + uint8_t *data; + int err, first; + + first = 1; + while (1) { + err = ff_cbs_h265_find_sei_message(au, + HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO, &message); + if (err < 0) + break; + + if (ctx->mdcv_sei == BSF_ELEMENT_REMOVE || + ctx->mdcv_sei == BSF_ELEMENT_INSERT) { + ff_cbs_h265_delete_sei_message(au, message); + + } else if (ctx->mdcv_sei == BSF_ELEMENT_EXTRACT && pkt) { + if (first) { + data = av_packet_new_side_data(pkt, + AV_PKT_DATA_MASTERING_DISPLAY_METADATA, sizeof(*mdm)); + if (!data) + return AVERROR(ENOMEM); + + mdm = (AVMasteringDisplayMetadata*)data; + ff_cbs_h265_extract_sei_mastering_display(mdm, + &message->payload.mastering_display); + } else if (!ctx->mdcv_multiple_warned) { + av_log(bsf, AV_LOG_WARNING, "Multiple MDCV SEI " + "messages found in access unit: " + "all but the first will be ignored.\n"); + ctx->mdcv_multiple_warned = 1; + } + } + + first = 0; + } + + if (seek_point && ctx->mdcv_sei == BSF_ELEMENT_INSERT) { + H265RawSEIPayload payload = { + .payload_type = HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO, + }; + H265RawSEIMasteringDisplayColourVolume *mdcv = + &payload.payload.mastering_display; + int size; + + data = av_packet_get_side_data(pkt, + AV_PKT_DATA_MASTERING_DISPLAY_METADATA, &size); + if (data) { + av_assert0(size >= sizeof(*mdm)); + mdm = (AVMasteringDisplayMetadata*)data; + ctx->mdcv_side_data = *mdm; + } + + if (ctx->mdcv_x265_str) { + *mdcv = ctx->mdcv_x265; + } else { + ff_cbs_h265_fill_sei_mastering_display(mdcv, + &ctx->mdcv_side_data); + } + + err = ff_cbs_h265_add_sei_message(au, &payload, 1); + if (err < 0) + return err; + } + + return 0; +} + +static int h265_metadata_update_cll(AVBSFContext *bsf, AVPacket *pkt, + CodedBitstreamFragment *au, + int seek_point) +{ + H265MetadataContext *ctx = bsf->priv_data; + H265RawSEIPayload *message = NULL; + AVContentLightMetadata *clm; + uint8_t *data; + int err, first; + + first = 1; + while (1) { + err = ff_cbs_h265_find_sei_message(au, + HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO, &message); + if (err < 0) + break; + + if (ctx->cll_sei == BSF_ELEMENT_REMOVE || + ctx->cll_sei == BSF_ELEMENT_INSERT) { + ff_cbs_h265_delete_sei_message(au, message); + + } else if (ctx->cll_sei == BSF_ELEMENT_EXTRACT && pkt) { + if (first) { + data = av_packet_new_side_data(pkt, + AV_PKT_DATA_CONTENT_LIGHT_LEVEL, sizeof(*clm)); + if (!data) + return AVERROR(ENOMEM); + + clm = (AVContentLightMetadata*)data; + ff_cbs_h265_extract_sei_content_light_level(clm, + &message->payload.content_light_level); + } else if (!ctx->cll_multiple_warned) { + av_log(bsf, AV_LOG_WARNING, "Multiple CLL SEI " + "messages found in access unit: " + "all but the first will be ignored.\n"); + ctx->cll_multiple_warned = 1; + } + } + + first = 0; + } + + if (seek_point && ctx->cll_sei == BSF_ELEMENT_INSERT) { + H265RawSEIPayload payload = { + .payload_type = HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO, + }; + H265RawSEIContentLightLevelInfo *cll = + &payload.payload.content_light_level; + int size; + + data = av_packet_get_side_data(pkt, + AV_PKT_DATA_MASTERING_DISPLAY_METADATA, &size); + if (data) { + av_assert0(size >= sizeof(*clm)); + clm = (AVContentLightMetadata*)data; + ctx->cll_side_data = *clm; + } + + if (ctx->cll_x265_str) { + *cll = ctx->cll_x265; + } else { + ff_cbs_h265_fill_sei_content_light_level(cll, + &ctx->cll_side_data); + } + + err = ff_cbs_h265_add_sei_message(au, &payload, 1); + if (err < 0) + return err; + } + + return 0; +} + static int h265_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, CodedBitstreamFragment *au) { H265MetadataContext *ctx = bsf->priv_data; - int err, i; + int err, i, has_vps, has_sps, seek_point; // If an AUD is present, it must be the first NAL unit. if (au->units[0].type == HEVC_NAL_AUD) { @@ -380,19 +542,48 @@ static int h265_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, if (ctx->level == LEVEL_AUTO && !ctx->level_guess) h265_metadata_guess_level(bsf, au); + has_vps = has_sps = 0; for (i = 0; i < au->nb_units; i++) { if (au->units[i].type == HEVC_NAL_VPS) { + has_vps = 1; err = h265_metadata_update_vps(bsf, au->units[i].content); if (err < 0) return err; } if (au->units[i].type == HEVC_NAL_SPS) { + has_sps = 1; err = h265_metadata_update_sps(bsf, au->units[i].content); if (err < 0) return err; } } + if (pkt) { + // The current packet should be treated as a seek point for + // metadata insertion if any of: + // - It is the first packet in the stream. + // - It contains a VPS or SPS, indicating that a sequence might + // start here. + // - It is marked as containing a key frame. + seek_point = !ctx->done_first_au || has_vps || has_sps || + (pkt->flags & AV_PKT_FLAG_KEY); + } else { + seek_point = 0; + } + + if (ctx->mdcv_sei != BSF_ELEMENT_PASS) { + err = h265_metadata_update_mdcv(bsf, pkt, au, seek_point); + if (err < 0) + return err; + } + if (ctx->cll_sei != BSF_ELEMENT_PASS) { + err = h265_metadata_update_cll(bsf, pkt, au, seek_point); + if (err < 0) + return err; + } + + if (pkt) + ctx->done_first_au = 1; return 0; } @@ -405,6 +596,44 @@ static const CBSBSFType h265_metadata_type = { static int h265_metadata_init(AVBSFContext *bsf) { + H265MetadataContext *ctx = bsf->priv_data; + int ret; + + if (ctx->mdcv_x265_str) { + ret = sscanf(ctx->mdcv_x265_str, + "G(%"SCNu16",%"SCNu16")" + "B(%"SCNu16",%"SCNu16")" + "R(%"SCNu16",%"SCNu16")" + "WP(%"SCNu16",%"SCNu16")" + "L(%"SCNu32",%"SCNu32")", + &ctx->mdcv_x265.display_primaries_x[0], + &ctx->mdcv_x265.display_primaries_y[0], + &ctx->mdcv_x265.display_primaries_x[1], + &ctx->mdcv_x265.display_primaries_y[1], + &ctx->mdcv_x265.display_primaries_x[2], + &ctx->mdcv_x265.display_primaries_y[2], + &ctx->mdcv_x265.white_point_x, + &ctx->mdcv_x265.white_point_y, + &ctx->mdcv_x265.max_display_mastering_luminance, + &ctx->mdcv_x265.min_display_mastering_luminance); + if (ret != 10) { + av_log(bsf, AV_LOG_ERROR, "Failed to parse " + "x265_master_display string: check formatting.\n"); + return AVERROR(EINVAL); + } + } + + if (ctx->cll_x265_str) { + ret = sscanf(ctx->cll_x265_str, "%"SCNu16",%"SCNu16, + &ctx->cll_x265.max_content_light_level, + &ctx->cll_x265.max_pic_average_light_level); + if (ret != 2) { + av_log(bsf, AV_LOG_ERROR, "Failed to parse " + "x265_max_cll string: check formatting.\n"); + return AVERROR(EINVAL); + } + } + return ff_cbs_bsf_init(bsf, &h265_metadata_type); } @@ -484,6 +713,23 @@ static const AVOption h265_metadata_options[] = { { LEVEL("8.5", 255) }, #undef LEVEL + BSF_ELEMENT_OPTIONS_PIRE("mastering_display_colour_volume", + "Mastering display colour volume SEI", + mdcv_sei, "mdcv_sei"), + { "x265_master_display", + "Mastering display colour volume values in x265 format", + OFFSET(mdcv_x265_str), AV_OPT_TYPE_STRING, + { .str = NULL }, .flags = FLAGS }, + + BSF_ELEMENT_OPTIONS_PIRE("content_light_level_information", + "Content light level information SEI", + cll_sei, "cll_sei"), + + { "x265_max_cll", + "Content light level values in x265 format", + OFFSET(cll_x265_str), AV_OPT_TYPE_STRING, + { .str = NULL }, .flags = FLAGS }, + { NULL } };