diff mbox

[FFmpeg-devel,1/2,avformat/mxf] Add core colorimetry support to MXF.

Message ID 1474694344-31167-1-git-send-email-steven@strobe.cc
State Changes Requested
Headers show

Commit Message

Steven Robertson Sept. 24, 2016, 5:19 a.m. UTC
Signed-off-by: Steven Robertson <steven@strobe.cc>
---
 libavformat/mxf.c    | 33 +++++++++++++++++++++++++++++++++
 libavformat/mxf.h    |  3 +++
 libavformat/mxfdec.c | 29 +++++++++++++++++++++++++++++
 libavformat/mxfenc.c | 36 +++++++++++++++++++++++++++++++-----
 4 files changed, 96 insertions(+), 5 deletions(-)

Comments

Michael Niedermayer Sept. 24, 2016, 11:35 a.m. UTC | #1
On Fri, Sep 23, 2016 at 10:19:03PM -0700, Steven Robertson wrote:
> Signed-off-by: Steven Robertson <steven@strobe.cc>
> ---
>  libavformat/mxf.c    | 33 +++++++++++++++++++++++++++++++++
>  libavformat/mxf.h    |  3 +++
>  libavformat/mxfdec.c | 29 +++++++++++++++++++++++++++++
>  libavformat/mxfenc.c | 36 +++++++++++++++++++++++++++++++-----
>  4 files changed, 96 insertions(+), 5 deletions(-)

breaks fate
make: *** [fate-copy-trac4914] Error 1
make: *** [fate-lavf-mxf_opatom_audio] Error 1
make: *** [fate-lavf-mxf] Error 1
make: *** [fate-lavf-mxf_d10] Error 1
make: *** [fate-lavf-mxf_opatom] Error 1

[...]
> @@ -2085,6 +2100,20 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
>                      }
>                  }
>              }
> +
> +            color_primaries_ul = mxf_get_codec_ul(ff_mxf_color_primaries_uls,
> +                                                  &descriptor->color_primaries_ul);
> +            if (color_primaries_ul->uid[0])
> +              st->codecpar->color_primaries = color_primaries_ul->id;
> +            color_space_ul = mxf_get_codec_ul(ff_mxf_coding_equations_uls,
> +                                              &descriptor->color_space_ul);
> +            if (color_space_ul->uid[0])
> +              st->codecpar->color_space = color_space_ul->id;
> +            color_trc_ul = mxf_get_codec_ul(ff_mxf_transfer_characteristics_uls,
> +                                            &descriptor->color_trc_ul);
> +            if (color_trc_ul->uid[0])
> +              st->codecpar->color_trc = color_trc_ul->id;
> +
>              st->need_parsing = AVSTREAM_PARSE_HEADERS;
>              if (material_track->sequence->origin) {
>                  av_dict_set_int(&st->metadata, "material_track_origin", material_track->sequence->origin, 0);
> diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
> index 7733ef8..eb77f3a 100644
> --- a/libavformat/mxfenc.c
> +++ b/libavformat/mxfenc.c
> @@ -415,9 +415,12 @@ static const MXFLocalTagPair mxf_local_tag_batch[] = {
>      { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */
>      { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */
>      { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */
> +    { 0x3210, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x01,0x02,0x00}}, /* Transfer Characteristic */
>      { 0x320B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0E,0x00,0x00,0x00}}, /* Presentation Y offset */
>      { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
>      { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
> +    { 0x321A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x03,0x01,0x00}}, /* Coding Equations */
> +    { 0x3219, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x09,0x04,0x01,0x02,0x01,0x01,0x06,0x01,0x00}}, /* Color Primaries */
>      { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */
>      { 0x3215, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x05,0x01,0x13,0x00,0x00,0x00,0x00}}, /* Signal Standard */
>      // CDCI Picture Essence Descriptor

> @@ -576,11 +579,10 @@ static void mxf_free(AVFormatContext *s)
>      }
>  }
>  
> -static const MXFCodecUL *mxf_get_data_definition_ul(int type)
> +static const MXFCodecUL *mxf_get_ul_by_id(const MXFCodecUL *uls, int id)
>  {
> -    const MXFCodecUL *uls = ff_mxf_data_definition_uls;
>      while (uls->uid[0]) {
> -        if (type == uls->id)
> +        if (id == uls->id)
>              break;
>          uls++;
>      }
> @@ -835,7 +837,7 @@ static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
>      if (st == mxf->timecode_track)
>          avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
>      else {
> -        const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codecpar->codec_type);
> +        const MXFCodecUL *data_def_ul = mxf_get_ul_by_id(ff_mxf_data_definition_uls, st->codecpar->codec_type);
>          avio_write(pb, data_def_ul->uid, 16);
>      }
>  

refactoring the code to make it more generic belongs in a seperate
patch


> @@ -1011,6 +1013,9 @@ static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke
>  {
>      MXFStreamContext *sc = st->priv_data;
>      AVIOContext *pb = s->pb;
> +    const MXFCodecUL* color_trc_ul;
> +    const MXFCodecUL* color_primaries_ul;
> +    const MXFCodecUL* color_space_ul;
>      int stored_height = (st->codecpar->height+15)/16*16;
>      int display_height;
>      int f1, f2;
> @@ -1020,6 +1025,16 @@ static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke
>      if (sc->signal_standard)
>          desc_size += 5;
>  
> +    color_trc_ul = mxf_get_ul_by_id(ff_mxf_transfer_characteristics_uls, st->codecpar->color_trc);
> +    if (color_trc_ul->uid[0])
> +      desc_size += 20;
> +    color_primaries_ul = mxf_get_ul_by_id(ff_mxf_color_primaries_uls, st->codecpar->color_primaries);
> +    if (color_primaries_ul->uid[0])
> +      desc_size += 20;
> +    color_space_ul = mxf_get_ul_by_id(ff_mxf_coding_equations_uls, st->codecpar->color_space);
> +    if (color_space_ul->uid[0])
> +      desc_size += 20;

inconsistent indention

[...]
diff mbox

Patch

diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index e9c48e8..ea7c1db 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -84,6 +84,39 @@  const MXFCodecUL ff_mxf_codec_tag_uls[] = {
     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,                         0 },
 };
 
+const MXFCodecUL ff_mxf_transfer_characteristics_uls[] = {
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x01,0x00,0x00 }, 14, AVCOL_TRC_GAMMA22 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00 }, 14, AVCOL_TRC_BT709 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x03,0x00,0x00 }, 14, AVCOL_TRC_SMPTE240M },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x04,0x00,0x00 }, 14, AVCOL_TRC_BT709 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x05,0x00,0x00 }, 14, AVCOL_TRC_BT1361_ECG },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x06,0x00,0x00 }, 14, AVCOL_TRC_LINEAR },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x08,0x04,0x01,0x01,0x01,0x01,0x07,0x00,0x00 }, 14, AVCOL_TRC_SMPTEST428_1 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x08,0x00,0x00 }, 14, AVCOL_TRC_IEC61966_2_4 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0E,0x04,0x01,0x01,0x01,0x01,0x09,0x00,0x00 }, 14, AVCOL_TRC_BT2020_10 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x0A,0x00,0x00 }, 14, AVCOL_TRC_SMPTEST2084 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x01,0x0B,0x00,0x00 }, 14, AVCOL_TRC_ARIB_STD_B67 },
+    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0, AVCOL_TRC_RESERVED0 },
+};
+
+const MXFCodecUL ff_mxf_coding_equations_uls[] = {
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x02,0x01,0x00,0x00 }, 14, AVCOL_SPC_BT470BG },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x02,0x02,0x00,0x00 }, 14, AVCOL_SPC_BT709 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x02,0x03,0x00,0x00 }, 14, AVCOL_SPC_SMPTE240M },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x04,0x00,0x00 }, 14, AVCOL_SPC_YCOCG },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x05,0x00,0x00 }, 14, AVCOL_SPC_RGB },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x02,0x06,0x00,0x00 }, 14, AVCOL_SPC_BT2020_NCL },
+    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0, AVCOL_SPC_UNSPECIFIED },
+};
+
+const MXFCodecUL ff_mxf_color_primaries_uls[] = {
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x01,0x00,0x00 }, 14, AVCOL_PRI_SMPTE170M },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x02,0x00,0x00 }, 14, AVCOL_PRI_BT470M },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x03,0x03,0x00,0x00 }, 14, AVCOL_PRI_BT709 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x01,0x01,0x03,0x04,0x00,0x00 }, 14, AVCOL_PRI_BT2020 },
+    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0, AVCOL_PRI_RESERVED0 },
+};
+
 static const struct {
     enum AVPixelFormat pix_fmt;
     const char data[16];
diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index f3db1f9..1c9ca2a 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -79,6 +79,9 @@  extern const MXFCodecUL ff_mxf_data_definition_uls[];
 extern const MXFCodecUL ff_mxf_codec_uls[];
 extern const MXFCodecUL ff_mxf_pixel_format_uls[];
 extern const MXFCodecUL ff_mxf_codec_tag_uls[];
+extern const MXFCodecUL ff_mxf_transfer_characteristics_uls[];
+extern const MXFCodecUL ff_mxf_coding_equations_uls[];
+extern const MXFCodecUL ff_mxf_color_primaries_uls[];
 
 int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt);
 const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base);
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 1939761..d012e41 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -188,6 +188,9 @@  typedef struct MXFDescriptor {
     uint8_t *extradata;
     int extradata_size;
     enum AVPixelFormat pix_fmt;
+    UID color_trc_ul;
+    UID color_primaries_ul;
+    UID color_space_ul;
 } MXFDescriptor;
 
 typedef struct MXFIndexTableSegment {
@@ -1000,9 +1003,18 @@  static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
         descriptor->aspect_ratio.num = avio_rb32(pb);
         descriptor->aspect_ratio.den = avio_rb32(pb);
         break;
+    case 0x3210:
+        avio_read(pb, descriptor->color_trc_ul, 16);
+        break;
     case 0x3212:
         descriptor->field_dominance = avio_r8(pb);
         break;
+    case 0x3219:
+        avio_read(pb, descriptor->color_primaries_ul, 16);
+        break;
+    case 0x321A:
+        avio_read(pb, descriptor->color_space_ul, 16);
+        break;
     case 0x3301:
         descriptor->component_depth = avio_rb32(pb);
         break;
@@ -1853,6 +1865,9 @@  static int mxf_parse_structural_metadata(MXFContext *mxf)
         const MXFCodecUL *codec_ul = NULL;
         const MXFCodecUL *container_ul = NULL;
         const MXFCodecUL *pix_fmt_ul = NULL;
+        const MXFCodecUL *color_trc_ul = NULL;
+        const MXFCodecUL *color_primaries_ul = NULL;
+        const MXFCodecUL *color_space_ul = NULL;
         AVStream *st;
         AVTimecode tc;
         int flags;
@@ -2085,6 +2100,20 @@  static int mxf_parse_structural_metadata(MXFContext *mxf)
                     }
                 }
             }
+
+            color_primaries_ul = mxf_get_codec_ul(ff_mxf_color_primaries_uls,
+                                                  &descriptor->color_primaries_ul);
+            if (color_primaries_ul->uid[0])
+              st->codecpar->color_primaries = color_primaries_ul->id;
+            color_space_ul = mxf_get_codec_ul(ff_mxf_coding_equations_uls,
+                                              &descriptor->color_space_ul);
+            if (color_space_ul->uid[0])
+              st->codecpar->color_space = color_space_ul->id;
+            color_trc_ul = mxf_get_codec_ul(ff_mxf_transfer_characteristics_uls,
+                                            &descriptor->color_trc_ul);
+            if (color_trc_ul->uid[0])
+              st->codecpar->color_trc = color_trc_ul->id;
+
             st->need_parsing = AVSTREAM_PARSE_HEADERS;
             if (material_track->sequence->origin) {
                 av_dict_set_int(&st->metadata, "material_track_origin", material_track->sequence->origin, 0);
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 7733ef8..eb77f3a 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -415,9 +415,12 @@  static const MXFLocalTagPair mxf_local_tag_batch[] = {
     { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */
     { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */
     { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */
+    { 0x3210, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x01,0x02,0x00}}, /* Transfer Characteristic */
     { 0x320B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0E,0x00,0x00,0x00}}, /* Presentation Y offset */
     { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
     { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
+    { 0x321A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x03,0x01,0x00}}, /* Coding Equations */
+    { 0x3219, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x09,0x04,0x01,0x02,0x01,0x01,0x06,0x01,0x00}}, /* Color Primaries */
     { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */
     { 0x3215, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x05,0x01,0x13,0x00,0x00,0x00,0x00}}, /* Signal Standard */
     // CDCI Picture Essence Descriptor
@@ -576,11 +579,10 @@  static void mxf_free(AVFormatContext *s)
     }
 }
 
-static const MXFCodecUL *mxf_get_data_definition_ul(int type)
+static const MXFCodecUL *mxf_get_ul_by_id(const MXFCodecUL *uls, int id)
 {
-    const MXFCodecUL *uls = ff_mxf_data_definition_uls;
     while (uls->uid[0]) {
-        if (type == uls->id)
+        if (id == uls->id)
             break;
         uls++;
     }
@@ -835,7 +837,7 @@  static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
     if (st == mxf->timecode_track)
         avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
     else {
-        const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codecpar->codec_type);
+        const MXFCodecUL *data_def_ul = mxf_get_ul_by_id(ff_mxf_data_definition_uls, st->codecpar->codec_type);
         avio_write(pb, data_def_ul->uid, 16);
     }
 
@@ -1011,6 +1013,9 @@  static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke
 {
     MXFStreamContext *sc = st->priv_data;
     AVIOContext *pb = s->pb;
+    const MXFCodecUL* color_trc_ul;
+    const MXFCodecUL* color_primaries_ul;
+    const MXFCodecUL* color_space_ul;
     int stored_height = (st->codecpar->height+15)/16*16;
     int display_height;
     int f1, f2;
@@ -1020,6 +1025,16 @@  static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke
     if (sc->signal_standard)
         desc_size += 5;
 
+    color_trc_ul = mxf_get_ul_by_id(ff_mxf_transfer_characteristics_uls, st->codecpar->color_trc);
+    if (color_trc_ul->uid[0])
+      desc_size += 20;
+    color_primaries_ul = mxf_get_ul_by_id(ff_mxf_color_primaries_uls, st->codecpar->color_primaries);
+    if (color_primaries_ul->uid[0])
+      desc_size += 20;
+    color_space_ul = mxf_get_ul_by_id(ff_mxf_coding_equations_uls, st->codecpar->color_space);
+    if (color_space_ul->uid[0])
+      desc_size += 20;
+
     mxf_write_generic_desc(s, st, key, desc_size);
 
     mxf_write_local_tag(pb, 4, 0x3203);
@@ -1082,7 +1097,6 @@  static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke
         f1 *= 2;
     }
 
-
     mxf_write_local_tag(pb, 16, 0x320D);
     avio_wb32(pb, 2);
     avio_wb32(pb, 4);
@@ -1101,6 +1115,18 @@  static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke
         avio_w8(pb, sc->field_dominance);
     }
 
+    if (color_trc_ul->uid[0]) {
+      mxf_write_local_tag(pb, 16, 0x3210);
+      avio_write(pb, color_trc_ul->uid, 16);
+    }
+    if (color_primaries_ul->uid[0]) {
+      mxf_write_local_tag(pb, 16, 0x3219);
+      avio_write(pb, color_primaries_ul->uid, 16);
+    }
+    if (color_space_ul->uid[0]) {
+      mxf_write_local_tag(pb, 16, 0x321A);
+      avio_write(pb, color_space_ul->uid, 16);
+    }
 }
 
 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)