static void
Play( audio_output_t *p_aout, block_t *p_buffer )
{
JNIEnv *env = NULL;
size_t i_buffer_offset = 0 ;
aout_sys_t *p_sys = p_aout->sys;
//去掉IEC61937的包头
if ( p_sys->b_passthrough && p_sys->fmt.i_format == VLC_CODEC_SPDIFB
&& ConvertFromIEC61937( p_aout, p_buffer ) != 0 )
{
block_Release(p_buffer);
return ;
}
vlc_mutex_lock( &p_sys->lock );
if ( p_sys->b_error || !( env = GET_ENV() ) )
goto bailout;
if ( p_sys->i_chans_to_reorder )
aout_ChannelReorder( p_buffer->p_buffer, p_buffer->i_buffer,
p_sys->i_chans_to_reorder, p_sys->p_chan_table,
p_sys->fmt.i_format );
//将数据写到RingBuffer中
while ( i_buffer_offset < p_buffer->i_buffer && !p_sys->b_error )
{
size_t i_circular_free;
size_t i_data_offset;
size_t i_data_size;
/* Wait for enough room in circular buffer */
while ( !p_sys->b_error && ( i_circular_free = p_sys->circular.i_size -
( p_sys->circular.i_write - p_sys->circular.i_read ) ) == 0 )
vlc_cond_wait( &p_sys->aout_cond, &p_sys->lock );
if ( p_sys->b_error )
goto bailout;
i_data_offset = p_sys->circular.i_write % p_sys->circular.i_size;
i_data_size = __MIN( p_buffer->i_buffer - i_buffer_offset,
p_sys->circular.i_size - i_data_offset );
i_data_size = __MIN( i_data_size, i_circular_free );
switch ( p_sys->i_write_type )
{
case WRITE_BYTEARRAY:
case WRITE_BYTEARRAYV23:
(*env)->SetByteArrayRegion( env, p_sys->circular.u.p_bytearray,
i_data_offset, i_data_size,
(jbyte *)p_buffer->p_buffer
+ i_buffer_offset);
break ;
case WRITE_SHORTARRAYV23:
i_data_offset &= ~ 1 ;
i_data_size &= ~ 1 ;
(*env)->SetShortArrayRegion( env, p_sys->circular.u.p_shortarray,
i_data_offset / 2 , i_data_size / 2 ,
(jshort *)p_buffer->p_buffer
+ i_buffer_offset / 2 );
break ;
case WRITE_FLOATARRAY:
i_data_offset &= ~ 3 ;
i_data_size &= ~ 3 ;
(*env)->SetFloatArrayRegion( env, p_sys->circular.u.p_floatarray,
i_data_offset / 4 , i_data_size / 4 ,
(jfloat *)p_buffer->p_buffer
+ i_buffer_offset / 4 );
break ;
case WRITE_BYTEBUFFER:
memcpy( p_sys->circular.u.bytebuffer.p_data + i_data_offset,
p_buffer->p_buffer + i_buffer_offset, i_data_size );
break ;
}
i_buffer_offset += i_data_size;
p_sys->circular.i_write += i_data_size;
if ( !p_sys->b_thread_waiting )
vlc_cond_signal( &p_sys->thread_cond );
}
bailout:
vlc_mutex_unlock( &p_sys->lock );
block_Release( p_buffer );
}
|