A source-output is stuck when the sink doesn't feed reference data enough.
So, bypass mode was added in case there wasn't sink-inputs.
[Version] 15.0.69
[Issue Type] Update
Change-Id: I1e2a58723d6f2facada2d578bb35c51c9821eb40
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
Name: pulseaudio-modules-tizen
Summary: Pulseaudio modules for Tizen
-Version: 15.0.68
+Version: 15.0.69
Release: 0
Group: Multimedia/Audio
License: LGPL-2.1+
u->preprocess_on = true;
pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor,
PA_SOURCE_MESSAGE_PREPROCESSOR_RESET_REFERENCE, (void *)true, 0, NULL, NULL);
+ pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor,
+ PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, u->holder, (int64_t)false, NULL, NULL);
} else {
+ pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor,
+ PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, u->holder, (int64_t)true, NULL, NULL);
u->preprocess_on = false;
}
if (u->reset_lazy_reference) {
pa_processor_reference_reset(reference);
pa_processor_reference_add_latency_padding(reference, get_round_trip_latency(source, sink));
-
+ pa_processor_reference_set_bypass(reference, false);
u->reset_lazy_reference = false;
}
u->reset_lazy_reference = true;
break;
+ case PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS: {
+ pa_processor_holder *holder = (pa_processor_holder *)data;
+ pa_processor_reference *reference = NULL;
+ bool bypass = !!offset;
+
+ reference = pa_processor_holder_get_connected_processor_reference(holder);
+ if (!holder || !reference) {
+ pa_log_error("holder(%p), reference(%p) aren't set", holder, reference);
+ break;
+ }
+
+ pa_processor_reference_set_bypass(reference, bypass);
+
+ break;
+ }
case PA_SOURCE_MESSAGE_PREPROCESSOR_DESTROY: {
pa_source_output *output;
PA_SOURCE_MESSAGE_PREPROCESSOR_PUSH_DATA,
PA_SOURCE_MESSAGE_PREPROCESSOR_PUSH_REFERENCE,
PA_SOURCE_MESSAGE_PREPROCESSOR_RESET_REFERENCE,
+ PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS,
PA_SOURCE_MESSAGE_PREPROCESSOR_DESTROY,
PA_SOURCE_MESSAGE_PREPROCESSOR_TERMINATE,
};
/* Do not touch chunk value */
int pa_processor_process(pa_processor *processor, pa_memchunk *chunk) {
- int r = -1;
int8_t *recording = NULL;
int8_t *reference = NULL;
int8_t *output = NULL;
pa_assert(chunk);
if (processor->reference) {
- if ((r = pa_processor_reference_pull(processor->reference, &rchunk)) < 0) {
- pa_log_warn("Failed to get memblock from reference memblockq. ret(%d)", r);
+ if (pa_processor_reference_get_bypass(processor->reference)) {
+ if (pa_memblockq_push(processor->result_memblockq, chunk) < 0)
+ pa_log_error("Bypass failed to push out chunk to result memblockq");
+
+ pa_log_debug("Bypass method(%d:%s). because reference sink isn't working now",
+ processor->method, pa_processor_method_str(processor->method));
+ return 0;
+ }
+
+ if (pa_processor_reference_pull(processor->reference, &rchunk) < 0) {
+ pa_log_debug("Underrun the reference memblock during a fall duplex situation. Buffering more reference memblocks.");
return -PROCESSOR_ERR_BUFFERING;
}
debug_timestamp_begin(processor);
- r = audio_effect_process_reference(processor->audio_effect, recording, reference, output);
- if (r < 0) {
+ if (audio_effect_process_reference(processor->audio_effect, recording, reference, output) < 0) {
pa_log_warn("Failed to process memchunk");
goto fail;
}
/* The memchunk in the result memblockq's refcount must be one */
pa_memblock_unref(ochunk.memblock);
- return r;
+ return 0;
fail:
pa_memblock_release(chunk->memblock);
pa_memblock_unref(ochunk.memblock);
- return r;
+ return -1;
}
pa_memblockq *pa_processor_get_result_memblockq(pa_processor *processor) {
#include "processor_holder.h"
#define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
-#define DEFAULT_PREBUFFER_MSEC (300)
+#define DEFAULT_PREBUFFER_MSEC (50)
pa_processor_holder *pa_processor_holder_new(pa_core *core, pa_sample_spec *ss) {
pa_processor_holder *holder;
if ((ret = pa_processor_process(p, &chunk)) < 0) {
pa_memblock_unref(chunk.memblock);
pa_memblockq_drop(pull_queue, chunk.length);
- pa_log_error("Failed to process");
+ if (ret == -PROCESSOR_ERR_BUFFERING)
+ pa_log_debug("Buffering reference memblocks.");
+ else
+ pa_log_warn("Failed to process memblock. ret(%d)", ret);
+
return ret;
}
pa_usec_t process_usec;
size_t process_bytes;
pa_sample_spec ss;
+ bool bypass;
/* only for pull mode (audio-share) */
void *priv;
reference->ss = *request_ss;
reference->process_bytes = pa_usec_to_bytes(reference->process_usec, &reference->ss);
reference->sink = sink;
+ reference->bypass = true;
pa_silence_memchunk_get(&core->silence_cache, core->mempool, &silence, request_ss, 0);
reference->memblockq = pa_memblockq_new("reference memblockq",
exit:
memblock_length = pa_memblockq_get_length(reference->memblockq);
- if (memblock_length < length) {
- pa_log_info("reference memblockq has less memblocks. memblock_length(%zu), length(%zu)",
- memblock_length, length);
+ /* Needs to gather more reference memblocks */
+ if (memblock_length < length)
return -1;
- }
if ((r = pa_memblockq_peek_fixed_size(reference->memblockq, length, chunk)) < 0) {
pa_log_error("Failed to get memblock from reference memblockq");
}
+void pa_processor_reference_set_bypass(pa_processor_reference *reference, bool bypass) {
+ pa_assert(reference);
+
+ if (reference->bypass == bypass)
+ return;
+
+ reference->bypass = bypass;
+
+ pa_log_info("set reference bypass(%d)", reference->bypass);
+}
+
+bool pa_processor_reference_get_bypass(pa_processor_reference *reference) {
+ pa_assert(reference);
+
+ pa_log_debug("get reference bypass(%d)", reference->bypass);
+
+ return reference->bypass;
+}
+
char *pa_processor_reference_dump_index(pa_processor_reference *reference) {
int64_t windex, rindex;
pa_usec_t pa_processor_reference_chunk_to_usec(pa_processor_reference *reference, pa_memchunk *chunk);
size_t pa_processor_reference_process_usec_to_bytes(pa_processor_reference *reference);
char *pa_processor_reference_dump_index(pa_processor_reference *reference);
+void pa_processor_reference_set_bypass(pa_processor_reference *reference, bool bypass);
+bool pa_processor_reference_get_bypass(pa_processor_reference *reference);
pa_sink *pa_processor_reference_get_sink(pa_processor_reference *reference);
pa_processor_reference_method_t pa_processor_reference_method_enum(const char *method);
u->preprocess_on = true;
pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor,
PA_SOURCE_MESSAGE_PREPROCESSOR_RESET_REFERENCE, (void *)true, 0, NULL, NULL);
+ pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor,
+ PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, u->holder, (int64_t)false, NULL, NULL);
} else {
+ pa_asyncmsgq_post(u->preprocessor_asyncmsgq, u->preprocessor,
+ PA_SOURCE_MESSAGE_PREPROCESSOR_REFERENCE_BYPASS, u->holder, (int64_t)true, NULL, NULL);
u->preprocess_on = false;
}