📄 pulse.c
字号:
pa_channel_map_snprint(cmt, sizeof(cmt), pa_stream_get_channel_map(p_sys->stream))); msg_Dbg(p_aout, "Connected to device %s (%u, %ssuspended).", pa_stream_get_device_name(p_sys->stream), pa_stream_get_device_index(p_sys->stream), pa_stream_is_suspended(p_sys->stream) ? "" : "not "); } return VLC_SUCCESS;unlock_and_fail: msg_Dbg(p_aout, "Pulse initialization unlock and fail"); if (p_sys->mainloop) pa_threaded_mainloop_unlock(p_sys->mainloop);fail: msg_Err(p_aout, "Pulse initialization failed"); uninit(p_aout); return VLC_EGENERIC;}/***************************************************************************** * Play: play a sound samples buffer *****************************************************************************/static void Play( aout_instance_t * p_aout ){ struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys; pa_operation *o; if(!p_sys->started){ msg_Dbg(p_aout, "Pulse stream started"); p_sys->start_date = aout_FifoFirstDate( p_aout, &p_aout->output.fifo ); p_sys->started = 1; pa_threaded_mainloop_lock(p_sys->mainloop); if((o = pa_stream_flush(p_sys->stream, success_cb, p_aout))){ pa_operation_unref(o); } pa_threaded_mainloop_unlock(p_sys->mainloop); pa_threaded_mainloop_signal(p_sys->mainloop, 0); }}/***************************************************************************** * Close: close the audio device *****************************************************************************/static void Close ( vlc_object_t *p_this ){ aout_instance_t *p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys = p_aout->output.p_sys; msg_Dbg(p_aout, "Pulse Close"); if(p_sys->stream){ pa_operation *o; pa_threaded_mainloop_lock(p_sys->mainloop); pa_stream_set_write_callback(p_sys->stream, NULL, NULL); if((o = pa_stream_drain(p_sys->stream, success_cb, p_aout))){ while (pa_operation_get_state(o) != PA_OPERATION_DONE) { CHECK_DEAD_GOTO(fail); pa_threaded_mainloop_wait(p_sys->mainloop); } fail: pa_operation_unref(o); } pa_threaded_mainloop_unlock(p_sys->mainloop); } uninit(p_aout);}static void uninit(aout_instance_t *p_aout){ struct aout_sys_t * p_sys = p_aout->output.p_sys; if (p_sys->mainloop) pa_threaded_mainloop_stop(p_sys->mainloop); if (p_sys->stream) { pa_stream_disconnect(p_sys->stream); pa_stream_unref(p_sys->stream); p_sys->stream = NULL; } if (p_sys->context) { pa_context_disconnect(p_sys->context); pa_context_unref(p_sys->context); p_sys->context = NULL; } if (p_sys->mainloop) { pa_threaded_mainloop_free(p_sys->mainloop); p_sys->mainloop = NULL; } free(p_sys); p_aout->output.p_sys = NULL;}static void context_state_cb(pa_context *c, void *userdata) { aout_instance_t *p_aout = (aout_instance_t *)userdata; struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys; assert(c); PULSE_DEBUG( "Pulse context state changed"); switch (pa_context_get_state(c)) { case PA_CONTEXT_READY: case PA_CONTEXT_TERMINATED: case PA_CONTEXT_FAILED: PULSE_DEBUG( "Pulse context state changed signal"); pa_threaded_mainloop_signal(p_sys->mainloop, 0); break; case PA_CONTEXT_UNCONNECTED: case PA_CONTEXT_CONNECTING: case PA_CONTEXT_AUTHORIZING: case PA_CONTEXT_SETTING_NAME: PULSE_DEBUG( "Pulse context state changed no signal"); break; }}static void stream_state_cb(pa_stream *s, void * userdata) { aout_instance_t *p_aout = (aout_instance_t *)userdata; struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys; assert(s); PULSE_DEBUG( "Pulse stream state changed"); switch (pa_stream_get_state(s)) { case PA_STREAM_READY: case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: pa_threaded_mainloop_signal(p_sys->mainloop, 0); break; case PA_STREAM_UNCONNECTED: case PA_STREAM_CREATING: break; }}static void stream_request_cb(pa_stream *s, size_t length, void *userdata) { aout_instance_t *p_aout = (aout_instance_t *)userdata; struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys; mtime_t next_date; assert(s); assert(p_sys); size_t buffer_size = p_sys->buffer_size; PULSE_DEBUG( "Pulse stream request %d", length); do{ aout_buffer_t * p_buffer = NULL; if(p_sys->started){ pa_usec_t latency; int negative; if(pa_stream_get_latency(p_sys->stream, &latency, &negative)<0){ if (pa_context_errno(p_sys->context) != PA_ERR_NODATA) { msg_Err(p_aout, "pa_stream_get_latency() failed: %s", pa_strerror(pa_context_errno(p_sys->context))); } latency = 0; } PULSE_DEBUG( "Pulse stream request latency=%"PRId64"", latency); next_date = mdate() + latency; if(p_sys->start_date < next_date + AOUT_PTS_TOLERANCE ){ /* vlc_mutex_lock( &p_aout->output_fifo_lock ); p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo ); vlc_mutex_unlock( &p_aout->output_fifo_lock ); */ p_buffer = aout_OutputNextBuffer( p_aout, next_date, 0); } } if ( p_buffer != NULL ) { PULSE_DEBUG( "Pulse stream request write buffer %d", p_buffer->i_nb_bytes); pa_stream_write(p_sys->stream, p_buffer->p_buffer, p_buffer->i_nb_bytes, NULL, 0, PA_SEEK_RELATIVE); length -= p_buffer->i_nb_bytes; aout_BufferFree( p_buffer ); } else { PULSE_DEBUG( "Pulse stream request write zeroes"); void *data = pa_xmalloc(buffer_size); bzero(data, buffer_size); pa_stream_write(p_sys->stream, data, buffer_size, pa_xfree, 0, PA_SEEK_RELATIVE); length -= buffer_size; } }while(length > buffer_size); pa_threaded_mainloop_signal(p_sys->mainloop, 0);}static void stream_latency_update_cb(pa_stream *s, void *userdata) { aout_instance_t *p_aout = (aout_instance_t *)userdata; struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys; assert(s); PULSE_DEBUG( "Pulse stream latency update"); pa_threaded_mainloop_signal(p_sys->mainloop, 0);}static void success_cb(pa_stream *s, int sucess, void *userdata){ aout_instance_t *p_aout = (aout_instance_t *)userdata; struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys; VLC_UNUSED(sucess); assert(s); pa_threaded_mainloop_signal(p_sys->mainloop, 0);}#undef PULSE_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -