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

Thomas Guillem thomas at gllm.fr
Tue Jan 16 16:28:24 CET 2018


Question: Should we use the WAVE order by default for the araw module ?

It is more likely to find PCM with WAVE order in the wild, no ?

On Tue, Jan 16, 2018, at 16:27, Thomas Guillem wrote:
> 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


More information about the vlc-devel mailing list