From patchwork Mon Jan 18 22:44:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 25016 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 D7D1644AAE4 for ; Tue, 19 Jan 2021 00:47:11 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id ACA656880C4; Tue, 19 Jan 2021 00:47:11 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BF2A668027D for ; Tue, 19 Jan 2021 00:47:04 +0200 (EET) Received: by mail-wm1-f44.google.com with SMTP id c124so14901662wma.5 for ; Mon, 18 Jan 2021 14:47:04 -0800 (PST) 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=b4GG2n+nQH68Jpre3WoRNEbnXKuIiC4QQpD13ZHCZ84=; b=QEzMwTvGo14yt2krdMKistUhTcBgYptyQnOpMJ9vINDBO8dsTCDfCnN7fZSM7Hg9p4 Q/VsF/IpzV5x6j25JI38LhYb4HlaGvgPqzP63kOv5yWxX8Xsr1ToryaGDRNJsXPgYymo Zfb3lHfSQWFSYk8gg6kBURGVJkHKKBcEvhRcg34F6s/BpKeG/fNd6rGd+9IBTrrUbuel n0sSJZI2ax/oQ6MPtro3P2vQ3GupcLT13Mm2pgTxsx1eb/5ESLThl88ktXPkXUZXlZ0g w8CtN9Ahdm1FbrQ8mz6ROkqEuaK9YZ7UPwNKz8wjgHvJzH0hIzKKZyOiu4e8HJMXrO35 ojaQ== 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=b4GG2n+nQH68Jpre3WoRNEbnXKuIiC4QQpD13ZHCZ84=; b=VQaewopoa8Y2AZQqyVB5N7NRMiTnW0It52l4JbBo7zliVyfDZHYQULX2m9D+f5S3LW Vv0L46LqOVIEaLPUSH3wqaHuuTZpoNkqmM6JDkUJIwdxx6HHDF+CVQvn44j3nTzIcs/w bFPFyUjCY/UxmR5zVUsvdSdnPRiYHxVU7I0itNqw4MKvJYLoHBt0OdgjdZ94h0jUyYU2 nntuQlNj9DKYw8QrJb5CeNPWS45RWg1FIB2Vmwfd8zxokZJH1IwXjHU9awJSqDziL16M A+0EFA2ngZ/9cF3Xxxg9Idg1OKSyvVUu/spI6QVjujkGDfF64OO9O7jMpUCUQBGsqR1x DGgw== X-Gm-Message-State: AOAM533+ULjr8D3aq4mqeqIAduVqqONGmsZ5Dw6mLkA5NkbMe8KW6vZr tDejljYXu2UtnDlEIUBSWz5qB5+kT49Vxw== X-Google-Smtp-Source: ABdhPJxBk30gwBpDmjqJ8YTmYRSJCa55M5d++vbovKkSKfQ3P47QytksjngKNZB9CsIvmLdnwQf+Kw== X-Received: by 2002:a7b:c5d2:: with SMTP id n18mr1282590wmk.56.1611010023580; Mon, 18 Jan 2021 14:47:03 -0800 (PST) Received: from localhost.localdomain (cpc91226-cmbg18-2-0-cust7.5-4.cable.virginm.net. [82.0.29.8]) by smtp.gmail.com with ESMTPSA id b3sm1525898wme.32.2021.01.18.14.47.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jan 2021 14:47:03 -0800 (PST) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Mon, 18 Jan 2021 22:44:43 +0000 Message-Id: <20210118224455.750030-2-sw@jkqxz.net> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210118224455.750030-1-sw@jkqxz.net> References: <20210118224455.750030-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 01/13] cbs_h2645: Merge SEI messages in common between codecs 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" Make a new template file for common SEI messages - this will also apply to H.266. --- libavcodec/cbs_h264.h | 37 +------ libavcodec/cbs_h2645.c | 24 +++-- libavcodec/cbs_h264_syntax_template.c | 106 +------------------- libavcodec/cbs_h265.h | 45 ++------- libavcodec/cbs_h265_syntax_template.c | 135 ++++---------------------- libavcodec/cbs_sei.h | 60 ++++++++++++ libavcodec/cbs_sei_syntax_template.c | 132 +++++++++++++++++++++++++ libavcodec/h264_metadata_bsf.c | 2 +- libavcodec/vaapi_encode_h264.c | 2 +- libavcodec/vaapi_encode_h265.c | 11 ++- 10 files changed, 250 insertions(+), 304 deletions(-) create mode 100644 libavcodec/cbs_sei.h create mode 100644 libavcodec/cbs_sei_syntax_template.c diff --git a/libavcodec/cbs_h264.h b/libavcodec/cbs_h264.h index a6fe0a6af2..81113f1ad0 100644 --- a/libavcodec/cbs_h264.h +++ b/libavcodec/cbs_h264.h @@ -24,6 +24,7 @@ #include "cbs.h" #include "cbs_h2645.h" +#include "cbs_sei.h" #include "h264.h" @@ -274,21 +275,6 @@ typedef struct H264RawSEIPanScanRect { uint16_t pan_scan_rect_repetition_period; } H264RawSEIPanScanRect; -typedef struct H264RawSEIUserDataRegistered { - uint8_t itu_t_t35_country_code; - uint8_t itu_t_t35_country_code_extension_byte; - uint8_t *data; - AVBufferRef *data_ref; - size_t data_length; -} H264RawSEIUserDataRegistered; - -typedef struct H264RawSEIUserDataUnregistered { - uint8_t uuid_iso_iec_11578[16]; - uint8_t *data; - AVBufferRef *data_ref; - size_t data_length; -} H264RawSEIUserDataUnregistered; - typedef struct H264RawSEIRecoveryPoint { uint16_t recovery_frame_cnt; uint8_t exact_match_flag; @@ -305,19 +291,6 @@ typedef struct H264RawSEIDisplayOrientation { uint8_t display_orientation_extension_flag; } H264RawSEIDisplayOrientation; -typedef struct H264RawSEIMasteringDisplayColourVolume { - uint16_t display_primaries_x[3]; - uint16_t display_primaries_y[3]; - uint16_t white_point_x; - uint16_t white_point_y; - uint32_t max_display_mastering_luminance; - uint32_t min_display_mastering_luminance; -} H264RawSEIMasteringDisplayColourVolume; - -typedef struct H264RawSEIAlternativeTransferCharacteristics { - uint8_t preferred_transfer_characteristics; -} H264RawSEIAlternativeTransferCharacteristics; - typedef struct H264RawSEIPayload { uint32_t payload_type; uint32_t payload_size; @@ -326,12 +299,12 @@ typedef struct H264RawSEIPayload { H264RawSEIPicTiming pic_timing; H264RawSEIPanScanRect pan_scan_rect; // H264RawSEIFiller filler -> no fields. - H264RawSEIUserDataRegistered user_data_registered; - H264RawSEIUserDataUnregistered user_data_unregistered; + SEIRawUserDataRegistered user_data_registered; + SEIRawUserDataUnregistered user_data_unregistered; H264RawSEIRecoveryPoint recovery_point; H264RawSEIDisplayOrientation display_orientation; - H264RawSEIMasteringDisplayColourVolume mastering_display_colour_volume; - H264RawSEIAlternativeTransferCharacteristics + SEIRawMasteringDisplayColourVolume mastering_display_colour_volume; + SEIRawAlternativeTransferCharacteristics alternative_transfer_characteristics; struct { uint8_t *data; diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 550c059ef3..9e210abba4 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -253,9 +253,11 @@ static int cbs_h265_payload_extension_present(GetBitContext *gbc, uint32_t paylo return err; \ } while (0) -#define FUNC_NAME(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name -#define FUNC_H264(rw, name) FUNC_NAME(rw, h264, name) -#define FUNC_H265(rw, name) FUNC_NAME(rw, h265, name) +#define FUNC_NAME2(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name +#define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name) +#define FUNC_H264(name) FUNC_NAME1(READWRITE, h264, name) +#define FUNC_H265(name) FUNC_NAME1(READWRITE, h265, name) +#define FUNC_SEI(name) FUNC_NAME1(READWRITE, sei, name) #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL) @@ -356,11 +358,15 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) name = name ## _ref->data; \ } while (0) -#define FUNC(name) FUNC_H264(READWRITE, name) +#define FUNC(name) FUNC_SEI(name) +#include "cbs_sei_syntax_template.c" +#undef FUNC + +#define FUNC(name) FUNC_H264(name) #include "cbs_h264_syntax_template.c" #undef FUNC -#define FUNC(name) FUNC_H265(READWRITE, name) +#define FUNC(name) FUNC_H265(name) #include "cbs_h265_syntax_template.c" #undef FUNC @@ -428,11 +434,15 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) } \ } while (0) -#define FUNC(name) FUNC_H264(READWRITE, name) +#define FUNC(name) FUNC_SEI(name) +#include "cbs_sei_syntax_template.c" +#undef FUNC + +#define FUNC(name) FUNC_H264(name) #include "cbs_h264_syntax_template.c" #undef FUNC -#define FUNC(name) FUNC_H265(READWRITE, name) +#define FUNC(name) FUNC_H265(name) #include "cbs_h265_syntax_template.c" #undef FUNC diff --git a/libavcodec/cbs_h264_syntax_template.c b/libavcodec/cbs_h264_syntax_template.c index b65460996b..76ed51cc7b 100644 --- a/libavcodec/cbs_h264_syntax_template.c +++ b/libavcodec/cbs_h264_syntax_template.c @@ -700,70 +700,6 @@ static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_user_data_registered)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIUserDataRegistered *current, - uint32_t *payload_size) -{ - int err, i, j; - - HEADER("User Data Registered ITU-T T.35"); - - u(8, itu_t_t35_country_code, 0x00, 0xff); - if (current->itu_t_t35_country_code != 0xff) - i = 1; - else { - u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); - i = 2; - } - -#ifdef READ - if (*payload_size < i) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data registered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - i; -#else - *payload_size = i + current->data_length; -#endif - - allocate(current->data, current->data_length); - for (j = 0; j < current->data_length; j++) - xu(8, itu_t_t35_payload_byte[i], current->data[j], 0x00, 0xff, 1, i + j); - - return 0; -} - -static int FUNC(sei_user_data_unregistered)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIUserDataUnregistered *current, - uint32_t *payload_size) -{ - int err, i; - - HEADER("User Data Unregistered"); - -#ifdef READ - if (*payload_size < 16) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data unregistered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - 16; -#else - *payload_size = 16 + current->data_length; -#endif - - for (i = 0; i < 16; i++) - us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); - - allocate(current->data, current->data_length); - - for (i = 0; i < current->data_length; i++) - xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); - - return 0; -} - static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEIRecoveryPoint *current) { @@ -798,40 +734,6 @@ static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext * return 0; } -static int FUNC(sei_mastering_display_colour_volume)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIMasteringDisplayColourVolume *current) -{ - int err, c; - - HEADER("Mastering Display Colour Volume"); - - for (c = 0; c < 3; c++) { - us(16, display_primaries_x[c], 0, 50000, 1, c); - us(16, display_primaries_y[c], 0, 50000, 1, c); - } - - u(16, white_point_x, 0, 50000); - u(16, white_point_y, 0, 50000); - - u(32, max_display_mastering_luminance, 1, MAX_UINT_BITS(32)); - u(32, min_display_mastering_luminance, 0, current->max_display_mastering_luminance - 1); - - return 0; -} - -static int FUNC(sei_alternative_transfer_characteristics)(CodedBitstreamContext *ctx, - RWContext *rw, - H264RawSEIAlternativeTransferCharacteristics *current) -{ - int err; - - HEADER("Alternative Transfer Characteristics"); - - ub(8, preferred_transfer_characteristics); - - return 0; -} - static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEIPayload *current) { @@ -864,11 +766,11 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, } break; case H264_SEI_TYPE_USER_DATA_REGISTERED: - CHECK(FUNC(sei_user_data_registered) + CHECK(FUNC_SEI(sei_user_data_registered) (ctx, rw, ¤t->payload.user_data_registered, ¤t->payload_size)); break; case H264_SEI_TYPE_USER_DATA_UNREGISTERED: - CHECK(FUNC(sei_user_data_unregistered) + CHECK(FUNC_SEI(sei_user_data_unregistered) (ctx, rw, ¤t->payload.user_data_unregistered, ¤t->payload_size)); break; case H264_SEI_TYPE_RECOVERY_POINT: @@ -880,11 +782,11 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, (ctx, rw, ¤t->payload.display_orientation)); break; case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: - CHECK(FUNC(sei_mastering_display_colour_volume) + CHECK(FUNC_SEI(sei_mastering_display_colour_volume) (ctx, rw, ¤t->payload.mastering_display_colour_volume)); break; case H264_SEI_TYPE_ALTERNATIVE_TRANSFER: - CHECK(FUNC(sei_alternative_transfer_characteristics) + CHECK(FUNC_SEI(sei_alternative_transfer_characteristics) (ctx, rw, ¤t->payload.alternative_transfer_characteristics)); break; default: diff --git a/libavcodec/cbs_h265.h b/libavcodec/cbs_h265.h index 15b22bbfd4..d8e93e3bb8 100644 --- a/libavcodec/cbs_h265.h +++ b/libavcodec/cbs_h265.h @@ -23,6 +23,7 @@ #include #include "cbs_h2645.h" +#include "cbs_sei.h" #include "hevc.h" enum { @@ -596,21 +597,6 @@ typedef struct H265RawSEIPanScanRect { uint16_t pan_scan_rect_persistence_flag; } H265RawSEIPanScanRect; -typedef struct H265RawSEIUserDataRegistered { - uint8_t itu_t_t35_country_code; - uint8_t itu_t_t35_country_code_extension_byte; - uint8_t *data; - AVBufferRef *data_ref; - size_t data_length; -} H265RawSEIUserDataRegistered; - -typedef struct H265RawSEIUserDataUnregistered { - uint8_t uuid_iso_iec_11578[16]; - uint8_t *data; - AVBufferRef *data_ref; - size_t data_length; -} H265RawSEIUserDataUnregistered; - typedef struct H265RawSEIRecoveryPoint { int16_t recovery_poc_cnt; uint8_t exact_match_flag; @@ -661,24 +647,6 @@ typedef struct H265RawSEITimeCode { int32_t time_offset_value[3]; } H265RawSEITimeCode; -typedef struct H265RawSEIMasteringDisplayColourVolume { - uint16_t display_primaries_x[3]; - uint16_t display_primaries_y[3]; - uint16_t white_point_x; - uint16_t white_point_y; - uint32_t max_display_mastering_luminance; - uint32_t min_display_mastering_luminance; -} H265RawSEIMasteringDisplayColourVolume; - -typedef struct H265RawSEIContentLightLevelInfo { - uint16_t max_content_light_level; - uint16_t max_pic_average_light_level; -} H265RawSEIContentLightLevelInfo; - -typedef struct H265RawSEIAlternativeTransferCharacteristics { - uint8_t preferred_transfer_characteristics; -} H265RawSEIAlternativeTransferCharacteristics; - typedef struct H265RawSEIAlphaChannelInfo { uint8_t alpha_channel_cancel_flag; uint8_t alpha_channel_use_idc; @@ -697,16 +665,17 @@ typedef struct H265RawSEIPayload { H265RawSEIBufferingPeriod buffering_period; H265RawSEIPicTiming pic_timing; H265RawSEIPanScanRect pan_scan_rect; - H265RawSEIUserDataRegistered user_data_registered; - H265RawSEIUserDataUnregistered user_data_unregistered; + SEIRawUserDataRegistered user_data_registered; + SEIRawUserDataUnregistered user_data_unregistered; H265RawSEIRecoveryPoint recovery_point; H265RawSEIDisplayOrientation display_orientation; H265RawSEIActiveParameterSets active_parameter_sets; H265RawSEIDecodedPictureHash decoded_picture_hash; H265RawSEITimeCode time_code; - H265RawSEIMasteringDisplayColourVolume mastering_display; - H265RawSEIContentLightLevelInfo content_light_level; - H265RawSEIAlternativeTransferCharacteristics + SEIRawMasteringDisplayColourVolume + mastering_display_colour_volume; + SEIRawContentLightLevelInfo content_light_level; + SEIRawAlternativeTransferCharacteristics alternative_transfer_characteristics; H265RawSEIAlphaChannelInfo alpha_channel_info; struct { diff --git a/libavcodec/cbs_h265_syntax_template.c b/libavcodec/cbs_h265_syntax_template.c index c0e94683a2..b792ec688a 100644 --- a/libavcodec/cbs_h265_syntax_template.c +++ b/libavcodec/cbs_h265_syntax_template.c @@ -1808,70 +1808,6 @@ static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_user_data_registered)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIUserDataRegistered *current, - uint32_t *payload_size) -{ - int err, i, j; - - HEADER("User Data Registered ITU-T T.35"); - - u(8, itu_t_t35_country_code, 0x00, 0xff); - if (current->itu_t_t35_country_code != 0xff) - i = 1; - else { - u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); - i = 2; - } - -#ifdef READ - if (*payload_size < i) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data registered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - i; -#else - *payload_size = i + current->data_length; -#endif - - allocate(current->data, current->data_length); - for (j = 0; j < current->data_length; j++) - xu(8, itu_t_t35_payload_byte[i], current->data[j], 0x00, 0xff, 1, i + j); - - return 0; -} - -static int FUNC(sei_user_data_unregistered)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIUserDataUnregistered *current, - uint32_t *payload_size) -{ - int err, i; - - HEADER("User Data Unregistered"); - -#ifdef READ - if (*payload_size < 16) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data unregistered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - 16; -#else - *payload_size = 16 + current->data_length; -#endif - - for (i = 0; i < 16; i++) - us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); - - allocate(current->data, current->data_length); - - for (i = 0; i < current->data_length; i++) - xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); - - return 0; -} - static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, H265RawSEIRecoveryPoint *current) { @@ -2022,55 +1958,6 @@ static int FUNC(sei_time_code)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_mastering_display)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIMasteringDisplayColourVolume *current) -{ - int err, c; - - HEADER("Mastering Display Colour Volume"); - - for (c = 0; c < 3; c++) { - us(16, display_primaries_x[c], 0, 50000, 1, c); - us(16, display_primaries_y[c], 0, 50000, 1, c); - } - - u(16, white_point_x, 0, 50000); - u(16, white_point_y, 0, 50000); - - u(32, max_display_mastering_luminance, - 1, MAX_UINT_BITS(32)); - u(32, min_display_mastering_luminance, - 0, current->max_display_mastering_luminance - 1); - - return 0; -} - -static int FUNC(sei_content_light_level)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIContentLightLevelInfo *current) -{ - int err; - - HEADER("Content Light Level"); - - ub(16, max_content_light_level); - ub(16, max_pic_average_light_level); - - return 0; -} - -static int FUNC(sei_alternative_transfer_characteristics)(CodedBitstreamContext *ctx, - RWContext *rw, - H265RawSEIAlternativeTransferCharacteristics *current) -{ - int err; - - HEADER("Alternative Transfer Characteristics"); - - ub(8, preferred_transfer_characteristics); - - return 0; -} - static int FUNC(sei_alpha_channel_info)(CodedBitstreamContext *ctx, RWContext *rw, H265RawSEIAlphaChannelInfo *current) @@ -2180,20 +2067,32 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, &more_data)); \ break +#define SEI_TYPE_N2(type, prefix_valid, suffix_valid, name) \ + case HEVC_SEI_TYPE_ ## type: \ + SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid); \ + CHECK(FUNC_SEI(sei_ ## name)(ctx, rw, ¤t->payload.name)); \ + break +#define SEI_TYPE_S2(type, prefix_valid, suffix_valid, name) \ + case HEVC_SEI_TYPE_ ## type: \ + SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid); \ + CHECK(FUNC_SEI(sei_ ## name)(ctx, rw, ¤t->payload.name, \ + ¤t->payload_size)); \ + break + SEI_TYPE_E(BUFFERING_PERIOD, 1, 0, buffering_period); SEI_TYPE_N(PICTURE_TIMING, 1, 0, pic_timing); SEI_TYPE_N(PAN_SCAN_RECT, 1, 0, pan_scan_rect); - SEI_TYPE_S(USER_DATA_REGISTERED_ITU_T_T35, + SEI_TYPE_S2(USER_DATA_REGISTERED_ITU_T_T35, 1, 1, user_data_registered); - SEI_TYPE_S(USER_DATA_UNREGISTERED, 1, 1, user_data_unregistered); + SEI_TYPE_S2(USER_DATA_UNREGISTERED, 1, 1, user_data_unregistered); SEI_TYPE_N(RECOVERY_POINT, 1, 0, recovery_point); SEI_TYPE_N(DISPLAY_ORIENTATION, 1, 0, display_orientation); SEI_TYPE_N(ACTIVE_PARAMETER_SETS, 1, 0, active_parameter_sets); SEI_TYPE_N(DECODED_PICTURE_HASH, 0, 1, decoded_picture_hash); SEI_TYPE_N(TIME_CODE, 1, 0, time_code); - SEI_TYPE_N(MASTERING_DISPLAY_INFO, 1, 0, mastering_display); - SEI_TYPE_N(CONTENT_LIGHT_LEVEL_INFO, 1, 0, content_light_level); - SEI_TYPE_N(ALTERNATIVE_TRANSFER_CHARACTERISTICS, + SEI_TYPE_N2(MASTERING_DISPLAY_INFO, 1, 0, mastering_display_colour_volume); + SEI_TYPE_N2(CONTENT_LIGHT_LEVEL_INFO,1, 0, content_light_level); + SEI_TYPE_N2(ALTERNATIVE_TRANSFER_CHARACTERISTICS, 1, 0, alternative_transfer_characteristics); SEI_TYPE_N(ALPHA_CHANNEL_INFO, 1, 0, alpha_channel_info); diff --git a/libavcodec/cbs_sei.h b/libavcodec/cbs_sei.h new file mode 100644 index 0000000000..95beabf4d7 --- /dev/null +++ b/libavcodec/cbs_sei.h @@ -0,0 +1,60 @@ +/* + * 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_SEI_H +#define AVCODEC_CBS_SEI_H + +#include +#include +#include "libavutil/buffer.h" + + +typedef struct SEIRawUserDataRegistered { + uint8_t itu_t_t35_country_code; + uint8_t itu_t_t35_country_code_extension_byte; + uint8_t *data; + AVBufferRef *data_ref; + size_t data_length; +} SEIRawUserDataRegistered; + +typedef struct SEIRawUserDataUnregistered { + uint8_t uuid_iso_iec_11578[16]; + uint8_t *data; + AVBufferRef *data_ref; + size_t data_length; +} SEIRawUserDataUnregistered; + +typedef struct SEIRawMasteringDisplayColourVolume { + uint16_t display_primaries_x[3]; + uint16_t display_primaries_y[3]; + uint16_t white_point_x; + uint16_t white_point_y; + uint32_t max_display_mastering_luminance; + uint32_t min_display_mastering_luminance; +} SEIRawMasteringDisplayColourVolume; + +typedef struct SEIRawContentLightLevelInfo { + uint16_t max_content_light_level; + uint16_t max_pic_average_light_level; +} SEIRawContentLightLevelInfo; + +typedef struct SEIRawAlternativeTransferCharacteristics { + uint8_t preferred_transfer_characteristics; +} SEIRawAlternativeTransferCharacteristics; + +#endif /* AVCODEC_CBS_SEI_H */ diff --git a/libavcodec/cbs_sei_syntax_template.c b/libavcodec/cbs_sei_syntax_template.c new file mode 100644 index 0000000000..93d9fafde1 --- /dev/null +++ b/libavcodec/cbs_sei_syntax_template.c @@ -0,0 +1,132 @@ +/* + * 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 + */ + +static int FUNC(sei_user_data_registered) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawUserDataRegistered *current, uint32_t *payload_size) +{ + int err, i, j; + + HEADER("User Data Registered ITU-T T.35"); + + u(8, itu_t_t35_country_code, 0x00, 0xff); + if (current->itu_t_t35_country_code != 0xff) + i = 1; + else { + u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); + i = 2; + } + +#ifdef READ + if (*payload_size < i) { + av_log(ctx->log_ctx, AV_LOG_ERROR, + "Invalid SEI user data registered payload.\n"); + return AVERROR_INVALIDDATA; + } + current->data_length = *payload_size - i; +#else + *payload_size = i + current->data_length; +#endif + + allocate(current->data, current->data_length); + for (j = 0; j < current->data_length; j++) + xu(8, itu_t_t35_payload_byte[], current->data[j], 0x00, 0xff, 1, i + j); + + return 0; +} + +static int FUNC(sei_user_data_unregistered) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawUserDataUnregistered *current, uint32_t *payload_size) +{ + int err, i; + + HEADER("User Data Unregistered"); + +#ifdef READ + if (*payload_size < 16) { + av_log(ctx->log_ctx, AV_LOG_ERROR, + "Invalid SEI user data unregistered payload.\n"); + return AVERROR_INVALIDDATA; + } + current->data_length = *payload_size - 16; +#else + *payload_size = 16 + current->data_length; +#endif + + for (i = 0; i < 16; i++) + us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); + + allocate(current->data, current->data_length); + + for (i = 0; i < current->data_length; i++) + xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); + + return 0; +} + +static int FUNC(sei_mastering_display_colour_volume) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawMasteringDisplayColourVolume *current) +{ + int err, c; + + HEADER("Mastering Display Colour Volume"); + + for (c = 0; c < 3; c++) { + us(16, display_primaries_x[c], 0, 50000, 1, c); + us(16, display_primaries_y[c], 0, 50000, 1, c); + } + + u(16, white_point_x, 0, 50000); + u(16, white_point_y, 0, 50000); + + u(32, max_display_mastering_luminance, + 1, MAX_UINT_BITS(32)); + u(32, min_display_mastering_luminance, + 0, current->max_display_mastering_luminance - 1); + + return 0; +} + +static int FUNC(sei_content_light_level) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawContentLightLevelInfo *current) +{ + int err; + + HEADER("Content Light Level"); + + ub(16, max_content_light_level); + ub(16, max_pic_average_light_level); + + return 0; +} + +static int FUNC(sei_alternative_transfer_characteristics) + (CodedBitstreamContext *ctx, RWContext *rw, + SEIRawAlternativeTransferCharacteristics *current) +{ + int err; + + HEADER("Alternative Transfer Characteristics"); + + ub(8, preferred_transfer_characteristics); + + return 0; +} diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c index eb1503159b..d7cf58095b 100644 --- a/libavcodec/h264_metadata_bsf.c +++ b/libavcodec/h264_metadata_bsf.c @@ -416,7 +416,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) H264RawSEIPayload payload = { .payload_type = H264_SEI_TYPE_USER_DATA_UNREGISTERED, }; - H264RawSEIUserDataUnregistered *udu = + SEIRawUserDataUnregistered *udu = &payload.payload.user_data_unregistered; for (i = j = 0; j < 32 && ctx->sei_user_data[i]; i++) { diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index e52a0e37a4..b577d09caf 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -96,7 +96,7 @@ typedef struct VAAPIEncodeH264Context { H264RawSEIBufferingPeriod sei_buffering_period; H264RawSEIPicTiming sei_pic_timing; H264RawSEIRecoveryPoint sei_recovery_point; - H264RawSEIUserDataUnregistered sei_identifier; + SEIRawUserDataUnregistered sei_identifier; char *sei_identifier_string; int aud_needed; diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 3e0af17ea5..a7af763ae4 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -76,8 +76,8 @@ typedef struct VAAPIEncodeH265Context { H265RawSEI raw_sei; H265RawSlice raw_slice; - H265RawSEIMasteringDisplayColourVolume sei_mastering_display; - H265RawSEIContentLightLevelInfo sei_content_light_level; + SEIRawMasteringDisplayColourVolume sei_mastering_display; + SEIRawContentLightLevelInfo sei_content_light_level; CodedBitstreamContext *cbc; CodedBitstreamFragment current_access_unit; @@ -219,7 +219,8 @@ static int vaapi_encode_h265_write_extra_header(AVCodecContext *avctx, if (priv->sei_needed & SEI_MASTERING_DISPLAY) { sei->payload[i].payload_type = HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO; - sei->payload[i].payload.mastering_display = priv->sei_mastering_display; + sei->payload[i].payload.mastering_display_colour_volume = + priv->sei_mastering_display; ++i; } @@ -781,7 +782,7 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, // SEI is needed when both the primaries and luminance are set if (mdm->has_primaries && mdm->has_luminance) { - H265RawSEIMasteringDisplayColourVolume *mdcv = + SEIRawMasteringDisplayColourVolume *mdcv = &priv->sei_mastering_display; const int mapping[3] = {1, 2, 0}; const int chroma_den = 50000; @@ -826,7 +827,7 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, if (sd) { AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; - H265RawSEIContentLightLevelInfo *clli = + SEIRawContentLightLevelInfo *clli = &priv->sei_content_light_level; clli->max_content_light_level = FFMIN(clm->MaxCLL, 65535);