pa_hook_slot *source_output_fixate_slot;
pa_hook_slot *source_output_put_slot;
+ pa_hook_slot *source_output_unlink_slot;
pa_hook_slot *source_output_unlink_post_slot;
+ pa_hook_slot *source_output_move_start_slot;
+ pa_hook_slot *source_output_move_finish_slot;
+
pa_rtpoll *rtpoll;
pa_thread *thread;
pa_thread_mq thread_mq;
NULL,
};
+static bool proplist_test_tizen_version2(pa_proplist *p) {
+ const char *tizen_version;
+ uint32_t version;
+
+ pa_assert(p);
+
+ if (!(tizen_version = pa_proplist_gets(p, "tizen.version")))
+ return false;
+
+ if (pa_atou(tizen_version, &version))
+ return false;
+
+ if (version < 2)
+ return false;
+
+ return true;
+}
+
+static void process_msg_main_thread(pa_msgobject *o, int code, void *userdata) {
+ pa_assert(o);
+ pa_assert(userdata);
+
+ o->process_msg(o, code, userdata, 0UL, NULL);
+}
+
static int proplist_get_fragment_size_usec(pa_proplist *p, pa_sample_spec *sample_spec, pa_usec_t *usec) {
const char *prop_fragsize;
uint32_t fragsize;
char *processor_str = NULL;
pa_processor_holder *holder;
- pa_usec_t process_usec;
+ pa_usec_t process_usec = 10 * PA_USEC_PER_MSEC;
pa_assert(core);
pa_assert(data);
processors_list = pa_proplist_gets(data->proplist, PA_PROP_MEDIA_PREPROCESSOR_METHOD);
pa_assert(processors_list);
- if (proplist_get_fragment_size_usec(data->source->proplist, &data->source->sample_spec, &process_usec) < 0) {
- pa_processor_holder_free(holder);
- pa_log_error("Failed to get source fragment usec. use default process usec");
- return NULL;
- }
+ if (proplist_get_fragment_size_usec(data->source->proplist, &data->source->sample_spec, &process_usec) < 0)
+ pa_log_warn("Failed to get source fragment usec. use default process usec");
+
+ pa_log_info("request to build processors_list(%s)", processors_list);
while ((processor_str = pa_split(processors_list, ",", &state))) {
pa_processor *processor;
pa_assert(o);
holder = (pa_processor_holder *)o->thread_info.processor_holder;
- pa_processor_holder_free(holder);
+ if (holder) {
+ pa_processor_holder_free(holder);
+ o->thread_info.processor_holder = NULL;
+ }
o->preprocess = NULL;
o->thread_info.processor_holder = NULL;
/* chunk must contain resampled sound pcm */
pa_processor_holder_push_data(holder, chunk);
+
ret = pa_processor_holder_pump(holder);
if (ret != PROCESSOR_OK) {
if (ret != -PROCESSOR_ERR_BUFFERING)
return PA_HOOK_OK;
holder = (pa_processor_holder *)o->thread_info.processor_holder;
+ if (!holder) {
+ pa_log_error("Failed to get processor holder");
+ return PA_HOOK_OK;
+ }
- pa_assert(holder);
- pa_assert(pa_processor_holder_get_current_source(holder)); /* source must be set at ADD_SOURCE_OUTPUT */
+ if (!proplist_test_tizen_version2(o->source->proplist)) {
+ pa_msgobject *msgobject = PA_MSGOBJECT(u->preprocessor);
+ pa_assert(msgobject);
+
+ process_msg_main_thread(msgobject, PA_SOURCE_MESSAGE_PREPROCESSOR_ADD_OUTPUT, o);
+
+ connect_to_reference_sink(holder, PA_MSGOBJECT(u->preprocessor), u->asyncmsgq_sink, true);
+
+ return PA_HOOK_OK;
+ }
connect_to_reference_sink(holder, PA_MSGOBJECT(u->preprocessor), u->asyncmsgq_sink, true);
return PA_HOOK_OK;
}
+static pa_hook_result_t source_output_unlink_cb(pa_core *c, pa_source_output *o, void *userdata) {
+ struct userdata *u = (struct userdata *)userdata;
+ pa_processor_holder *holder;
+
+ pa_assert(c);
+ pa_assert(o);
+ pa_assert(u);
+
+ if (!is_preprocessor_marked(o->flags))
+ return PA_HOOK_OK;
+
+ holder = (pa_processor_holder *)o->thread_info.processor_holder;
+ if (!holder) {
+ pa_log_error("Failed to get processor holder");
+ return PA_HOOK_OK;
+ }
+
+ /* in case of normal source(not tizen2)
+ * This should be destroy in unlink process
+ * because o->source wouldn't exist in the unlink_post step. */
+ if (!proplist_test_tizen_version2(o->source->proplist)) {
+ pa_msgobject *msgobject = PA_MSGOBJECT(u->preprocessor);
+ pa_assert(msgobject);
+
+ process_msg_main_thread(msgobject, PA_SOURCE_MESSAGE_PREPROCESSOR_DESTROY, o);
+
+ connect_to_reference_sink(holder, NULL, NULL, false);
+ }
+
+ return PA_HOOK_OK;
+}
+
/* This function will be also called when source unlink */
static pa_hook_result_t source_output_unlink_post_cb(pa_core *c, pa_source_output *o, void *userdata) {
struct userdata *u = (struct userdata *)userdata;
return PA_HOOK_OK;
holder = (pa_processor_holder *)o->thread_info.processor_holder;
+ if (!holder) {
+ pa_log_info("holder doesn't exist. source-output might not be connected to tizen2 source");
+ return PA_HOOK_OK;
+ }
connect_to_reference_sink(holder, NULL, NULL, false);
return PA_HOOK_OK;
}
+static pa_hook_result_t source_output_move_start_cb(pa_core *c, pa_source_output *o, void *userdata) {
+ struct userdata *u = (struct userdata *)userdata;
+
+ pa_assert(c);
+ pa_assert(o);
+ pa_assert(u);
+
+ if (!proplist_test_tizen_version2(o->source->proplist)) {
+ pa_msgobject *msgobject = PA_MSGOBJECT(u->preprocessor);
+ pa_assert(msgobject);
+
+ process_msg_main_thread(msgobject, PA_SOURCE_MESSAGE_PREPROCESSOR_REMOVE_OUTPUT, o);
+ }
+
+ return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_move_finish_cb(pa_core *c, pa_source_output *o, void *userdata) {
+ struct userdata *u = (struct userdata *)userdata;
+
+ pa_assert(c);
+ pa_assert(o);
+ pa_assert(u);
+
+ if (!proplist_test_tizen_version2(o->source->proplist)) {
+ pa_msgobject *msgobject = PA_MSGOBJECT(u->preprocessor);
+ pa_assert(msgobject);
+
+ process_msg_main_thread(msgobject, PA_SOURCE_MESSAGE_PREPROCESSOR_ADD_OUTPUT, o);
+ }
+
+ return PA_HOOK_OK;
+}
+
static void thread_func(void *userdata) {
struct userdata *u = (struct userdata *)userdata;
goto fail;
}
+ u->source_output_unlink_slot =
+ pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK],
+ PA_HOOK_EARLY, (pa_hook_cb_t) source_output_unlink_cb, u);
+
u->source_output_unlink_post_slot =
pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST],
PA_HOOK_EARLY, (pa_hook_cb_t) source_output_unlink_post_cb, u);
pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT],
PA_HOOK_LATE, (pa_hook_cb_t) source_output_put_cb, u);
+ u->source_output_move_start_slot =
+ pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_START],
+ PA_HOOK_LATE, (pa_hook_cb_t) source_output_move_start_cb, u);
+
+ u->source_output_move_finish_slot =
+ pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH],
+ PA_HOOK_LATE, (pa_hook_cb_t) source_output_move_finish_cb, u);
+
/* TODO : need to check sink configuration change */
pa_modargs_free(ma);