1
mirror of https://code.videolan.org/videolan/vlc synced 2024-10-03 01:31:53 +02:00

* src/audio_output/common.c: common facility for channel reordering (aout_CheckChannelReorder() and aout_ChannelReorder()).

This commit is contained in:
Gildas Bazin 2004-09-30 16:46:37 +00:00
parent 067ebc33ce
commit 17f16d7678
2 changed files with 106 additions and 0 deletions

View File

@ -98,6 +98,7 @@ typedef int32_t vlc_fixed_t;
#define AOUT_CHAN_REVERSESTEREO 0x40000
#define AOUT_CHAN_PHYSMASK 0xFFFF
#define AOUT_CHAN_MAX 9
/* Values used for the audio-device and audio-channels object variables */
#define AOUT_VAR_MONO 1
@ -167,6 +168,9 @@ VLC_EXPORT( void, aout_DateMove, ( audio_date_t *, mtime_t ) );
VLC_EXPORT( mtime_t, aout_DateGet, ( const audio_date_t * ) );
VLC_EXPORT( mtime_t, aout_DateIncrement, ( audio_date_t *, uint32_t ) );
VLC_EXPORT( int, aout_CheckChannelReorder, ( const uint32_t *, const uint32_t *, uint32_t, int, int * ) );
VLC_EXPORT( void, aout_ChannelReorder, ( uint8_t *, int, int, const int *, int ) );
/* From dec.c : */
#define aout_DecNew(a, b, c) __aout_DecNew(VLC_OBJECT(a), b, c)
VLC_EXPORT( aout_input_t *, __aout_DecNew, ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) );

View File

@ -464,3 +464,105 @@ mtime_t aout_DateIncrement( audio_date_t * p_date, uint32_t i_nb_samples )
return p_date->date;
}
/*****************************************************************************
* aout_CheckChannelReorder : Check if we need to do some channel re-ordering
*****************************************************************************/
int aout_CheckChannelReorder( const uint32_t *pi_chan_order_in,
const uint32_t *pi_chan_order_out,
uint32_t i_channel_mask,
int i_channels, int *pi_chan_table )
{
vlc_bool_t b_chan_reorder = VLC_FALSE;
int i, j, k, l;
if( i_channels > AOUT_CHAN_MAX ) return VLC_FALSE;
for( i = 0, j = 0; pi_chan_order_in[i]; i++ )
{
if( !(i_channel_mask & pi_chan_order_in[i]) ) continue;
for( k = 0, l = 0; pi_chan_order_in[i] != pi_chan_order_out[k]; k++ )
{
if( i_channel_mask & pi_chan_order_out[k] ) l++;
}
pi_chan_table[j++] = l;
}
for( i = 0; i < i_channels; i++ )
{
if( pi_chan_table[i] != i ) b_chan_reorder = VLC_TRUE;
}
return b_chan_reorder;
}
/*****************************************************************************
* aout_ChannelReorder :
*****************************************************************************/
void aout_ChannelReorder( uint8_t *p_buf, int i_buffer,
int i_channels, const int *pi_chan_table,
int i_bits_per_sample )
{
uint8_t p_tmp[AOUT_CHAN_MAX * 4];
int i, j;
if( i_bits_per_sample == 8 )
{
for( i = 0; i < i_buffer / i_channels; i++ )
{
for( j = 0; j < i_channels; j++ )
{
p_tmp[pi_chan_table[j]] = p_buf[j];
}
memcpy( p_buf, p_tmp, i_channels );
p_buf += i_channels;
}
}
else if( i_bits_per_sample == 16 )
{
for( i = 0; i < i_buffer / i_channels / 2; i++ )
{
for( j = 0; j < i_channels; j++ )
{
p_tmp[2 * pi_chan_table[j]] = p_buf[2 * j];
p_tmp[2 * pi_chan_table[j] + 1] = p_buf[2 * j + 1];
}
memcpy( p_buf, p_tmp, 2 * i_channels );
p_buf += 2 * i_channels;
}
}
else if( i_bits_per_sample == 24 )
{
for( i = 0; i < i_buffer / i_channels / 3; i++ )
{
for( j = 0; j < i_channels; j++ )
{
p_tmp[3 * pi_chan_table[j]] = p_buf[3 * j];
p_tmp[3 * pi_chan_table[j] + 1] = p_buf[3 * j + 1];
p_tmp[3 * pi_chan_table[j] + 2] = p_buf[3 * j + 2];
}
memcpy( p_buf, p_tmp, 3 * i_channels );
p_buf += 3 * i_channels;
}
}
else if( i_bits_per_sample == 32 )
{
for( i = 0; i < i_buffer / i_channels / 4; i++ )
{
for( j = 0; j < i_channels; j++ )
{
p_tmp[4 * pi_chan_table[j]] = p_buf[4 * j];
p_tmp[4 * pi_chan_table[j] + 1] = p_buf[4 * j + 1];
p_tmp[4 * pi_chan_table[j] + 2] = p_buf[4 * j + 2];
p_tmp[4 * pi_chan_table[j] + 3] = p_buf[4 * j + 3];
}
memcpy( p_buf, p_tmp, 4 * i_channels );
p_buf += 4 * i_channels;
}
}
}