[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