[vlc-devel] [RFCv2] dcp: Audio channels reordering

Nicolas Bertrand nicoinattendu at gmail.com
Mon Dec 9 23:50:43 CET 2013


Rewrite of channels configuration according number of channels
Is compliant with SMPTE S428-3 and get rid of asdcplib bug on
channels config

---
 modules/access/dcp/dcp.cpp |  119 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 94 insertions(+), 25 deletions(-)

diff --git a/modules/access/dcp/dcp.cpp b/modules/access/dcp/dcp.cpp
index bb7dee9..516968d 100644
--- a/modules/access/dcp/dcp.cpp
+++ b/modules/access/dcp/dcp.cpp
@@ -43,6 +43,7 @@
 #include <vlc_plugin.h>
 #include <vlc_xml.h>
 #include <vlc_url.h>
+#include <vlc_aout.h>
 
 /* ASDCP headers */
 #include <AS_DCP.h>
@@ -133,6 +134,10 @@ class demux_sys_t
     /* total number of frames */
     uint32_t frames_total;
 
+    uint8_t i_chans_to_reorder;            /* do we need channel reordering */
+    uint8_t pi_chan_table[AOUT_CHAN_MAX];
+    uint8_t i_channels;
+
     mtime_t i_pts;
 
     demux_sys_t():
@@ -168,6 +173,55 @@ class demux_sys_t
     }
 };
 
+/*TODO: basic correlation between SMPTE S428-3/S429-2
+ * Real sound is more complex with case of left/right surround, ...
+ * and hearing impaired/Narration channels */
+#define NB_AUDIO_CONFIGS 10
+static const uint32_t pi_channels_aout[NB_AUDIO_CONFIGS][9] = {
+    /* Dummy, no channels */
+    {0},
+    /* 1 channel: mono */
+    {0,0, AOUT_CHAN_LEFT},
+    /* 2 channels: stereo */
+    { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0},
+    /* 3 channels: dummy */
+    {0},
+    /* 4 channels */
+    { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
+    AOUT_CHAN_LFE, 0},
+    /* 5 channels: dummy */
+    {0},
+    /* 6 channels: 5.1 */
+    { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,      AOUT_CHAN_CENTER,
+      AOUT_CHAN_LFE,  AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,
+     0 ,              0,                    0 },
+    /* 7 channels: 6.1 */
+    { AOUT_CHAN_LEFT,       AOUT_CHAN_RIGHT,    AOUT_CHAN_CENTER,
+      AOUT_CHAN_LFE,        AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
+      AOUT_CHAN_REARCENTER, 0,                  0  },
+    /* 8 channels:  7.1 */
+    { AOUT_CHAN_LEFT,        AOUT_CHAN_RIGHT,      AOUT_CHAN_CENTER,
+      AOUT_CHAN_LFE,         AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,
+      AOUT_CHAN_MIDDLELEFT,  AOUT_CHAN_MIDDLELEFT, 0 },
+    /* 9 channels */
+   { AOUT_CHAN_LEFT,        AOUT_CHAN_RIGHT,      AOUT_CHAN_CENTER,
+      AOUT_CHAN_LFE,         AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,
+      AOUT_CHAN_MIDDLELEFT,  AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_REARCENTER },
+};
+
+static const unsigned i_channel_mask[NB_AUDIO_CONFIGS] = {
+    0,
+    AOUT_CHAN_LEFT,
+    AOUT_CHANS_STEREO,
+    0,
+    AOUT_CHANS_3_1,
+    0,
+    AOUT_CHANS_5_1,
+    AOUT_CHANS_6_1_MIDDLE,
+    AOUT_CHANS_7_1,
+    AOUT_CHANS_8_1
+} ;
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -352,39 +406,49 @@ static int Open( vlc_object_t *obj )
 
         p_AudioMXFReader->FillAudioDescriptor( *p_AudioDesc );
 
-        es_format_Init( &audio_format, AUDIO_ES, VLC_CODEC_S24L );
-        if( p_AudioDesc->AudioSamplingRate.Denominator != 0 )
-            audio_format.audio.i_rate =
-                  p_AudioDesc->AudioSamplingRate.Numerator
-                / p_AudioDesc->AudioSamplingRate.Denominator;
-        else if ( AudioEssType == ESS_PCM_24b_96k )
-            audio_format.audio.i_rate = 96000;
-        else
-            audio_format.audio.i_rate = 48000;
-
-        audio_format.audio.i_bitspersample = p_AudioDesc->QuantizationBits;
-        audio_format.audio.i_blockalign    = p_AudioDesc->BlockAlign;
-        audio_format.audio.i_channels      = p_AudioDesc->ChannelCount;
-
-        p_sys->i_audio_buffer = PCM::CalcFrameBufferSize(*p_AudioDesc);
-
-        if( ( p_sys->p_audio_es = es_out_Add( p_demux->out, &audio_format ) ) == NULL ) {
-            msg_Err( p_demux, "Failed to add audio es" );
-            retval = VLC_EGENERIC;
-            delete p_AudioDesc;
+        if (p_AudioDesc->ChannelCount > NB_AUDIO_CONFIGS) {
+            msg_Err(p_demux, " DCP module support not support %i channels",
+                p_AudioDesc->ChannelCount);
             delete p_AudioMXFReader;
-            goto error;
+        } else {
+            es_format_Init( &audio_format, AUDIO_ES, VLC_CODEC_S24L );
+            if( p_AudioDesc->AudioSamplingRate.Denominator != 0 )
+                audio_format.audio.i_rate =
+                    p_AudioDesc->AudioSamplingRate.Numerator
+                    / p_AudioDesc->AudioSamplingRate.Denominator;
+            else if ( AudioEssType == ESS_PCM_24b_96k )
+                audio_format.audio.i_rate = 96000;
+            else
+                audio_format.audio.i_rate = 48000;
+
+            audio_format.audio.i_bitspersample = p_AudioDesc->QuantizationBits;
+            audio_format.audio.i_blockalign    = p_AudioDesc->BlockAlign;
+            audio_format.audio.i_channels      =
+                p_sys->i_channels                  = p_AudioDesc->ChannelCount;
+            p_sys->i_audio_buffer = PCM::CalcFrameBufferSize(*p_AudioDesc);
+
+            /* Manage channel orders */
+            p_sys->i_chans_to_reorder =  aout_CheckChannelReorder(
+                    pi_channels_aout[ p_AudioDesc->ChannelCount], NULL,
+                    i_channel_mask[p_AudioDesc->ChannelCount],
+                    p_sys->pi_chan_table );
+
+            if( ( p_sys->p_audio_es = es_out_Add( p_demux->out, &audio_format ) ) == NULL ) {
+                msg_Err( p_demux, "Failed to add audio es" );
+                retval = VLC_EGENERIC;
+                delete p_AudioDesc;
+                delete p_AudioMXFReader;
+                goto error;
+            }
+            p_sys->p_AudioMXFReader = p_AudioMXFReader;
         }
-        p_sys->p_AudioMXFReader = p_AudioMXFReader;
         delete p_AudioDesc;
     } else {
         msg_Err( p_demux, "The file %s is not a supported AS_DCP essence container",
-                          p_sys->p_dcp->audiofile.c_str() );
+                p_sys->p_dcp->audiofile.c_str() );
         retval = VLC_EGENERIC;
         goto error;
     }
-
-
     p_sys->p_out = p_demux->out;
     p_demux->pf_demux = Demux;
     p_demux->pf_control = Control;
@@ -489,6 +553,11 @@ static int Demux( demux_t *p_demux )
         goto error_asdcp;
     }
 
+    if( p_sys->i_chans_to_reorder )
+        aout_ChannelReorder( p_audio_frame->p_buffer, p_audio_frame->i_buffer,
+                p_sys->i_channels,
+                p_sys->pi_chan_table, VLC_CODEC_S24L );
+
     p_audio_frame->i_buffer = AudioFrameBuff.Size();
     p_audio_frame->i_length = CLOCK_FREQ * p_sys->frame_rate_denom / p_sys->frame_rate_num;
     p_audio_frame->i_pts = CLOCK_FREQ * p_sys->frame_no * p_sys->frame_rate_denom / p_sys->frame_rate_num;
-- 
1.7.9.5




More information about the vlc-devel mailing list