[pulseaudio-discuss] [PATCH] null-source: fix multiple bugs
Georg Chini
georg at chini.tk
Fri Feb 16 12:04:53 UTC 2018
On 16.02.2018 11:46, Raman Shishniou wrote:
> On 02/15/2018 11:51 PM, Georg Chini wrote:
>> The current null-source implementation has several bugs:
>>
>> 1) The latency reported is the negative of the correct latency.
>> 2) The memchunk passed to pa_source_post() is not initialized
>> with silence.
>> 3) In PA_SOURCE_MESSAGE_SET_STATE the timestamp is always set
>> when the source transitions to RUNNING state. This should only
>> happen when the source transitions from SUSPENDED to RUNNING
>> but also if it changes from SUSPENDED to IDLE.
>> 4) The timing of the thread function is incorrect. It always
>> uses u->latency_time, regardless of the specified source
>> latency.
>> 5) The latency_time argument seems pointless because the source
>> is defined with dynamic latency.
>>
>> This patch fixes the issues by
>> 1) inverting the sign of the reported latency,
>> 2) initializing the memchunk with silence,
>> 3) changing the logic in PA_SOURCE_MESSAGE_SET_STATE so that
>> the timestamp is set when needed,
>> 4) using u->block_usec instead of u->latency_time for setting
>> the rtpoll timer and checking if the timer has elapsed,
>> 5) removing the latency_time option.
>> ---
>> src/modules/module-null-source.c | 40 +++++++++++++++++++---------------------
>> 1 file changed, 19 insertions(+), 21 deletions(-)
>>
>> diff --git a/src/modules/module-null-source.c b/src/modules/module-null-source.c
>> index 41f17bd9..7bbe7f47 100644
>> --- a/src/modules/module-null-source.c
>> +++ b/src/modules/module-null-source.c
>> @@ -51,12 +51,11 @@ PA_MODULE_USAGE(
>> "rate=<sample rate> "
>> "source_name=<name of source> "
>> "channel_map=<channel map> "
>> - "description=<description for the source> "
>> - "latency_time=<latency time in ms>");
>> + "description=<description for the source> ");
>>
>> #define DEFAULT_SOURCE_NAME "source.null"
>> -#define DEFAULT_LATENCY_TIME 20
>> #define MAX_LATENCY_USEC (PA_USEC_PER_SEC * 2)
>> +#define MIN_LATENCY_USEC (500)
>>
>> struct userdata {
>> pa_core *core;
>> @@ -71,7 +70,6 @@ struct userdata {
>>
>> pa_usec_t block_usec;
>> pa_usec_t timestamp;
>> - pa_usec_t latency_time;
>> };
>>
>> static const char* const valid_modargs[] = {
>> @@ -81,7 +79,6 @@ static const char* const valid_modargs[] = {
>> "source_name",
>> "channel_map",
>> "description",
>> - "latency_time",
>> NULL
>> };
>>
>> @@ -91,8 +88,10 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
>> switch (code) {
>> case PA_SOURCE_MESSAGE_SET_STATE:
>>
>> - if (PA_PTR_TO_UINT(data) == PA_SOURCE_RUNNING)
>> - u->timestamp = pa_rtclock_now();
>> + if (pa_source_get_state(u->source) == PA_SOURCE_SUSPENDED || pa_source_get_state(u->source) == PA_SOURCE_INIT) {
>> + if (PA_PTR_TO_UINT(data) == PA_SOURCE_RUNNING || PA_PTR_TO_UINT(data) == PA_SOURCE_IDLE)
>> + u->timestamp = pa_rtclock_now();
>> + }
> pa_source_get_state() is the macro:
> #define pa_source_get_state(s) ((pa_source_state_t) (s)->state)
>
> I think it's unsafe to access u->source->state in source_process_msg() since it called from i/o thread context.
> Also there is the macro PA_SOURCE_IS_OPENED(state) which check the source is running or idle.
>
> I think it should look like this:
>
> - if (PA_PTR_TO_UINT(data) == PA_SOURCE_RUNNING)
> - u->timestamp = pa_rtclock_now();
> + if (u->source->thread_info.state == PA_SOURCE_SUSPENDED || u->source->thread_info.state == PA_SOURCE_INIT) {
> + if (PA_SOURCE_IS_OPENED(PA_PTR_TO_UINT(data)))
> + u->timestamp = pa_rtclock_now();
> + }
>
It is safe to access the main thread variables because the main thread
is waiting for us.
The same code is also used in module-null-sink. That's why I just copied
it over.
More information about the pulseaudio-discuss
mailing list