On 12/29/2016 07:46 PM, Nicolas George wrote:
Thanks for the patch.

L'octidi 8 nivôse, an CCXXV, Nikola Kolarović a écrit :
From: Nikola Kolarović <nikola.kolaro...@rt-rk.com>

Extract max_content_light_level and max_frame_average_light_level
which are used in HEVC Main 10 (HDR10) for luminosity adjustment.

Based on ISO/IEC 23008-2:2015 section D.2.35.
---
  libavcodec/hevc.h     |  4 ++++
  libavcodec/hevc_sei.c | 12 ++++++++++++
  2 files changed, 16 insertions(+)
The fields you set in this patch are not used anywhere else. Is there a
second patch coming to make use of them?

Regards,

Hi Nicolas,

No problem, we can expose parsed values in frame/packet side_data.
Follow-up patch is below, and I've run FATE regression tests on x86_64 linux.

Thanks,
Nikola


From 3caeb8dcd2b68a966c521ffc686c2a326563c7fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Kolarovi=C4=87?= <nikola.kolaro...@rt-rk.com>
Date: Fri, 30 Dec 2016 14:12:09 +0100
Subject: [PATCH] avcodec/hevc: Expose light level data using
 AVContentLightLevelMetadata

Set HEVC side data (frame and packet) based on values extracted from Content light level
HEVC SEI prefix message.
---
 libavcodec/avcodec.h                   |  7 +++++++
 libavcodec/hevc.c                      | 17 +++++++++++++++++
 libavcodec/hevc.h                      |  1 +
 libavcodec/hevc_sei.c                  |  1 +
 libavcodec/utils.c                     |  1 +
 libavfilter/f_sidedata.c               |  1 +
 libavutil/frame.c                      |  7 ++++---
 libavutil/frame.h                      |  6 ++++++
 libavutil/mastering_display_metadata.h | 24 ++++++++++++++++++++++++
 9 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index ca8b786077..5dc4556684 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -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.
      */
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 7c563a34ba..1a3ccc51a6 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -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,
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index d5970b61b6..0af633f52e 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -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;

diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 13ecc67173..ec75e66668 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -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;
 }

diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 1263306f63..3393ca34c9 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -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) {
diff --git a/libavfilter/f_sidedata.c b/libavfilter/f_sidedata.c
index 45d246b732..1a30a8014d 100644
--- a/libavfilter/f_sidedata.c
+++ b/libavfilter/f_sidedata.c
@@ -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 } \
 }
diff --git a/libavutil/frame.c b/libavutil/frame.c
index c2f55098c8..2efc227920 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -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;
 }
diff --git a/libavutil/frame.h b/libavutil/frame.h
index b4500923af..a80269a59b 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -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.
      */
diff --git a/libavutil/mastering_display_metadata.h b/libavutil/mastering_display_metadata.h
index 936533fec4..45249a7502 100644
--- a/libavutil/mastering_display_metadata.h
+++ 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().
--
2.11.0


_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to