Message ID | 20210101213537.169546-2-sw@jkqxz.net |
---|---|
State | Superseded |
Headers | show |
Series | Metadata handling in CBS | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
On Sat, Jan 2, 2021 at 5:45 AM Mark Thompson <sw@jkqxz.net> wrote: > 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 <stdint.h> > > #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 <stddef.h> > +#include <stdint.h> > +#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); > although it's just a name, change itu_t_t35_payload_byte[i] to itu_t_t35_payload_byte[i+j] maybe better? > + > + 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); > could you explain more about the 50000? it's not in spec. > + > + 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); > -- > 2.29.2 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On 1/4/2021 11:32 AM, Nuo Mi wrote: >> +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); >> > could you explain more about the 50000? it's not in spec. Check patch 4/27. It was a constrain present in previous revisions of the spec.
Yeah, thanks for the reminder. On Mon, Jan 4, 2021 at 10:47 PM James Almer <jamrial@gmail.com> wrote: > On 1/4/2021 11:32 AM, Nuo Mi wrote: > >> +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); > >> > > could you explain more about the 50000? it's not in spec. > > Check patch 4/27. It was a constrain present in previous revisions of > the spec. > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On 04/01/2021 14:32, Nuo Mi wrote: > On Sat, Jan 2, 2021 at 5:45 AM Mark Thompson <sw@jkqxz.net> wrote: > >> 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 >> >> ... >> + >> +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); >> > although it's just a name, change itu_t_t35_payload_byte[i] to > itu_t_t35_payload_byte[i+j] maybe better? No, because there is no standard variable called j so it shouldn't be in the string. i makes the most sense given that i is the loop index, though it's really i - (1 or 2). Maybe it would cause less confusion to leave the brackets empty? (After all, that element isn't actually an array, we just write it as one here because it's cleaner.) >> + >> + return 0; >> +} >> + - Mark
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 <stdint.h> #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 <stddef.h> +#include <stdint.h> +#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);