Make a new template file for common SEI messages - this will also apply to H.266.tags/n4.4
| @@ -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; | |||
| @@ -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 | |||
| @@ -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: | |||
| @@ -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 { | |||
| @@ -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); | |||
| @@ -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 */ | |||
| @@ -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; | |||
| } | |||
| @@ -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++) { | |||
| @@ -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; | |||
| @@ -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); | |||