diff mbox

[FFmpeg-devel] mov: Support mdcv and clli boxes for mastering display an color light level

Message ID 20171127202010.45621-1-vittorio.giovara@gmail.com
State Accepted
Commit 10db42f117ed5cb5b662eef619ee6a92d868095a
Headers show

Commit Message

Vittorio Giovara Nov. 27, 2017, 8:20 p.m. UTC
Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
---
 libavformat/mov.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

Comments

James Almer Nov. 27, 2017, 8:42 p.m. UTC | #1
On 11/27/2017 5:20 PM, Vittorio Giovara wrote:
> Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
> ---
>  libavformat/mov.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 71 insertions(+)
> 
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 79023ef369..bb463017a3 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -5072,6 +5072,51 @@ static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      return 0;
>  }
>  
> +static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> +{
> +    MOVStreamContext *sc;
> +    const int mapping[3] = {1, 2, 0};
> +    const int chroma_den = 50000;
> +    const int luma_den = 10000;
> +    int i;
> +
> +    if (c->fc->nb_streams < 1)
> +        return AVERROR_INVALIDDATA;
> +
> +    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
> +
> +    if (atom.size < 24) {
> +        av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    sc->mastering = av_mastering_display_metadata_alloc();
> +    if (!sc->mastering)
> +        return AVERROR(ENOMEM);
> +
> +    for (i = 0; i < 3; i++) {
> +        const int j = mapping[i];
> +        sc->mastering->display_primaries[j][0].num = avio_rb16(pb);
> +        sc->mastering->display_primaries[j][0].den = chroma_den;
> +        sc->mastering->display_primaries[j][1].num = avio_rb16(pb);
> +        sc->mastering->display_primaries[j][1].den = chroma_den;
> +    }
> +    sc->mastering->white_point[0].num = avio_rb16(pb);
> +    sc->mastering->white_point[0].den = chroma_den;
> +    sc->mastering->white_point[1].num = avio_rb16(pb);
> +    sc->mastering->white_point[1].den = chroma_den;
> +
> +    sc->mastering->max_luminance.num = avio_rb32(pb);
> +    sc->mastering->max_luminance.den = luma_den;
> +    sc->mastering->min_luminance.num = avio_rb32(pb);
> +    sc->mastering->min_luminance.den = luma_den;
> +
> +    sc->mastering->has_luminance = 1;
> +    sc->mastering->has_primaries = 1;
> +
> +    return 0;
> +}
> +
>  static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  {
>      MOVStreamContext *sc;
> @@ -5104,6 +5149,30 @@ static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      return 0;
>  }
>  
> +static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> +{
> +    MOVStreamContext *sc;
> +
> +    if (c->fc->nb_streams < 1)
> +        return AVERROR_INVALIDDATA;
> +
> +    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
> +
> +    if (atom.size < 4) {
> +        av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
> +    if (!sc->coll)
> +        return AVERROR(ENOMEM);
> +
> +    sc->coll->MaxCLL  = avio_rb16(pb);
> +    sc->coll->MaxFALL = avio_rb16(pb);
> +
> +    return 0;
> +}
> +
>  static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  {
>      AVStream *st;
> @@ -5912,6 +5981,8 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
>  { MKTAG('S','m','D','m'), mov_read_smdm },
>  { MKTAG('C','o','L','L'), mov_read_coll },
>  { MKTAG('v','p','c','C'), mov_read_vpcc },
> +{ MKTAG('m','d','c','v'), mov_read_mdcv },
> +{ MKTAG('c','l','l','i'), mov_read_clli },
>  { 0, NULL }
>  };

Where are these two defined? Because
https://github.com/webmproject/vp9-dash/blob/master/VPCodecISOMediaFileFormatBinding.md
describes coll and smdm, and those are already supported.
Michael Niedermayer Nov. 28, 2017, 7:33 p.m. UTC | #2
On Mon, Nov 27, 2017 at 03:20:10PM -0500, Vittorio Giovara wrote:
> Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
> ---
>  libavformat/mov.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 71 insertions(+)
> 
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 79023ef369..bb463017a3 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -5072,6 +5072,51 @@ static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      return 0;
>  }
>  
> +static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> +{
> +    MOVStreamContext *sc;
> +    const int mapping[3] = {1, 2, 0};
> +    const int chroma_den = 50000;
> +    const int luma_den = 10000;
> +    int i;
> +
> +    if (c->fc->nb_streams < 1)
> +        return AVERROR_INVALIDDATA;
> +
> +    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
> +
> +    if (atom.size < 24) {
> +        av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    sc->mastering = av_mastering_display_metadata_alloc();
> +    if (!sc->mastering)
> +        return AVERROR(ENOMEM);
> +
> +    for (i = 0; i < 3; i++) {
> +        const int j = mapping[i];

rather minor suggestion but you could use:
 ((int[]){ 1, 2, 0 })[i];

as mapping is not used anywhere else

[...]
diff mbox

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 79023ef369..bb463017a3 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -5072,6 +5072,51 @@  static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     return 0;
 }
 
+static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    MOVStreamContext *sc;
+    const int mapping[3] = {1, 2, 0};
+    const int chroma_den = 50000;
+    const int luma_den = 10000;
+    int i;
+
+    if (c->fc->nb_streams < 1)
+        return AVERROR_INVALIDDATA;
+
+    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+
+    if (atom.size < 24) {
+        av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    sc->mastering = av_mastering_display_metadata_alloc();
+    if (!sc->mastering)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < 3; i++) {
+        const int j = mapping[i];
+        sc->mastering->display_primaries[j][0].num = avio_rb16(pb);
+        sc->mastering->display_primaries[j][0].den = chroma_den;
+        sc->mastering->display_primaries[j][1].num = avio_rb16(pb);
+        sc->mastering->display_primaries[j][1].den = chroma_den;
+    }
+    sc->mastering->white_point[0].num = avio_rb16(pb);
+    sc->mastering->white_point[0].den = chroma_den;
+    sc->mastering->white_point[1].num = avio_rb16(pb);
+    sc->mastering->white_point[1].den = chroma_den;
+
+    sc->mastering->max_luminance.num = avio_rb32(pb);
+    sc->mastering->max_luminance.den = luma_den;
+    sc->mastering->min_luminance.num = avio_rb32(pb);
+    sc->mastering->min_luminance.den = luma_den;
+
+    sc->mastering->has_luminance = 1;
+    sc->mastering->has_primaries = 1;
+
+    return 0;
+}
+
 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     MOVStreamContext *sc;
@@ -5104,6 +5149,30 @@  static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     return 0;
 }
 
+static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    MOVStreamContext *sc;
+
+    if (c->fc->nb_streams < 1)
+        return AVERROR_INVALIDDATA;
+
+    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+
+    if (atom.size < 4) {
+        av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
+    if (!sc->coll)
+        return AVERROR(ENOMEM);
+
+    sc->coll->MaxCLL  = avio_rb16(pb);
+    sc->coll->MaxFALL = avio_rb16(pb);
+
+    return 0;
+}
+
 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
@@ -5912,6 +5981,8 @@  static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('S','m','D','m'), mov_read_smdm },
 { MKTAG('C','o','L','L'), mov_read_coll },
 { MKTAG('v','p','c','C'), mov_read_vpcc },
+{ MKTAG('m','d','c','v'), mov_read_mdcv },
+{ MKTAG('c','l','l','i'), mov_read_clli },
 { 0, NULL }
 };