From patchwork Fri Jan 1 21:35:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 24754 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 354BC44B645 for ; Fri, 1 Jan 2021 23:45:19 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1553D68A91B; Fri, 1 Jan 2021 23:45:19 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9A82B6880B2 for ; Fri, 1 Jan 2021 23:45:17 +0200 (EET) Received: by mail-wm1-f45.google.com with SMTP id g185so10014678wmf.3 for ; Fri, 01 Jan 2021 13:45:17 -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=G30UgA53lhwsDZ4JOYs2VY9OjysWasCbR1RdN/osetA=; b=JV6+c5bEEo7iyYtGxsuOF1qLugVqb12PBW5F05+eXxYwBogohhh5cwfI7fRUn9VdN1 EUpdPGKxsqYDqtYyswPVE4lVSZk/6rTAqD3Aa+9l1E+stg64TuhUsWHvwH5dtDP/K9eG NbQgfboQps8w3ui1IAWxPIlVAe+CsyjS9KpoBevMBw51vhJjChnQYEC8KL2dEkvdq6OS yFRdw+Uh2eUt41MJSeoPsUhenYdOUuP5DNk0RcCeVSeoaUi0dXwnzWpvmFFbfEgdRBbr 3wT3W8ivompk/n7I47JhPwjdEA4RntV/LIbhJIpIhKJ6o0RkfxWb74drYDW5tefAS/Ql LGhA== 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=G30UgA53lhwsDZ4JOYs2VY9OjysWasCbR1RdN/osetA=; b=Yrx0HEiUOhpmkcc1UitqA81NueNpQf3GqAYzOPVsijMBHP5TbBb9hVj8KiMspvsBw9 ot/pT//G/p2eK/Or8vBlRzRMknnZLDQhx5ZZHHra1hS2RmXMJBsaoN4ri9npc5LDtFS2 RZeA/lCAwFKQ2whYM6P9CVY/GjsTAJ8hfGD32Z+TBG+4KKMHCdOoBcDz0JeqDSnz48yM jE+6IEI7wzj8GkRig5Pa07LYrxspIrmUgPaBZLT7/WoPrVYX7kQK9uWeWH7TzPLiq8G3 XE1ySpiUxEZ3rJHa1FChgU98bK/X15IurciugyvoHcmLe/Pkh9y1xZkx1SYwTEoUtC/Y u/6g== X-Gm-Message-State: AOAM530zGqeGU0GBWADRhORDSbmRuqmCyq7+BC/mjoj2dsslbcO3wLZ4 hYVLF9EoQpcpOy8gQD7cYVkfMk7Vb85R6w== X-Google-Smtp-Source: ABdhPJztejzO4bBGeBWcVAN+gZZTH6o7pMQozq+Iip06INBDewCFyK8L/g4zo3j9u5h9eaEZrG3juQ== X-Received: by 2002:a7b:c397:: with SMTP id s23mr16832842wmj.63.1609537069758; Fri, 01 Jan 2021 13:37:49 -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 v20sm18784595wml.34.2021.01.01.13.37.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Jan 2021 13:37:48 -0800 (PST) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Fri, 1 Jan 2021 21:35:11 +0000 Message-Id: <20210101213537.169546-2-sw@jkqxz.net> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210101213537.169546-1-sw@jkqxz.net> References: <20210101213537.169546-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 01/27] 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 434322492c..ce58e47a36 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 48fae82d04..e4cc1a9be8 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..cc900830ae --- /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[i], 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);