@@ -1543,6 +1543,13 @@ enum AVPacketSideDataType {
AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
/**
+ * Content light level metadata (based on SMPTE 2086:2014). The payload
+ * is an AVContentLightLevelMetadata type and it contains upper
bounds for
+ * the nominal target brightness light level.
+ */
+ AV_PKT_DATA_CONTENT_LIGHT_LEVEL_METADATA,
+
+ /**
* This side data should be associated with a video stream and
corresponds
* to the AVSphericalMapping structure.
*/
@@ -2645,7 +2645,24 @@ static int set_side_data(HEVCContext *s)
"min_luminance=%f, max_luminance=%f\n",
av_q2d(metadata->min_luminance),
av_q2d(metadata->max_luminance));
}
+ if (s->sei_content_light_level_info_present) {
+ AVFrameSideData* sd = av_frame_new_side_data(out,
+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL_METADATA,
+ sizeof(AVContentLightLevelMetadata));
+ if (sd) {
+ AVContentLightLevelMetadata* metadata =
(AVContentLightLevelMetadata*)sd->data;
+ const int luma_den = 10000;
+
+ metadata->max_content_light_level.num =
s->max_content_light_level;
+ metadata->max_content_light_level.den = luma_den;
+ metadata->max_frame_average_light_level.num =
s->max_frame_average_light_level;
+ metadata->max_frame_average_light_level.den = luma_den;
+ av_log(s->avctx, AV_LOG_DEBUG, "Content Light Level:
MaxCLL=%f, MaxFALL=%f\n",
+ av_q2d(metadata->max_content_light_level),
+ av_q2d(metadata->max_frame_average_light_level));
+ }
+ }
if (s->a53_caption) {
AVFrameSideData* sd = av_frame_new_side_data(out,
AV_FRAME_DATA_A53_CC,
@@ -932,6 +932,7 @@ typedef struct HEVCContext {
uint32_t min_mastering_luminance;
/** content light level */
+ int sei_content_light_level_info_present;
uint16_t max_content_light_level;
uint16_t max_frame_average_light_level;
@@ -109,6 +109,7 @@ static int
decode_nal_sei_content_light_level_info(HEVCContext *s)
s->max_content_light_level = get_bits(gb, 16);
s->max_frame_average_light_level = get_bits(gb, 16);
+ s->sei_content_light_level_info_present = 1;
return 0;
}
@@ -766,6 +766,7 @@ int ff_init_buffer_info(AVCodecContext *avctx,
AVFrame *frame)
{ AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D },
{ AV_PKT_DATA_AUDIO_SERVICE_TYPE,
AV_FRAME_DATA_AUDIO_SERVICE_TYPE },
{ AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA },
+ { AV_PKT_DATA_CONTENT_LIGHT_LEVEL_METADATA,
AV_FRAME_DATA_CONTENT_LIGHT_LEVEL_METADATA },
};
if (pkt) {
@@ -61,6 +61,7 @@ static const AVOption filt_name##_options[] = { \
{ "SKIP_SAMPLES", "", 0, AV_OPT_TYPE_CONST, {.i64
= AV_FRAME_DATA_SKIP_SAMPLES }, 0, 0, FLAGS, "type" }, \
{ "AUDIO_SERVICE_TYPE", "", 0, AV_OPT_TYPE_CONST, {.i64
= AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, 0, 0, FLAGS, "type" }, \
{ "MASTERING_DISPLAY_METADATA", "", 0, AV_OPT_TYPE_CONST, {.i64
= AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, 0, 0, FLAGS, "type" }, \
+ { "CONTENT_LIGHT_LEVEL_METADATA","",0, AV_OPT_TYPE_CONST, {.i64
= AV_FRAME_DATA_CONTENT_LIGHT_LEVEL_METADATA},0, 0, FLAGS, "type" }, \
{ "GOP_TIMECODE", "", 0, AV_OPT_TYPE_CONST, {.i64
= AV_FRAME_DATA_GOP_TIMECODE }, 0, 0, FLAGS, "type" }, \
{ NULL } \
}
@@ -758,9 +758,10 @@ const char *av_frame_side_data_name(enum
AVFrameSideDataType type)
case AV_FRAME_DATA_AFD: return "Active format
description";
case AV_FRAME_DATA_MOTION_VECTORS: return "Motion vectors";
case AV_FRAME_DATA_SKIP_SAMPLES: return "Skip samples";
- case AV_FRAME_DATA_AUDIO_SERVICE_TYPE: return "Audio
service type";
- case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: return "Mastering
display metadata";
- case AV_FRAME_DATA_GOP_TIMECODE: return "GOP timecode";
+ case AV_FRAME_DATA_AUDIO_SERVICE_TYPE: return "Audio
service type";
+ case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: return "Mastering
display metadata";
+ case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL_METADATA: return "Content
light level";
+ case AV_FRAME_DATA_GOP_TIMECODE: return "GOP timecode";
}
return NULL;
}
@@ -117,6 +117,12 @@ enum AVFrameSideDataType {
*/
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA,
/**
+ * Content light level metadata associated with a video frame. The
payload
+ * is an AVContentLightLevelMetadata type and it contains upper
bounds for
+ * the nominal target brightness light level.
+ */
+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL_METADATA,
+ /**
* The GOP timecode in 25 bit timecode format. Data format is
64-bit integer.
* This is set on the first frame of a GOP that has a temporal
reference of 0.
*/
b/libavutil/mastering_display_metadata.h
@@ -68,6 +68,30 @@ typedef struct AVMasteringDisplayMetadata {
} AVMasteringDisplayMetadata;
+
+/**
+ * Luminance attributes of the mastered content, calculated in linear light
+ * domain, defined by SMPTE 2086:2014 and ISO/IEC 23008-2:2015.
+ *
+ * To be used as payload of a AVFrameSideData or AVPacketSideData with the
+ * appropriate type.
+ *
+ * @note The struct should be allocated with av_frame_new_side_data()
+ */
+typedef struct AVContentLightLevelMetadata {
+ /**
+ * MaxCLL: Maximum Content Light Level (cd/m^2).
+ */
+ AVRational max_content_light_level;
+
+ /**
+ * MaxFALL: Maximum Frame-Average Light Level (cd/m^2).
+ */
+ AVRational max_frame_average_light_level;
+
+} AVContentLightLevelMetadata;
+
+
/**
* Allocate an AVMasteringDisplayMetadata structure and set its fields to
* default values. The resulting struct can be freed using av_freep().