diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c index b1ec55d35b..cb6be0594b 100644 --- a/libavcodec/h2645_sei.c +++ b/libavcodec/h2645_sei.c @@ -422,6 +422,23 @@ static int decode_nal_sei_mastering_display_info(H2645SEIMasteringDisplay *s, return 0; } +static int decode_nal_sei_content_light_info(H2645SEIContentLight *s, + GetByteContext *gb) +{ + if (bytestream2_get_bytes_left(gb) < 4) + return AVERROR_INVALIDDATA; + + // Max and average light levels + s->max_content_light_level = bytestream2_get_be16u(gb); + s->max_pic_average_light_level = bytestream2_get_be16u(gb); + // As this SEI message comes before the first frame that references it, + // initialize the flag to 2 and decrement on IRAP access unit so it + // persists for the coded video sequence (e.g., between two IRAPs) + s->present = 2; + + return 0; +} + int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, enum AVCodecID codec_id, GetBitContext *gb, GetByteContext *gbyte, void *logctx) @@ -445,6 +462,8 @@ int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, case SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: return decode_nal_sei_mastering_display_info(&h->mastering_display, gbyte); + case SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: + return decode_nal_sei_content_light_info(&h->content_light, gbyte); default: return FF_H2645_SEI_MESSAGE_UNHANDLED; } @@ -730,6 +749,19 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei, av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); } + if (sei->content_light.present) { + AVContentLightMetadata *metadata = + av_content_light_metadata_create_side_data(frame); + if (!metadata) + return AVERROR(ENOMEM); + metadata->MaxCLL = sei->content_light.max_content_light_level; + metadata->MaxFALL = sei->content_light.max_pic_average_light_level; + + av_log(avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n"); + av_log(avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n", + metadata->MaxCLL, metadata->MaxFALL); + } + return 0; } @@ -746,4 +778,5 @@ void ff_h2645_sei_reset(H2645SEI *s) s->ambient_viewing_environment.present = 0; s->mastering_display.present = 0; + s->content_light.present = 0; } diff --git a/libavcodec/h2645_sei.h b/libavcodec/h2645_sei.h index 83e1b2ec16..0ebf48011a 100644 --- a/libavcodec/h2645_sei.h +++ b/libavcodec/h2645_sei.h @@ -113,6 +113,12 @@ typedef struct H2645SEIMasteringDisplay { uint32_t min_luminance; } H2645SEIMasteringDisplay; +typedef struct H2645SEIContentLight { + int present; + uint16_t max_content_light_level; + uint16_t max_pic_average_light_level; +} H2645SEIContentLight; + typedef struct H2645SEI { H2645SEIA53Caption a53_caption; H2645SEIAFD afd; @@ -125,6 +131,7 @@ typedef struct H2645SEI { H2645SEIFilmGrainCharacteristics film_grain_characteristics; H2645SEIAmbientViewingEnvironment ambient_viewing_environment; H2645SEIMasteringDisplay mastering_display; + H2645SEIContentLight content_light; } H2645SEI; enum { diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 586ce20bba..e576bcb070 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -440,6 +440,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->sei.common.unregistered.x264_build = h1->sei.common.unregistered.x264_build; h->sei.common.mastering_display = h1->sei.common.mastering_display; + h->sei.common.content_light = h1->sei.common.content_light; if (!h->cur_pic_ptr) return 0; diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index b7b77d4d0c..351e699726 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -49,23 +49,6 @@ static int decode_nal_sei_decoded_picture_hash(HEVCSEIPictureHash *s, return 0; } -static int decode_nal_sei_content_light_info(HEVCSEIContentLight *s, - GetByteContext *gb) -{ - if (bytestream2_get_bytes_left(gb) < 4) - return AVERROR_INVALIDDATA; - - // Max and average light levels - s->max_content_light_level = bytestream2_get_be16u(gb); - s->max_pic_average_light_level = bytestream2_get_be16u(gb); - // As this SEI message comes before the first frame that references it, - // initialize the flag to 2 and decrement on IRAP access unit so it - // persists for the coded video sequence (e.g., between two IRAPs) - s->present = 2; - - return 0; -} - static int decode_nal_sei_pic_timing(HEVCSEI *s, GetBitContext *gb, const HEVCParamSets *ps, void *logctx) { @@ -177,8 +160,6 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gbyte); case SEI_TYPE_PIC_TIMING: return decode_nal_sei_pic_timing(s, gb, ps, logctx); - case SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: - return decode_nal_sei_content_light_info(&s->content_light, gbyte); case SEI_TYPE_ACTIVE_PARAMETER_SETS: return decode_nal_sei_active_parameter_sets(s, gb, logctx); case SEI_TYPE_TIME_CODE: diff --git a/libavcodec/hevc_sei.h b/libavcodec/hevc_sei.h index 077abdc74a..a23a64ec4f 100644 --- a/libavcodec/hevc_sei.h +++ b/libavcodec/hevc_sei.h @@ -53,12 +53,6 @@ typedef struct HEVCSEIPictureTiming { int picture_struct; } HEVCSEIPictureTiming; -typedef struct HEVCSEIContentLight { - int present; - uint16_t max_content_light_level; - uint16_t max_pic_average_light_level; -} HEVCSEIContentLight; - typedef struct HEVCSEIAlternativeTransfer { int present; int preferred_transfer_characteristics; @@ -88,7 +82,6 @@ typedef struct HEVCSEI { H2645SEI common; HEVCSEIPictureHash picture_hash; HEVCSEIPictureTiming picture_timing; - HEVCSEIContentLight content_light; int active_seq_parameter_set_id; HEVCSEITimeCode timecode; } HEVCSEI; diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 434750965b..1fe91238d4 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -31,7 +31,6 @@ #include "libavutil/display.h" #include "libavutil/film_grain_params.h" #include "libavutil/internal.h" -#include "libavutil/mastering_display_metadata.h" #include "libavutil/md5.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" @@ -2769,21 +2768,9 @@ static int set_side_data(HEVCContext *s) } // Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1 // so the side data persists for the entire coded video sequence. - if (s->sei.content_light.present > 0 && + if (s->sei.common.content_light.present > 0 && IS_IRAP(s) && s->no_rasl_output_flag) { - s->sei.content_light.present--; - } - if (s->sei.content_light.present) { - AVContentLightMetadata *metadata = - av_content_light_metadata_create_side_data(out); - if (!metadata) - return AVERROR(ENOMEM); - metadata->MaxCLL = s->sei.content_light.max_content_light_level; - metadata->MaxFALL = s->sei.content_light.max_pic_average_light_level; - - av_log(s->avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n"); - av_log(s->avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n", - metadata->MaxCLL, metadata->MaxFALL); + s->sei.common.content_light.present--; } ret = ff_h2645_sei_to_frame(out, &s->sei.common, AV_CODEC_ID_HEVC, NULL, @@ -3624,7 +3611,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->sei.common.display_orientation = s0->sei.common.display_orientation; s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer; s->sei.common.mastering_display = s0->sei.common.mastering_display; - s->sei.content_light = s0->sei.content_light; + s->sei.common.content_light = s0->sei.common.content_light; ret = export_stream_params_from_sei(s); if (ret < 0) diff --git a/tests/ref/fate/hevc-hdr-vivid-metadata b/tests/ref/fate/hevc-hdr-vivid-metadata index cb5db4557f..f3c777a852 100644 --- a/tests/ref/fate/hevc-hdr-vivid-metadata +++ b/tests/ref/fate/hevc-hdr-vivid-metadata @@ -1,10 +1,5 @@ [FRAME] [SIDE_DATA] -side_data_type=Content light level metadata -max_content=0 -max_average=0 -[/SIDE_DATA] -[SIDE_DATA] side_data_type=H.26[45] User Data Unregistered SEI message [/SIDE_DATA] [SIDE_DATA] @@ -21,6 +16,11 @@ min_luminance=50/10000 max_luminance=40000000/10000 [/SIDE_DATA] [SIDE_DATA] +side_data_type=Content light level metadata +max_content=0 +max_average=0 +[/SIDE_DATA] +[SIDE_DATA] side_data_type=HDR Dynamic Metadata CUVA 005.1 2021 (Vivid) system_start_code=1 num_windows=1 diff --git a/tests/ref/fate/hevc-hdr10-plus-metadata b/tests/ref/fate/hevc-hdr10-plus-metadata index cdf308b96a..f226cd8c7b 100644 --- a/tests/ref/fate/hevc-hdr10-plus-metadata +++ b/tests/ref/fate/hevc-hdr10-plus-metadata @@ -1,10 +1,5 @@ [FRAME] [SIDE_DATA] -side_data_type=Content light level metadata -max_content=1000 -max_average=200 -[/SIDE_DATA] -[SIDE_DATA] side_data_type=Mastering display metadata red_x=13250/50000 red_y=34500/50000 @@ -18,6 +13,11 @@ min_luminance=50/10000 max_luminance=10000000/10000 [/SIDE_DATA] [SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=200 +[/SIDE_DATA] +[SIDE_DATA] side_data_type=HDR Dynamic Metadata SMPTE2094-40 (HDR10+) application version=1 num_windows=1