[vlc-devel] [PATCH 2/2] codec: araw: add an option to specify the channel order

Rémi Denis-Courmont remi at remlab.net
Tue Jan 16 17:06:33 CET 2018


Le 16 janvier 2018 17:27:11 GMT+02:00, Thomas Guillem <thomas at gllm.fr> a écrit :
>The default channel order is still WG4, but this can be changed to WAVE
>for the
>encoder or the decoder. This can be used by sout commands to use the
>WAVE
>channel order. Example: 'transcode{acodec=s16l,aenc=araw{order=1}}'.
>---
>modules/codec/araw.c | 136
>+++++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 116 insertions(+), 20 deletions(-)
>
>diff --git a/modules/codec/araw.c b/modules/codec/araw.c
>index 0d8145527a..2c380f2d37 100644
>--- a/modules/codec/araw.c
>+++ b/modules/codec/araw.c
>@@ -42,8 +42,20 @@
> static int  DecoderOpen ( vlc_object_t * );
> static void DecoderClose( vlc_object_t * );
> 
>+#define ARAW_ORDER_TEXT N_("PCM channels order")
>+
>+#define ARAW_CFG_PREFIX "araw-"
>+#define ARAW_ORDER_WG4 0
>+#define ARAW_ORDER_WAVE 1
>+static const int order_list[] = { ARAW_ORDER_WG4, ARAW_ORDER_WAVE };
>+static const char *order_list_text[] = {
>+  N_("WG4 (DVD) order"),
>+  N_("Wave order"),
>+};
>+
> #ifdef ENABLE_SOUT
> static int  EncoderOpen ( vlc_object_t * );
>+static void  EncoderClose ( vlc_object_t * );
> #endif
> 
> vlc_module_begin ()
>@@ -53,16 +65,25 @@ vlc_module_begin ()
>     set_category( CAT_INPUT )
>     set_subcategory( SUBCAT_INPUT_ACODEC )
>     set_callbacks( DecoderOpen, DecoderClose )
>+    add_integer( ARAW_CFG_PREFIX "order", ARAW_ORDER_WG4,
>+                 ARAW_ORDER_TEXT, NULL, true )
>+    change_integer_list( order_list, order_list_text )
> 
> #ifdef ENABLE_SOUT
>     /* audio encoder submodule */
>     add_submodule ()
>     set_description( N_("Raw audio encoder") )
>     set_capability( "encoder", 150 )
>-    set_callbacks( EncoderOpen, NULL )
>+    set_callbacks( EncoderOpen, EncoderClose )
> #endif
> vlc_module_end ()
> 
>+#ifdef ENABLE_SOUT
>+static const char *const ppsz_enc_options[] = {
>+    "order", NULL
>+};
>+#endif
>+
>/*****************************************************************************
>  * Local prototypes
>*****************************************************************************/
>@@ -72,6 +93,8 @@ static void Flush( decoder_t * );
> struct decoder_sys_t
> {
>     void (*decode) (void *, const uint8_t *, unsigned);
>+    uint8_t chans_table[AOUT_CHAN_MAX];
>+    uint8_t chans_to_reorder;
>     size_t framebits;
>     date_t end_date;
> };
>@@ -106,6 +129,41 @@ static void F64NDecode( void *, const uint8_t *,
>unsigned );
> static void F64IDecode( void *, const uint8_t *, unsigned );
> static void DAT12Decode( void *, const uint8_t *, unsigned );
> 
>+static unsigned
>+SetupChanOrder( vlc_object_t *p_this, bool decode,
>+                  uint32_t mask, uint8_t *restrict table )
>+{
>+    switch( var_InheritInteger( p_this, ARAW_CFG_PREFIX "order" ) )
>+    {
>+        case ARAW_ORDER_WAVE:
>+        {
>+            static const uint32_t wave_order[] = {
>+                AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
>+                AOUT_CHAN_CENTER, AOUT_CHAN_LFE,
>+                AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
>AOUT_CHAN_REARCENTER,
>+                AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, 0
>+            };
>+            const uint32_t *chans_in;
>+            const uint32_t *chans_out;
>+            if( decode )
>+            {
>+                chans_in = wave_order;
>+                chans_out = pi_vlc_chan_order_wg4;
>+            }
>+            else
>+            {
>+                chans_in = pi_vlc_chan_order_wg4;
>+                chans_out = wave_order;
>+            }
>+            return aout_CheckChannelReorder( chans_in, chans_out,
>mask, table );
>+        }
>+        default:
>+        case ARAW_ORDER_WG4:
>+            return 0;
>+    }
>+}
>+
>+
>/*****************************************************************************
>  * DecoderOpen: probe the decoder and return score
>*****************************************************************************/
>@@ -285,13 +343,19 @@ static int DecoderOpen( vlc_object_t *p_this )
>         else
>             p_dec->fmt_out.audio.i_physical_channels =
>                      pi_channels_maps[p_dec->fmt_in.audio.i_channels];
>+        p_sys->chans_to_reorder =
>+            SetupChanOrder( p_this, false,
>p_dec->fmt_out.audio.i_physical_channels,
>+                            p_sys->chans_table );
>     }
>     else
>     {
>      /* Unknown channel map, let the aout/filters decide what to do */
>      p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
>         p_dec->fmt_out.audio.i_physical_channels = 0;
>+        p_sys->chans_to_reorder = 0;
>     }
>+
>+
>     aout_FormatPrepare( &p_dec->fmt_out.audio );
> 
>     p_sys->decode = decode;
>@@ -370,6 +434,11 @@ static int DecodeBlock( decoder_t *p_dec, block_t
>*p_block )
>         p_block->i_buffer = samples * (p_sys->framebits / 8);
>     }
> 
>+    if( p_sys->chans_to_reorder )
>+        aout_ChannelReorder( p_block->p_buffer, p_block->i_buffer,
>+                             p_sys->chans_to_reorder,
>p_sys->chans_table,
>+                             p_dec->fmt_out.i_codec );
>+
>     p_block->i_pts = date_Get( &p_sys->end_date );
>     p_block->i_length = date_Increment( &p_sys->end_date, samples )
>                       - p_block->i_pts;
>@@ -652,6 +721,13 @@ static void DecoderClose( vlc_object_t *p_this )
> }
> 
> #ifdef ENABLE_SOUT
>+struct encoder_sys_t
>+{
>+    void (*encode)(void *, const uint8_t *, unsigned);
>+    uint8_t chans_table[AOUT_CHAN_MAX];
>+    uint8_t chans_to_reorder;
>+};
>+
>/* NOTE: Output buffers are always aligned since they are allocated by
>the araw plugin.
>* Contrary to the decoder, the encoder can also assume that input
>buffers are aligned,
>  * since decoded audio blocks must always be aligned. */
>@@ -805,14 +881,18 @@ static block_t *Encode( encoder_t *enc, block_t
>*in )
>     out->i_pts        = in->i_pts;
>     out->i_length     = in->i_length;
> 
>-    void (*encode)(void *, const uint8_t *, unsigned) = (void
>*)enc->p_sys;
>-    if( encode != NULL )
>-        encode( out->p_buffer, in->p_buffer, in->i_nb_samples
>-                                             *
>enc->fmt_out.audio.i_channels );
>+    encoder_sys_t *p_sys = enc->p_sys;
>+    if( p_sys->encode != NULL )
>+        p_sys->encode( out->p_buffer, in->p_buffer, in->i_nb_samples
>+                       * enc->fmt_out.audio.i_channels );
>     else {
>         assert( out->i_buffer >= in->i_buffer );
>         memcpy( out->p_buffer, in->p_buffer, in->i_buffer );
>     }
>+    if( p_sys->chans_to_reorder )
>+        aout_ChannelReorder( out->p_buffer, out->i_buffer,
>+                             p_sys->chans_to_reorder,
>p_sys->chans_table,
>+                             enc->fmt_out.i_codec );
>     return out;
> }
> 
>@@ -822,66 +902,76 @@ static block_t *Encode( encoder_t *enc, block_t
>*in )
> static int EncoderOpen( vlc_object_t *p_this )
> {
>     encoder_t *p_enc = (encoder_t *)p_this;
>-    void (*encode)(void *, const uint8_t *, unsigned) = NULL;
>+
>+    config_ChainParse( p_this, ARAW_CFG_PREFIX, ppsz_enc_options,
>p_enc->p_cfg );
>+
>+    struct encoder_sys_t *p_sys = malloc(sizeof(struct
>encoder_sys_t));
>+    if( !p_sys )
>+        return VLC_ENOMEM;
>+
>+    p_sys->chans_to_reorder =
>+        SetupChanOrder( p_this, false,
>p_enc->fmt_in.audio.i_physical_channels,
>+                        p_sys->chans_table );
>+    p_sys->encode = NULL;
> 
>     switch( p_enc->fmt_out.i_codec )
>     {
>     case VLC_CODEC_S8:
>-        encode = S8Decode;
>+        p_sys->encode = S8Decode;
>         /* fall through */
>     case VLC_CODEC_U8:
>         p_enc->fmt_in.i_codec = VLC_CODEC_U8;
>         p_enc->fmt_out.audio.i_bitspersample = 8;
>         break;
>     case VLC_CODEC_U16I:
>-        encode = U16IEncode;
>+        p_sys->encode = U16IEncode;
>         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
>         p_enc->fmt_out.audio.i_bitspersample = 16;
>         break;
>     case VLC_CODEC_U16N:
>-        encode = U16NEncode;
>+        p_sys->encode = U16NEncode;
>         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
>         p_enc->fmt_out.audio.i_bitspersample = 16;
>         break;
>     case VLC_CODEC_S16I:
>-        encode = S16IDecode;
>+        p_sys->encode = S16IDecode;
>         /* fall through */
>     case VLC_CODEC_S16N:
>         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
>         p_enc->fmt_out.audio.i_bitspersample = 16;
>         break;
>     case VLC_CODEC_U24B:
>-        encode = U24BEncode;
>+        p_sys->encode = U24BEncode;
>         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
>         p_enc->fmt_out.audio.i_bitspersample = 24;
>         break;
>     case VLC_CODEC_U24L:
>-        encode = U24LEncode;
>+        p_sys->encode = U24LEncode;
>         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
>         p_enc->fmt_out.audio.i_bitspersample = 24;
>         break;
>     case VLC_CODEC_S24B:
>-        encode = S24BEncode;
>+        p_sys->encode = S24BEncode;
>         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
>         p_enc->fmt_out.audio.i_bitspersample = 24;
>         break;
>     case VLC_CODEC_S24L:
>-        encode = S24LEncode;
>+        p_sys->encode = S24LEncode;
>         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
>         p_enc->fmt_out.audio.i_bitspersample = 24;
>         break;
>     case VLC_CODEC_U32I:
>-        encode = U32IEncode;
>+        p_sys->encode = U32IEncode;
>         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
>         p_enc->fmt_out.audio.i_bitspersample = 32;
>         break;
>     case VLC_CODEC_U32N:
>-        encode = U32NEncode;
>+        p_sys->encode = U32NEncode;
>         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
>         p_enc->fmt_out.audio.i_bitspersample = 32;
>         break;
>     case VLC_CODEC_S32I:
>-        encode = S32IEncode;
>+        p_sys->encode = S32IEncode;
>         /* fall through */
>     case VLC_CODEC_S32N:
>         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
>@@ -892,7 +982,7 @@ static int EncoderOpen( vlc_object_t *p_this )
> #else
>     case VLC_CODEC_F32B:
> #endif
>-        encode = F32IEncode;
>+        p_sys->encode = F32IEncode;
>         /* fall through */
>     case VLC_CODEC_FL32:
>         p_enc->fmt_in.i_codec = VLC_CODEC_FL32;
>@@ -903,7 +993,7 @@ static int EncoderOpen( vlc_object_t *p_this )
> #else
>     case VLC_CODEC_F64B:
> #endif
>-        encode = F64IEncode;
>+        p_sys->encode = F64IEncode;
>         /* fall through */
>     case VLC_CODEC_FL64:
>         p_enc->fmt_in.i_codec = VLC_CODEC_FL64;
>@@ -913,7 +1003,7 @@ static int EncoderOpen( vlc_object_t *p_this )
>         return VLC_EGENERIC;
>     }
> 
>-    p_enc->p_sys = (void *)encode;
>+    p_enc->p_sys = p_sys;
>     p_enc->pf_encode_audio = Encode;
>     p_enc->fmt_out.audio.i_bytes_per_frame =
>         (p_enc->fmt_out.audio.i_bitspersample / 8) *
>@@ -929,4 +1019,10 @@ static int EncoderOpen( vlc_object_t *p_this )
> 
>     return VLC_SUCCESS;
> }
>+
>+static void  EncoderClose ( vlc_object_t *p_this )
>+{
>+    encoder_t *p_enc = (encoder_t *)p_this;
>+    free( p_enc->p_sys );
>+}
> #endif /* ENABLE_SOUT */
>-- 
>2.11.0
>
>_______________________________________________
>vlc-devel mailing list
>To unsubscribe or modify your subscription options:
>https://mailman.videolan.org/listinfo/vlc-devel

Supporting multiple channel orders is pretty pointless IMO. It adds a lot of complexity for negligible performance gains.

We have a lot of pain with RGB masks... I would rather not reproduce that mistake with audio.
-- 
Remi Denis-Courmont


More information about the vlc-devel mailing list