[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