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 );
}
|