@@ -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;
}
@@ -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 {
@@ -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;
@@ -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:
@@ -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;
@@ -2769,21 +2769,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 +3612,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)
@@ -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
@@ -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