📄 common.c
字号:
/***************************************************************************** * aout_FifoInit : initialize the members of a FIFO *****************************************************************************/void aout_FifoInit( aout_instance_t * p_aout, aout_fifo_t * p_fifo, uint32_t i_rate ){ p_fifo->p_first = NULL; p_fifo->pp_last = &p_fifo->p_first; aout_DateInit( &p_fifo->end_date, i_rate );}/***************************************************************************** * aout_FifoPush : push a packet into the FIFO *****************************************************************************/void aout_FifoPush( aout_instance_t * p_aout, aout_fifo_t * p_fifo, aout_buffer_t * p_buffer ){ *p_fifo->pp_last = p_buffer; p_fifo->pp_last = &p_buffer->p_next; *p_fifo->pp_last = NULL; /* Enforce the continuity of the stream. */ if ( aout_DateGet( &p_fifo->end_date ) ) { p_buffer->start_date = aout_DateGet( &p_fifo->end_date ); p_buffer->end_date = aout_DateIncrement( &p_fifo->end_date, p_buffer->i_nb_samples ); } else { aout_DateSet( &p_fifo->end_date, p_buffer->end_date ); }}/***************************************************************************** * aout_FifoSet : set end_date and trash all buffers (because they aren't * properly dated) *****************************************************************************/void aout_FifoSet( aout_instance_t * p_aout, aout_fifo_t * p_fifo, mtime_t date ){ aout_buffer_t * p_buffer; aout_DateSet( &p_fifo->end_date, date ); p_buffer = p_fifo->p_first; while ( p_buffer != NULL ) { aout_buffer_t * p_next = p_buffer->p_next; aout_BufferFree( p_buffer ); p_buffer = p_next; } p_fifo->p_first = NULL; p_fifo->pp_last = &p_fifo->p_first;}/***************************************************************************** * aout_FifoMoveDates : Move forwards or backwards all dates in the FIFO *****************************************************************************/void aout_FifoMoveDates( aout_instance_t * p_aout, aout_fifo_t * p_fifo, mtime_t difference ){ aout_buffer_t * p_buffer; aout_DateMove( &p_fifo->end_date, difference ); p_buffer = p_fifo->p_first; while ( p_buffer != NULL ) { p_buffer->start_date += difference; p_buffer->end_date += difference; p_buffer = p_buffer->p_next; }}/***************************************************************************** * aout_FifoNextStart : return the current end_date *****************************************************************************/mtime_t aout_FifoNextStart( aout_instance_t * p_aout, aout_fifo_t * p_fifo ){ return aout_DateGet( &p_fifo->end_date );}/***************************************************************************** * aout_FifoFirstDate : return the playing date of the first buffer in the * FIFO *****************************************************************************/mtime_t aout_FifoFirstDate( aout_instance_t * p_aout, aout_fifo_t * p_fifo ){ return p_fifo->p_first ? p_fifo->p_first->start_date : 0;}/***************************************************************************** * aout_FifoPop : get the next buffer out of the FIFO *****************************************************************************/aout_buffer_t * aout_FifoPop( aout_instance_t * p_aout, aout_fifo_t * p_fifo ){ aout_buffer_t * p_buffer; p_buffer = p_fifo->p_first; if ( p_buffer == NULL ) return NULL; p_fifo->p_first = p_buffer->p_next; if ( p_fifo->p_first == NULL ) { p_fifo->pp_last = &p_fifo->p_first; } return p_buffer;}/***************************************************************************** * aout_FifoDestroy : destroy a FIFO and its buffers *****************************************************************************/void aout_FifoDestroy( aout_instance_t * p_aout, aout_fifo_t * p_fifo ){ aout_buffer_t * p_buffer; p_buffer = p_fifo->p_first; while ( p_buffer != NULL ) { aout_buffer_t * p_next = p_buffer->p_next; aout_BufferFree( p_buffer ); p_buffer = p_next; } p_fifo->p_first = NULL; p_fifo->pp_last = &p_fifo->p_first;}/* * Date management (internal and external) *//***************************************************************************** * aout_DateInit : set the divider of an audio_date_t *****************************************************************************/void aout_DateInit( audio_date_t * p_date, uint32_t i_divider ){ p_date->date = 0; p_date->i_divider = i_divider; p_date->i_remainder = 0;}/***************************************************************************** * aout_DateSet : set the date of an audio_date_t *****************************************************************************/void aout_DateSet( audio_date_t * p_date, mtime_t new_date ){ p_date->date = new_date; p_date->i_remainder = 0;}/***************************************************************************** * aout_DateMove : move forwards or backwards the date of an audio_date_t *****************************************************************************/void aout_DateMove( audio_date_t * p_date, mtime_t difference ){ p_date->date += difference;}/***************************************************************************** * aout_DateGet : get the date of an audio_date_t *****************************************************************************/mtime_t aout_DateGet( const audio_date_t * p_date ){ return p_date->date;}/***************************************************************************** * aout_DateIncrement : increment the date and return the result, taking * into account rounding errors *****************************************************************************/mtime_t aout_DateIncrement( audio_date_t * p_date, uint32_t i_nb_samples ){ mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000; p_date->date += i_dividend / p_date->i_divider; p_date->i_remainder += (int)(i_dividend % p_date->i_divider); if ( p_date->i_remainder >= p_date->i_divider ) { /* This is Bresenham algorithm. */ p_date->date++; p_date->i_remainder -= p_date->i_divider; } 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; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -