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.h" | ||||
| #include "cbs_h2645.h" | #include "cbs_h2645.h" | ||||
| #include "cbs_sei.h" | |||||
| #include "h264.h" | #include "h264.h" | ||||
| @@ -274,21 +275,6 @@ typedef struct H264RawSEIPanScanRect { | |||||
| uint16_t pan_scan_rect_repetition_period; | uint16_t pan_scan_rect_repetition_period; | ||||
| } H264RawSEIPanScanRect; | } 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 { | typedef struct H264RawSEIRecoveryPoint { | ||||
| uint16_t recovery_frame_cnt; | uint16_t recovery_frame_cnt; | ||||
| uint8_t exact_match_flag; | uint8_t exact_match_flag; | ||||
| @@ -305,19 +291,6 @@ typedef struct H264RawSEIDisplayOrientation { | |||||
| uint8_t display_orientation_extension_flag; | uint8_t display_orientation_extension_flag; | ||||
| } H264RawSEIDisplayOrientation; | } 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 { | typedef struct H264RawSEIPayload { | ||||
| uint32_t payload_type; | uint32_t payload_type; | ||||
| uint32_t payload_size; | uint32_t payload_size; | ||||
| @@ -326,12 +299,12 @@ typedef struct H264RawSEIPayload { | |||||
| H264RawSEIPicTiming pic_timing; | H264RawSEIPicTiming pic_timing; | ||||
| H264RawSEIPanScanRect pan_scan_rect; | H264RawSEIPanScanRect pan_scan_rect; | ||||
| // H264RawSEIFiller filler -> no fields. | // H264RawSEIFiller filler -> no fields. | ||||
| H264RawSEIUserDataRegistered user_data_registered; | |||||
| H264RawSEIUserDataUnregistered user_data_unregistered; | |||||
| SEIRawUserDataRegistered user_data_registered; | |||||
| SEIRawUserDataUnregistered user_data_unregistered; | |||||
| H264RawSEIRecoveryPoint recovery_point; | H264RawSEIRecoveryPoint recovery_point; | ||||
| H264RawSEIDisplayOrientation display_orientation; | H264RawSEIDisplayOrientation display_orientation; | ||||
| H264RawSEIMasteringDisplayColourVolume mastering_display_colour_volume; | |||||
| H264RawSEIAlternativeTransferCharacteristics | |||||
| SEIRawMasteringDisplayColourVolume mastering_display_colour_volume; | |||||
| SEIRawAlternativeTransferCharacteristics | |||||
| alternative_transfer_characteristics; | alternative_transfer_characteristics; | ||||
| struct { | struct { | ||||
| uint8_t *data; | uint8_t *data; | ||||
| @@ -253,9 +253,11 @@ static int cbs_h265_payload_extension_present(GetBitContext *gbc, uint32_t paylo | |||||
| return err; \ | return err; \ | ||||
| } while (0) | } 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) | #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; \ | name = name ## _ref->data; \ | ||||
| } while (0) | } 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" | #include "cbs_h264_syntax_template.c" | ||||
| #undef FUNC | #undef FUNC | ||||
| #define FUNC(name) FUNC_H265(READWRITE, name) | |||||
| #define FUNC(name) FUNC_H265(name) | |||||
| #include "cbs_h265_syntax_template.c" | #include "cbs_h265_syntax_template.c" | ||||
| #undef FUNC | #undef FUNC | ||||
| @@ -428,11 +434,15 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) | |||||
| } \ | } \ | ||||
| } while (0) | } 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" | #include "cbs_h264_syntax_template.c" | ||||
| #undef FUNC | #undef FUNC | ||||
| #define FUNC(name) FUNC_H265(READWRITE, name) | |||||
| #define FUNC(name) FUNC_H265(name) | |||||
| #include "cbs_h265_syntax_template.c" | #include "cbs_h265_syntax_template.c" | ||||
| #undef FUNC | #undef FUNC | ||||
| @@ -700,70 +700,6 @@ static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, | |||||
| return 0; | 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, | static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, | ||||
| H264RawSEIRecoveryPoint *current) | H264RawSEIRecoveryPoint *current) | ||||
| { | { | ||||
| @@ -798,40 +734,6 @@ static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext * | |||||
| return 0; | 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, | static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, | ||||
| H264RawSEIPayload *current) | H264RawSEIPayload *current) | ||||
| { | { | ||||
| @@ -864,11 +766,11 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, | |||||
| } | } | ||||
| break; | break; | ||||
| case H264_SEI_TYPE_USER_DATA_REGISTERED: | 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)); | (ctx, rw, ¤t->payload.user_data_registered, ¤t->payload_size)); | ||||
| break; | break; | ||||
| case H264_SEI_TYPE_USER_DATA_UNREGISTERED: | 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)); | (ctx, rw, ¤t->payload.user_data_unregistered, ¤t->payload_size)); | ||||
| break; | break; | ||||
| case H264_SEI_TYPE_RECOVERY_POINT: | 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)); | (ctx, rw, ¤t->payload.display_orientation)); | ||||
| break; | break; | ||||
| case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: | 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)); | (ctx, rw, ¤t->payload.mastering_display_colour_volume)); | ||||
| break; | break; | ||||
| case H264_SEI_TYPE_ALTERNATIVE_TRANSFER: | 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)); | (ctx, rw, ¤t->payload.alternative_transfer_characteristics)); | ||||
| break; | break; | ||||
| default: | default: | ||||
| @@ -23,6 +23,7 @@ | |||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include "cbs_h2645.h" | #include "cbs_h2645.h" | ||||
| #include "cbs_sei.h" | |||||
| #include "hevc.h" | #include "hevc.h" | ||||
| enum { | enum { | ||||
| @@ -596,21 +597,6 @@ typedef struct H265RawSEIPanScanRect { | |||||
| uint16_t pan_scan_rect_persistence_flag; | uint16_t pan_scan_rect_persistence_flag; | ||||
| } H265RawSEIPanScanRect; | } 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 { | typedef struct H265RawSEIRecoveryPoint { | ||||
| int16_t recovery_poc_cnt; | int16_t recovery_poc_cnt; | ||||
| uint8_t exact_match_flag; | uint8_t exact_match_flag; | ||||
| @@ -661,24 +647,6 @@ typedef struct H265RawSEITimeCode { | |||||
| int32_t time_offset_value[3]; | int32_t time_offset_value[3]; | ||||
| } H265RawSEITimeCode; | } 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 { | typedef struct H265RawSEIAlphaChannelInfo { | ||||
| uint8_t alpha_channel_cancel_flag; | uint8_t alpha_channel_cancel_flag; | ||||
| uint8_t alpha_channel_use_idc; | uint8_t alpha_channel_use_idc; | ||||
| @@ -697,16 +665,17 @@ typedef struct H265RawSEIPayload { | |||||
| H265RawSEIBufferingPeriod buffering_period; | H265RawSEIBufferingPeriod buffering_period; | ||||
| H265RawSEIPicTiming pic_timing; | H265RawSEIPicTiming pic_timing; | ||||
| H265RawSEIPanScanRect pan_scan_rect; | H265RawSEIPanScanRect pan_scan_rect; | ||||
| H265RawSEIUserDataRegistered user_data_registered; | |||||
| H265RawSEIUserDataUnregistered user_data_unregistered; | |||||
| SEIRawUserDataRegistered user_data_registered; | |||||
| SEIRawUserDataUnregistered user_data_unregistered; | |||||
| H265RawSEIRecoveryPoint recovery_point; | H265RawSEIRecoveryPoint recovery_point; | ||||
| H265RawSEIDisplayOrientation display_orientation; | H265RawSEIDisplayOrientation display_orientation; | ||||
| H265RawSEIActiveParameterSets active_parameter_sets; | H265RawSEIActiveParameterSets active_parameter_sets; | ||||
| H265RawSEIDecodedPictureHash decoded_picture_hash; | H265RawSEIDecodedPictureHash decoded_picture_hash; | ||||
| H265RawSEITimeCode time_code; | H265RawSEITimeCode time_code; | ||||
| H265RawSEIMasteringDisplayColourVolume mastering_display; | |||||
| H265RawSEIContentLightLevelInfo content_light_level; | |||||
| H265RawSEIAlternativeTransferCharacteristics | |||||
| SEIRawMasteringDisplayColourVolume | |||||
| mastering_display_colour_volume; | |||||
| SEIRawContentLightLevelInfo content_light_level; | |||||
| SEIRawAlternativeTransferCharacteristics | |||||
| alternative_transfer_characteristics; | alternative_transfer_characteristics; | ||||
| H265RawSEIAlphaChannelInfo alpha_channel_info; | H265RawSEIAlphaChannelInfo alpha_channel_info; | ||||
| struct { | struct { | ||||
| @@ -1808,70 +1808,6 @@ static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, | |||||
| return 0; | 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, | static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, | ||||
| H265RawSEIRecoveryPoint *current) | H265RawSEIRecoveryPoint *current) | ||||
| { | { | ||||
| @@ -2022,55 +1958,6 @@ static int FUNC(sei_time_code)(CodedBitstreamContext *ctx, RWContext *rw, | |||||
| return 0; | 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, | static int FUNC(sei_alpha_channel_info)(CodedBitstreamContext *ctx, | ||||
| RWContext *rw, | RWContext *rw, | ||||
| H265RawSEIAlphaChannelInfo *current) | H265RawSEIAlphaChannelInfo *current) | ||||
| @@ -2180,20 +2067,32 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, | |||||
| &more_data)); \ | &more_data)); \ | ||||
| break | 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_E(BUFFERING_PERIOD, 1, 0, buffering_period); | ||||
| SEI_TYPE_N(PICTURE_TIMING, 1, 0, pic_timing); | SEI_TYPE_N(PICTURE_TIMING, 1, 0, pic_timing); | ||||
| SEI_TYPE_N(PAN_SCAN_RECT, 1, 0, pan_scan_rect); | 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); | 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(RECOVERY_POINT, 1, 0, recovery_point); | ||||
| SEI_TYPE_N(DISPLAY_ORIENTATION, 1, 0, display_orientation); | SEI_TYPE_N(DISPLAY_ORIENTATION, 1, 0, display_orientation); | ||||
| SEI_TYPE_N(ACTIVE_PARAMETER_SETS, 1, 0, active_parameter_sets); | 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(DECODED_PICTURE_HASH, 0, 1, decoded_picture_hash); | ||||
| SEI_TYPE_N(TIME_CODE, 1, 0, time_code); | 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); | 1, 0, alternative_transfer_characteristics); | ||||
| SEI_TYPE_N(ALPHA_CHANNEL_INFO, 1, 0, alpha_channel_info); | 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 = { | H264RawSEIPayload payload = { | ||||
| .payload_type = H264_SEI_TYPE_USER_DATA_UNREGISTERED, | .payload_type = H264_SEI_TYPE_USER_DATA_UNREGISTERED, | ||||
| }; | }; | ||||
| H264RawSEIUserDataUnregistered *udu = | |||||
| SEIRawUserDataUnregistered *udu = | |||||
| &payload.payload.user_data_unregistered; | &payload.payload.user_data_unregistered; | ||||
| for (i = j = 0; j < 32 && ctx->sei_user_data[i]; i++) { | for (i = j = 0; j < 32 && ctx->sei_user_data[i]; i++) { | ||||
| @@ -96,7 +96,7 @@ typedef struct VAAPIEncodeH264Context { | |||||
| H264RawSEIBufferingPeriod sei_buffering_period; | H264RawSEIBufferingPeriod sei_buffering_period; | ||||
| H264RawSEIPicTiming sei_pic_timing; | H264RawSEIPicTiming sei_pic_timing; | ||||
| H264RawSEIRecoveryPoint sei_recovery_point; | H264RawSEIRecoveryPoint sei_recovery_point; | ||||
| H264RawSEIUserDataUnregistered sei_identifier; | |||||
| SEIRawUserDataUnregistered sei_identifier; | |||||
| char *sei_identifier_string; | char *sei_identifier_string; | ||||
| int aud_needed; | int aud_needed; | ||||
| @@ -76,8 +76,8 @@ typedef struct VAAPIEncodeH265Context { | |||||
| H265RawSEI raw_sei; | H265RawSEI raw_sei; | ||||
| H265RawSlice raw_slice; | H265RawSlice raw_slice; | ||||
| H265RawSEIMasteringDisplayColourVolume sei_mastering_display; | |||||
| H265RawSEIContentLightLevelInfo sei_content_light_level; | |||||
| SEIRawMasteringDisplayColourVolume sei_mastering_display; | |||||
| SEIRawContentLightLevelInfo sei_content_light_level; | |||||
| CodedBitstreamContext *cbc; | CodedBitstreamContext *cbc; | ||||
| CodedBitstreamFragment current_access_unit; | 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) { | if (priv->sei_needed & SEI_MASTERING_DISPLAY) { | ||||
| sei->payload[i].payload_type = HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO; | 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; | ++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 | // SEI is needed when both the primaries and luminance are set | ||||
| if (mdm->has_primaries && mdm->has_luminance) { | if (mdm->has_primaries && mdm->has_luminance) { | ||||
| H265RawSEIMasteringDisplayColourVolume *mdcv = | |||||
| SEIRawMasteringDisplayColourVolume *mdcv = | |||||
| &priv->sei_mastering_display; | &priv->sei_mastering_display; | ||||
| const int mapping[3] = {1, 2, 0}; | const int mapping[3] = {1, 2, 0}; | ||||
| const int chroma_den = 50000; | const int chroma_den = 50000; | ||||
| @@ -826,7 +827,7 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, | |||||
| if (sd) { | if (sd) { | ||||
| AVContentLightMetadata *clm = | AVContentLightMetadata *clm = | ||||
| (AVContentLightMetadata *)sd->data; | (AVContentLightMetadata *)sd->data; | ||||
| H265RawSEIContentLightLevelInfo *clli = | |||||
| SEIRawContentLightLevelInfo *clli = | |||||
| &priv->sei_content_light_level; | &priv->sei_content_light_level; | ||||
| clli->max_content_light_level = FFMIN(clm->MaxCLL, 65535); | clli->max_content_light_level = FFMIN(clm->MaxCLL, 65535); | ||||