[vlc-devel] [PATCH] mp4: Handle colr atom

Hugo Beauzée-Luyssen hugo at beauzee.fr
Sat Apr 16 17:07:26 CEST 2016


---
 modules/demux/mp4/essetup.c | 29 +++++++++++++++++++++++++++++
 modules/demux/mp4/libmp4.c  | 24 ++++++++++++++++++++++++
 modules/demux/mp4/libmp4.h  | 30 ++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+)

diff --git a/modules/demux/mp4/essetup.c b/modules/demux/mp4/essetup.c
index b88728d..16f0c15 100644
--- a/modules/demux/mp4/essetup.c
+++ b/modules/demux/mp4/essetup.c
@@ -411,6 +411,35 @@ int SetupVideoES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
         p_track->i_block_flags = BOXDATA(p_fiel)->i_flags;
     }
 
+    const MP4_Box_t *p_colr = MP4_BoxGet( p_sample, "colr" );
+    if ( p_colr != NULL )
+    {
+        if ( BOXDATA(p_colr)->i_type == ATOM_nclc || BOXDATA(p_colr)->i_type == ATOM_nclx )
+        {
+            bool b_fullrange = BOXDATA(p_colr)->i_type == ATOM_nclx &&
+                    (BOXDATA(p_colr)->nclx.i_full_range >> 7) != 0;
+
+            switch ( BOXDATA( p_colr )->nclc.i_primary_idx )
+            {
+            case 1: p_track->fmt.video.primaries = COLOR_PRIMARIES_BT709; break;
+            case 5: p_track->fmt.video.primaries = COLOR_PRIMARIES_BT601_625; break;
+            case 6: p_track->fmt.video.primaries = COLOR_PRIMARIES_BT601_525; break;
+            default: p_track->fmt.video.primaries = COLOR_PRIMARIES_UNDEF; break;
+            }
+            switch ( BOXDATA( p_colr )->nclc.i_transfer_function_idx )
+            {
+            case 1: p_track->fmt.video.transfer = TRANSFER_FUNC_BT709; break;
+            default: p_track->fmt.video.transfer = TRANSFER_FUNC_UNDEF; break;
+            }
+            switch ( BOXDATA( p_colr )->nclc.i_matrix_idx )
+            {
+            case 1: p_track->fmt.video.space = b_fullrange ? COLOR_SPACE_BT709_FULL : COLOR_SPACE_BT709_LIMITED; break;
+            case 2: p_track->fmt.video.space = b_fullrange ? COLOR_SPACE_BT601_FULL : COLOR_SPACE_BT601_LIMITED; break;
+            default: p_track->fmt.video.space = COLOR_SPACE_UNDEF; break;
+            }
+        }
+    }
+
     SetupGlobalExtensions( p_track, p_sample );
 
     /* now see if esds is present and if so create a data packet
diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 84f97a1..2aa02b2 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -3460,6 +3460,28 @@ static int MP4_ReadBox_keys( stream_t *p_stream, MP4_Box_t *p_box )
     MP4_READBOX_EXIT( 1 );
 }
 
+static int MP4_ReadBox_colr( stream_t *p_stream, MP4_Box_t *p_box )
+{
+    MP4_READBOX_ENTER( MP4_Box_data_colr_t, NULL );
+    MP4_GETFOURCC( p_box->data.p_colr->i_type );
+    if ( p_box->data.p_colr->i_type == ATOM_nclc || p_box->data.p_colr->i_type == ATOM_nclx )
+    {
+        MP4_GET2BYTES( p_box->data.p_colr->nclc.i_primary_idx );
+        MP4_GET2BYTES( p_box->data.p_colr->nclc.i_transfer_function_idx );
+        MP4_GET2BYTES( p_box->data.p_colr->nclc.i_matrix_idx );
+        if ( p_box->data.p_colr->i_type == ATOM_nclx )
+            MP4_GET1BYTE( p_box->data.p_colr->nclx.i_full_range );
+    }
+    else
+    {
+#ifdef MP4_VERBOSE
+        msg_Warn( p_stream, "Unhandled colr type: %4.4s", (char*)&p_box->data.p_colr->i_type );
+#endif
+        MP4_READBOX_EXIT( 0 );
+    }
+    MP4_READBOX_EXIT( 1 );
+}
+
 static int MP4_ReadBox_meta( stream_t *p_stream, MP4_Box_t *p_box )
 {
     uint8_t meta_data[8];
@@ -3952,6 +3974,8 @@ static const struct
     { ATOM_pasp,    MP4_ReadBox_pasp,         0 },
     { ATOM_btrt,    MP4_ReadBox_btrt,         0 }, /* codecs bitrate stsd/????/btrt */
     { ATOM_keys,    MP4_ReadBox_keys,         ATOM_meta },
+    { ATOM_colr,    MP4_ReadBox_colr,         0 },
+
 
     /* Samples groups specific information */
     { ATOM_sbgp,    MP4_ReadBox_sbgp,         ATOM_stbl },
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index a170456..fb0ada5 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -343,6 +343,9 @@ typedef int64_t stime_t;
 #define ATOM_gssd VLC_FOURCC( 'g', 's', 's', 'd' )
 #define ATOM_gsst VLC_FOURCC( 'g', 's', 's', 't' )
 #define ATOM_gstd VLC_FOURCC( 'g', 's', 't', 'd' )
+#define ATOM_colr VLC_FOURCC( 'c', 'o', 'l', 'r' )
+#define ATOM_nclc VLC_FOURCC( 'n', 'c', 'l', 'c' )
+#define ATOM_nclx VLC_FOURCC( 'n', 'c', 'l', 'x' )
 
 #define ATOM_0x40PRM VLC_FOURCC( '@', 'P', 'R', 'M' )
 #define ATOM_0x40PRQ VLC_FOURCC( '@', 'P', 'R', 'Q' )
@@ -581,6 +584,32 @@ typedef struct MP4_Box_data_ctts_s
 
 } MP4_Box_data_ctts_t;
 
+// https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-125526
+
+typedef struct MP4_Box_Data_nclc_s
+{
+    uint16_t i_primary_idx;
+    uint16_t i_transfer_function_idx;
+    uint16_t i_matrix_idx;
+} MP4_Box_Data_nclc_t;
+
+typedef struct MP4_Box_Data_nclx_s
+{
+    uint16_t i_primary_idx;
+    uint16_t i_transfer_function_idx;
+    uint16_t i_matrix_idx;
+    uint8_t i_full_range;
+} MP4_Box_Data_nclx_t;
+
+typedef struct MP4_Box_data_colr_s
+{
+    uint32_t i_type;
+    union
+    {
+        MP4_Box_Data_nclc_t nclc;
+        MP4_Box_Data_nclx_t nclx;
+    };
+} MP4_Box_data_colr_t;
 
 typedef struct MP4_Box_data_sample_soun_s
 {
@@ -1521,6 +1550,7 @@ typedef union MP4_Box_data_s
     MP4_Box_data_lcont_t *p_lcont;
     MP4_Box_data_stts_t *p_stts;
     MP4_Box_data_ctts_t *p_ctts;
+    MP4_Box_data_colr_t *p_colr;
 
     MP4_Box_data_sbgp_t *p_sbgp;
     MP4_Box_data_sgpd_t *p_sgpd;
-- 
2.8.0.rc3



More information about the vlc-devel mailing list