- tmpev = gst_event_new_segment(&player->gapless.segment[stream_type]);
- gst_event_set_seqnum(tmpev, gst_event_get_seqnum(event));
- gst_event_unref(event);
- GST_PAD_PROBE_INFO_DATA(info) = tmpev;
- }
- break;
- }
- case GST_EVENT_QOS:
- {
- gdouble proportion = 0.0;
- GstClockTimeDiff diff = 0;
- GstClockTime timestamp = 0;
- gint64 running_time_diff = -1;
- GstQOSType type = 0;
- GstEvent *tmpev = NULL;
-
- running_time_diff = player->gapless.segment[stream_type].base;
-
- if (running_time_diff <= 0) /* don't need to adjust */
- break;
-
- gst_event_parse_qos(event, &type, &proportion, &diff, ×tamp);
- gst_event_unref(event);
-
- if (timestamp < running_time_diff) {
- LOGW("QOS event from previous group");
- ret = GST_PAD_PROBE_DROP;
- break;
- }
-
- LOGD("[%d] Adjusting QOS event: %" GST_TIME_FORMAT
- " - %" GST_TIME_FORMAT " = %" GST_TIME_FORMAT,
- stream_type, GST_TIME_ARGS(timestamp),
- GST_TIME_ARGS(running_time_diff),
- GST_TIME_ARGS(timestamp - running_time_diff));
-
- timestamp -= running_time_diff;
-
- /* That case is invalid for QoS events */
- if (diff < 0 && -diff > timestamp) {
- LOGW("QOS event from previous group");
- ret = GST_PAD_PROBE_DROP;
- break;
- }
-
- tmpev = gst_event_new_qos(GST_QOS_TYPE_UNDERFLOW, proportion, diff, timestamp);
- GST_PAD_PROBE_INFO_DATA(info) = tmpev;
-
- break;
- }
- default:
- break;
- }
-
-ERROR:
- if (caps)
- gst_caps_unref(caps);
- return ret;
-}
-
-static void
-__mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
-{
- mm_player_t* player = NULL;
- GstElement* pipeline = NULL;
- GstElement* selector = NULL;
- GstElement* fakesink = NULL;
- GstCaps* caps = NULL;
- GstStructure* str = NULL;
- const gchar* name = NULL;
- GstPad* sinkpad = NULL;
- GstPad* srcpad = NULL;
- gboolean first_track = FALSE;
-
- enum MainElementID elemId = MMPLAYER_M_NUM;
- MMPlayerTrackType stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
-
- /* check handles */
- player = (mm_player_t*)data;
-
- MMPLAYER_RETURN_IF_FAIL(elem && pad);
- MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
- //LOGD("pad-added signal handling\n");
-
- pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-
- /* get mimetype from caps */
- caps = gst_pad_query_caps(pad, NULL);
- if (!caps) {
- LOGE("cannot get caps from pad.\n");
- goto ERROR;
- }
-
- str = gst_caps_get_structure(caps, 0);
- if (!str) {
- LOGE("cannot get structure from caps.\n");
- goto ERROR;
- }
-
- name = gst_structure_get_name(str);
- if (!name) {
- LOGE("cannot get mimetype from structure.\n");
- goto ERROR;
- }
-
- MMPLAYER_LOG_GST_CAPS_TYPE(caps);
- //LOGD("detected mimetype : %s\n", name);
-
- if (strstr(name, "video")) {
- gint stype = 0;
-
- mm_attrs_set_int_by_name(player->attrs, "content_video_found", TRUE);
- mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
-
- /* don't make video because of not required, and not support multiple track */
- if (stype == MM_DISPLAY_SURFACE_NULL) {
- LOGD("no video sink by null surface");
-
- gchar *caps_str = gst_caps_to_string(caps);
- if (caps_str && (strstr(caps_str, "ST12") || strstr(caps_str, "SN12") ||
- strstr(caps_str, "SN21") || strstr(caps_str, "S420") || strstr(caps_str, "SR32")))
- player->set_mode.video_zc = TRUE;
-
- MMPLAYER_FREEIF(caps_str);
-
- if (player->v_stream_caps) {
- gst_caps_unref(player->v_stream_caps);
- player->v_stream_caps = NULL;
- }
-
- LOGD("create fakesink instead of videobin");
-
- /* fake sink */
- fakesink = gst_element_factory_make("fakesink", NULL);
- if (fakesink == NULL) {
- LOGE("ERROR : fakesink create error\n");
- goto ERROR;
- }
-
- if (player->ini.set_dump_element_flag)
- __mmplayer_add_dump_buffer_probe(player, fakesink);
-
- player->video_fakesink = fakesink;
-
- /* store it as it's sink element */
- __mmplayer_add_sink(player, player->video_fakesink);
-
- gst_bin_add(GST_BIN(pipeline), fakesink);
-
- // link
- sinkpad = gst_element_get_static_pad(fakesink, "sink");
-
- if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
- LOGW("failed to link fakesink\n");
- gst_object_unref(GST_OBJECT(fakesink));
- goto ERROR;
- }
-
- if (stype == MM_DISPLAY_SURFACE_REMOTE) {
- MMPLAYER_SIGNAL_CONNECT(player, sinkpad, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
- "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), player);
- }
-
- if (player->set_mode.media_packet_video_stream) {
- g_object_set(G_OBJECT(fakesink), "signal-handoffs", TRUE, NULL);
-
- MMPLAYER_SIGNAL_CONNECT(player,
- G_OBJECT(fakesink),
- MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
- "handoff",
- G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
- (gpointer)player);
-
- MMPLAYER_SIGNAL_CONNECT(player,
- G_OBJECT(fakesink),
- MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
- "preroll-handoff",
- G_CALLBACK(__mmplayer_video_stream_decoded_preroll_cb),
- (gpointer)player);
- }
-
- g_object_set(G_OBJECT(fakesink), "async", TRUE, "sync", TRUE, NULL);
- gst_element_set_state(fakesink, GST_STATE_PAUSED);
- goto DONE;
- }
-
- if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
- __mmplayer_gst_decode_callback(elem, pad, player);
- goto DONE;
- }
-
- LOGD("video selector \n");
- elemId = MMPLAYER_M_V_INPUT_SELECTOR;
- stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
- } else {
- if (strstr(name, "audio")) {
- gint samplerate = 0;
- gint channels = 0;
-
- if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
- __mmplayer_gst_decode_callback(elem, pad, player);
- goto DONE;
- }
-
- LOGD("audio selector \n");
- elemId = MMPLAYER_M_A_INPUT_SELECTOR;
- stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
-
- gst_structure_get_int(str, "rate", &samplerate);
- gst_structure_get_int(str, "channels", &channels);
-
- if ((channels > 0 && samplerate == 0)) {//exclude audio decoding
- /* fake sink */
- fakesink = gst_element_factory_make("fakesink", NULL);
- if (fakesink == NULL) {
- LOGE("ERROR : fakesink create error\n");
- goto ERROR;
- }
-
- gst_bin_add(GST_BIN(pipeline), fakesink);
-
- /* link */
- sinkpad = gst_element_get_static_pad(fakesink, "sink");
-
- if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
- LOGW("failed to link fakesink\n");
- gst_object_unref(GST_OBJECT(fakesink));
- goto ERROR;
- }
-
- g_object_set(G_OBJECT(fakesink), "async", TRUE, NULL);
- g_object_set(G_OBJECT(fakesink), "sync", TRUE, NULL);
- gst_element_set_state(fakesink, GST_STATE_PAUSED);
-
- goto DONE;
- }
- } else if (strstr(name, "text")) {
- LOGD("text selector \n");
- elemId = MMPLAYER_M_T_INPUT_SELECTOR;
- stream_type = MM_PLAYER_TRACK_TYPE_TEXT;
- } else {
- LOGE("wrong elem id \n");
- goto ERROR;
- }
- }
-
- selector = player->pipeline->mainbin[elemId].gst;
- if (selector == NULL) {
- selector = gst_element_factory_make("input-selector", NULL);
- LOGD("Creating input-selector\n");
- if (selector == NULL) {
- LOGE("ERROR : input-selector create error\n");
- goto ERROR;
- }
- g_object_set(selector, "sync-streams", TRUE, NULL);
-
- player->pipeline->mainbin[elemId].id = elemId;
- player->pipeline->mainbin[elemId].gst = selector;
-
- first_track = TRUE;
- // player->selector[stream_type].active_pad_index = DEFAULT_TRACK; // default
-
- srcpad = gst_element_get_static_pad(selector, "src");
-
- LOGD("blocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- player->selector[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
- __mmplayer_gst_selector_blocked, NULL, NULL);
- player->selector[stream_type].event_probe_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH|GST_PAD_PROBE_TYPE_EVENT_FLUSH,
- __mmplayer_gst_selector_event_probe, player, NULL);
-
- gst_element_set_state(selector, GST_STATE_PAUSED);
- gst_bin_add(GST_BIN(pipeline), selector);
- } else
- LOGD("input-selector is already created.\n");
-
- // link
- LOGD("Calling request pad with selector %p \n", selector);
- sinkpad = gst_element_get_request_pad(selector, "sink_%u");
-
- LOGD("got pad %s:%s from selector", GST_DEBUG_PAD_NAME(sinkpad));
-
- if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
- LOGW("failed to link selector\n");
- gst_object_unref(GST_OBJECT(selector));
- goto ERROR;
- }
-
- if (first_track) {
- LOGD("this is first track --> active track \n");
- g_object_set(selector, "active-pad", sinkpad, NULL);
- }
-
- _mmplayer_track_update_info(player, stream_type, sinkpad);
-
-
-DONE:
-ERROR:
-
- if (caps)
- gst_caps_unref(caps);
-
- if (sinkpad) {
- gst_object_unref(GST_OBJECT(sinkpad));
- sinkpad = NULL;
- }
-
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
-
- return;
-}
-
-static void __mmplayer_handle_text_decode_path(mm_player_t* player, GstElement* text_selector)
-{
- GstPad* srcpad = NULL;
- MMHandleType attrs = 0;
- gint active_index = 0;
-
- // [link] input-selector :: textbin
- srcpad = gst_element_get_static_pad(text_selector, "src");
- if (!srcpad) {
- LOGE("failed to get srcpad from selector\n");
- return;
- }
-
- LOGD("got pad %s:%s from text selector\n", GST_DEBUG_PAD_NAME(srcpad));
-
- active_index = player->selector[MM_PLAYER_TRACK_TYPE_TEXT].active_pad_index;
- if ((active_index != DEFAULT_TRACK) &&
- (__mmplayer_change_selector_pad(player, MM_PLAYER_TRACK_TYPE_TEXT, active_index) != MM_ERROR_NONE)) {
- LOGW("failed to change text track\n");
- player->selector[MM_PLAYER_TRACK_TYPE_TEXT].active_pad_index = DEFAULT_TRACK;
- }
-
- player->no_more_pad = TRUE;
- __mmplayer_gst_decode_callback(text_selector, srcpad, player);
-
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id) {
- gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id);
- player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id = 0;
- }
-
- LOGD("Total text tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num);
-
- if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
- player->has_closed_caption = TRUE;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if (attrs) {
- mm_attrs_set_int_by_name(attrs, "content_text_track_num", (gint)player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num);
- if (mmf_attrs_commit(attrs))
- LOGE("failed to commit.\n");
- } else
- LOGE("cannot get content attribute");
-
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
-}
-
-static void
-__mmplayer_gst_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpointer data)
-{
- mm_player_t* player = (mm_player_t*)data;
- GstElement* selector = NULL;
- GstElement* queue = NULL;
-
- GstPad* srcpad = NULL;
- GstPad* sinkpad = NULL;
- GstCaps* caps = NULL;
- gchar* caps_str = NULL;
-
- MMPLAYER_FENTER();
- MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
- caps = gst_pad_get_current_caps(pad);
- caps_str = gst_caps_to_string(caps);
- LOGD("deinterleave new caps : %s\n", caps_str);
- MMPLAYER_FREEIF(caps_str);
- gst_caps_unref(caps);
-
- if ((queue = __mmplayer_element_create_and_link(player, pad, "queue")) == NULL) {
- LOGE("ERROR : queue create error\n");
- goto ERROR;
- }
-
- g_object_set(G_OBJECT(queue),
- "max-size-buffers", 10,
- "max-size-bytes", 0,
- "max-size-time", (guint64)0,
- NULL);
-
- selector = player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst;
-
- if (!selector) {
- LOGE("there is no audio channel selector.\n");
- goto ERROR;
- }
-
- srcpad = gst_element_get_static_pad(queue, "src");
- sinkpad = gst_element_get_request_pad(selector, "sink_%u");
-
- LOGD("link(%s:%s - %s:%s)\n", GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
-
- if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
- LOGW("failed to link deinterleave - selector\n");
- goto ERROR;
- }
-
- gst_element_set_state(queue, GST_STATE_PAUSED);
- player->audio_mode.total_track_num++;
-
-ERROR:
-
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
-
- if (sinkpad) {
- gst_object_unref(GST_OBJECT(sinkpad));
- sinkpad = NULL;
- }
-
- MMPLAYER_FLEAVE();
- return;
-}
-
-static void
-__mmplayer_gst_deinterleave_no_more_pads(GstElement *elem, gpointer data)
-{
- mm_player_t* player = NULL;
- GstElement* selector = NULL;
- GstPad* sinkpad = NULL;
- gint active_index = 0;
- gchar* change_pad_name = NULL;
- GstCaps* caps = NULL; // no need to unref
- gint default_audio_ch = 0;
-
- MMPLAYER_FENTER();
- player = (mm_player_t*) data;
-
- selector = player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst;
-
- if (!selector) {
- LOGE("there is no audio channel selector.\n");
- goto ERROR;
- }
-
- active_index = player->audio_mode.active_pad_index;
-
- if (active_index != default_audio_ch) {
- gint audio_ch = default_audio_ch;
-
- /*To get the new pad from the selector*/
- change_pad_name = g_strdup_printf("sink%d", active_index);
- if (change_pad_name != NULL) {
- sinkpad = gst_element_get_static_pad(selector, change_pad_name);
- if (sinkpad != NULL) {
- LOGD("Set Active Pad - %s:%s\n", GST_DEBUG_PAD_NAME(sinkpad));
- g_object_set(selector, "active-pad", sinkpad, NULL);
-
- audio_ch = active_index;
-
- caps = gst_pad_get_current_caps(sinkpad);
- MMPLAYER_LOG_GST_CAPS_TYPE(caps);
-
- __mmplayer_set_audio_attrs(player, caps);
- gst_caps_unref(caps);
- }
- MMPLAYER_FREEIF(change_pad_name);
- }
-
- player->audio_mode.active_pad_index = audio_ch;
- LOGD("audio LR info(0:stereo) = %d\n", player->audio_mode.active_pad_index);
- }
-
-ERROR:
-
- if (sinkpad)
- gst_object_unref(sinkpad);
-
- MMPLAYER_FLEAVE();
- return;
-}
-
-static void
-__mmplayer_gst_build_deinterleave_path(GstElement *elem, GstPad *pad, gpointer data)
-{
- mm_player_t* player = NULL;
- MMPlayerGstElement *mainbin = NULL;
-
- GstElement* tee = NULL;
- GstElement* stereo_queue = NULL;
- GstElement* mono_queue = NULL;
- GstElement* conv = NULL;
- GstElement* filter = NULL;
- GstElement* deinterleave = NULL;
- GstElement* selector = NULL;
-
- GstPad* srcpad = NULL;
- GstPad* selector_srcpad = NULL;
- GstPad* sinkpad = NULL;
- GstCaps* caps = NULL;
- gulong block_id = 0;
-
- MMPLAYER_FENTER();
-
- /* check handles */
- player = (mm_player_t*) data;
-
- MMPLAYER_RETURN_IF_FAIL(elem && pad);
- MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
- mainbin = player->pipeline->mainbin;
-
- /* tee */
- if ((tee = __mmplayer_element_create_and_link(player, pad, "tee")) == NULL) {
- LOGE("ERROR : tee create error\n");
- goto ERROR;
- }
-
- mainbin[MMPLAYER_M_A_TEE].id = MMPLAYER_M_A_TEE;
- mainbin[MMPLAYER_M_A_TEE].gst = tee;
-
- gst_element_set_state(tee, GST_STATE_PAUSED);
-
- /* queue */
- srcpad = gst_element_get_request_pad(tee, "src_%u");
- if ((stereo_queue = __mmplayer_element_create_and_link(player, srcpad, "queue")) == NULL) {
- LOGE("ERROR : stereo queue create error\n");
- goto ERROR;
- }
-
- g_object_set(G_OBJECT(stereo_queue),
- "max-size-buffers", 10,
- "max-size-bytes", 0,
- "max-size-time", (guint64)0,
- NULL);
-
- player->pipeline->mainbin[MMPLAYER_M_A_Q1].id = MMPLAYER_M_A_Q1;
- player->pipeline->mainbin[MMPLAYER_M_A_Q1].gst = stereo_queue;
-
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
-
- srcpad = gst_element_get_request_pad(tee, "src_%u");
-
- if ((mono_queue = __mmplayer_element_create_and_link(player, srcpad, "queue")) == NULL) {
- LOGE("ERROR : mono queue create error\n");
- goto ERROR;
- }
-
- g_object_set(G_OBJECT(mono_queue),
- "max-size-buffers", 10,
- "max-size-bytes", 0,
- "max-size-time", (guint64)0,
- NULL);
-
- player->pipeline->mainbin[MMPLAYER_M_A_Q2].id = MMPLAYER_M_A_Q2;
- player->pipeline->mainbin[MMPLAYER_M_A_Q2].gst = mono_queue;
-
- gst_element_set_state(stereo_queue, GST_STATE_PAUSED);
- gst_element_set_state(mono_queue, GST_STATE_PAUSED);
-
- /* audioconvert */
- srcpad = gst_element_get_static_pad(mono_queue, "src");
- if ((conv = __mmplayer_element_create_and_link(player, srcpad, "audioconvert")) == NULL) {
- LOGE("ERROR : audioconvert create error\n");
- goto ERROR;
- }
-
- player->pipeline->mainbin[MMPLAYER_M_A_CONV].id = MMPLAYER_M_A_CONV;
- player->pipeline->mainbin[MMPLAYER_M_A_CONV].gst = conv;
-
- /* caps filter */
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
- srcpad = gst_element_get_static_pad(conv, "src");
-
- if ((filter = __mmplayer_element_create_and_link(player, srcpad, "capsfilter")) == NULL) {
- LOGE("ERROR : capsfilter create error\n");
- goto ERROR;
- }
-
- player->pipeline->mainbin[MMPLAYER_M_A_FILTER].id = MMPLAYER_M_A_FILTER;
- player->pipeline->mainbin[MMPLAYER_M_A_FILTER].gst = filter;
-
- caps = gst_caps_from_string("audio/x-raw-int, "
- "width = (int) 16, "
- "depth = (int) 16, "
- "channels = (int) 2");
-
- g_object_set(GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_A_FILTER].gst), "caps", caps, NULL);
- gst_caps_unref(caps);
-
- gst_element_set_state(conv, GST_STATE_PAUSED);
- gst_element_set_state(filter, GST_STATE_PAUSED);
-
- /* deinterleave */
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
- srcpad = gst_element_get_static_pad(filter, "src");
-
- if ((deinterleave = __mmplayer_element_create_and_link(player, srcpad, "deinterleave")) == NULL) {
- LOGE("ERROR : deinterleave create error\n");
- goto ERROR;
- }
-
- g_object_set(deinterleave, "keep-positions", TRUE, NULL);
-
- MMPLAYER_SIGNAL_CONNECT(player, deinterleave, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
- G_CALLBACK(__mmplayer_gst_deinterleave_pad_added), player);
-
- MMPLAYER_SIGNAL_CONNECT(player, deinterleave, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
- G_CALLBACK(__mmplayer_gst_deinterleave_no_more_pads), player);
-
- player->pipeline->mainbin[MMPLAYER_M_A_DEINTERLEAVE].id = MMPLAYER_M_A_DEINTERLEAVE;
- player->pipeline->mainbin[MMPLAYER_M_A_DEINTERLEAVE].gst = deinterleave;
-
- /* selector */
- selector = gst_element_factory_make("input-selector", "audio-channel-selector");
- if (selector == NULL) {
- LOGE("ERROR : audio-selector create error\n");
- goto ERROR;
- }
-
- g_object_set(selector, "sync-streams", TRUE, NULL);
- gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), selector);
-
- player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].id = MMPLAYER_M_A_SELECTOR;
- player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst = selector;
-
- selector_srcpad = gst_element_get_static_pad(selector, "src");
-
- LOGD("blocking %s:%s", GST_DEBUG_PAD_NAME(selector_srcpad));
- block_id =
- gst_pad_add_probe(selector_srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
- __mmplayer_gst_selector_blocked, NULL, NULL);
-
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
-
- srcpad = gst_element_get_static_pad(stereo_queue, "src");
- sinkpad = gst_element_get_request_pad(selector, "sink_%u");
-
- if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
- LOGW("failed to link queue_stereo - selector\n");
- goto ERROR;
- }
-
- player->audio_mode.total_track_num++;
-
- g_object_set(selector, "active-pad", sinkpad, NULL);
- gst_element_set_state(deinterleave, GST_STATE_PAUSED);
- gst_element_set_state(selector, GST_STATE_PAUSED);
-
- __mmplayer_gst_decode_callback(selector, selector_srcpad, player);
-
-ERROR:
-
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(selector_srcpad));
- if (block_id != 0) {
- gst_pad_remove_probe(selector_srcpad, block_id);
- block_id = 0;
- }
-
- if (sinkpad) {
- gst_object_unref(GST_OBJECT(sinkpad));
- sinkpad = NULL;
- }
-
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
-
- if (selector_srcpad) {
- gst_object_unref(GST_OBJECT(selector_srcpad));
- selector_srcpad = NULL;
- }
-
- MMPLAYER_FLEAVE();
- return;
-}
-
-static void
-__mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
-{
- mm_player_t* player = NULL;
- GstPad* srcpad = NULL;
- GstElement* video_selector = NULL;
- GstElement* audio_selector = NULL;
- GstElement* text_selector = NULL;
- MMHandleType attrs = 0;
- gint active_index = 0;
- gint64 dur_bytes = 0L;
-
- player = (mm_player_t*) data;
-
- LOGD("no-more-pad signal handling\n");
-
- if ((player->cmd == MMPLAYER_COMMAND_DESTROY) ||
- (player->cmd == MMPLAYER_COMMAND_UNREALIZE)) {
- LOGW("no need to go more");
-
- if (player->gapless.reconfigure) {
- player->gapless.reconfigure = FALSE;
- MMPLAYER_PLAYBACK_UNLOCK(player);
- }
-
- return;
- }
-
- if ((!MMPLAYER_IS_HTTP_PD(player)) &&
- (MMPLAYER_IS_HTTP_STREAMING(player)) &&
- (!player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) &&
- (player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)) {
- #define ESTIMATED_BUFFER_UNIT (1*1024*1024)
-
- if (NULL == player->streamer) {
- LOGW("invalid state for buffering");
- goto ERROR;
- }
-
- gint init_buffering_time = player->streamer->buffering_req.prebuffer_time;
- guint buffer_bytes = (guint)(init_buffering_time/1000) * ESTIMATED_BUFFER_UNIT;
-
- buffer_bytes = MAX(buffer_bytes, player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffering_bytes);
- LOGD("[Decodebin2] set use-buffering on Q2(pre buffer time: %d ms, buffer size : %d)\n", init_buffering_time, buffer_bytes);
-
- init_buffering_time = (init_buffering_time != 0) ? (init_buffering_time) : (player->ini.http_buffering_time);
-
- if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
- LOGE("fail to get duration.\n");
-
- // enable use-buffering on queue2 instead of multiqueue(ex)audio only streaming
- // use file information was already set on Q2 when it was created.
- __mm_player_streaming_set_queue2(player->streamer,
- player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst,
- TRUE, // use_buffering
- buffer_bytes,
- init_buffering_time,
- 1.0, // low percent
- player->ini.http_buffering_limit, // high percent
- MUXED_BUFFER_TYPE_MEM_QUEUE,
- NULL,
- ((dur_bytes > 0) ? ((guint64)dur_bytes) : 0));
- }
-
- video_selector = player->pipeline->mainbin[MMPLAYER_M_V_INPUT_SELECTOR].gst;
- audio_selector = player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst;
- text_selector = player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst;
- if (video_selector) {
- // [link] input-selector :: videobin
- srcpad = gst_element_get_static_pad(video_selector, "src");
- if (!srcpad) {
- LOGE("failed to get srcpad from video selector\n");
- goto ERROR;
- }
-
- LOGD("got pad %s:%s from video selector\n", GST_DEBUG_PAD_NAME(srcpad));
- if (!text_selector && !audio_selector)
- player->no_more_pad = TRUE;
-
- __mmplayer_gst_decode_callback(video_selector, srcpad, player);
-
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- if (player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id) {
- gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id);
- player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id = 0;
- }
- }
-
- if (audio_selector) {
- active_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
- if ((active_index != DEFAULT_TRACK) &&
- (__mmplayer_change_selector_pad(player, MM_PLAYER_TRACK_TYPE_AUDIO, active_index) != MM_ERROR_NONE)) {
- LOGW("failed to change audio track\n");
- player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index = DEFAULT_TRACK;
- }
-
- // [link] input-selector :: audiobin
- srcpad = gst_element_get_static_pad(audio_selector, "src");
- if (!srcpad) {
- LOGE("failed to get srcpad from selector\n");
- goto ERROR;
- }
-
- LOGD("got pad %s:%s from selector\n", GST_DEBUG_PAD_NAME(srcpad));
- if (!text_selector)
- player->no_more_pad = TRUE;
-
- if ((player->use_deinterleave == TRUE) && (player->max_audio_channels >= 2)) {
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id) {
- gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id);
- player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id = 0;
- }
-
- __mmplayer_gst_build_deinterleave_path(audio_selector, srcpad, player);
- } else {
- __mmplayer_gst_decode_callback(audio_selector, srcpad, player);
-
- LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
- if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id) {
- gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id);
- player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id = 0;
- }
- }
-
- LOGD("Total audio tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num);
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if (attrs) {
- mm_attrs_set_int_by_name(attrs, "content_audio_track_num", (gint)player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num);
- if (mmf_attrs_commit(attrs))
- LOGE("failed to commit.\n");
- } else
- LOGE("cannot get content attribute");
- } else {
- if ((player->pipeline->audiobin) && (player->pipeline->audiobin[MMPLAYER_A_BIN].gst)) {
- LOGD("There is no audio track : remove audiobin");
-
- __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN);
- __mmplayer_del_sink(player, player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
-
- MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->audiobin, MMPLAYER_A_BIN);
- MMPLAYER_FREEIF(player->pipeline->audiobin);
- }
-
- if (player->num_dynamic_pad == 0)
- __mmplayer_pipeline_complete(NULL, player);
- }
-
- if (!MMPLAYER_IS_MS_BUFF_SRC(player)) {
- if (text_selector)
- __mmplayer_handle_text_decode_path(player, text_selector);
- }
-
- MMPLAYER_FLEAVE();
-
-ERROR:
- if (srcpad) {
- gst_object_unref(GST_OBJECT(srcpad));
- srcpad = NULL;
- }
-
- if (player->gapless.reconfigure) {
- player->gapless.reconfigure = FALSE;
- MMPLAYER_PLAYBACK_UNLOCK(player);
- }
-}
-
-static void
-__mmplayer_gst_decode_callback(GstElement *elem, GstPad *pad, gpointer data)
-{
- mm_player_t* player = NULL;
- MMHandleType attrs = 0;
- GstElement* pipeline = NULL;
- GstCaps* caps = NULL;
- gchar* caps_str = NULL;
- GstStructure* str = NULL;
- const gchar* name = NULL;
- GstPad* sinkpad = NULL;
- GstElement* sinkbin = NULL;
- gboolean reusing = FALSE;
- GstElement *text_selector = NULL;
-
- /* check handles */
- player = (mm_player_t*) data;
-
- MMPLAYER_RETURN_IF_FAIL(elem && pad);
- MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
- pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if (!attrs) {
- LOGE("cannot get content attribute\n");
- goto ERROR;
- }
-
- /* get mimetype from caps */
- caps = gst_pad_query_caps(pad, NULL);
- if (!caps) {
- LOGE("cannot get caps from pad.\n");
- goto ERROR;
- }
- caps_str = gst_caps_to_string(caps);
-
- str = gst_caps_get_structure(caps, 0);
- if (!str) {
- LOGE("cannot get structure from caps.\n");
- goto ERROR;
- }
-
- name = gst_structure_get_name(str);
- if (!name) {
- LOGE("cannot get mimetype from structure.\n");
- goto ERROR;
- }
-
- //LOGD("detected mimetype : %s\n", name);
-
- if (strstr(name, "audio")) {
- if (player->pipeline->audiobin == NULL) {
- if (MM_ERROR_NONE != __mmplayer_gst_create_audio_pipeline(player)) {
- LOGE("failed to create audiobin. continuing without audio\n");
- goto ERROR;
- }
-
- sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
- LOGD("creating audiosink bin success\n");
- } else {
- reusing = TRUE;
- sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
- LOGD("reusing audiobin\n");
- _mmplayer_update_content_attrs(player, ATTR_AUDIO);
- }
-
- if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num <= 0) // should not update if content have multi audio tracks
- mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 1);
-
- player->audiosink_linked = 1;
-
- sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "sink");
- if (!sinkpad) {
- LOGE("failed to get pad from sinkbin\n");
- goto ERROR;
- }
- } else if (strstr(name, "video")) {
- if (caps_str && (strstr(caps_str, "ST12") || strstr(caps_str, "SN12") ||
- strstr(caps_str, "SN21") || strstr(caps_str, "S420") || strstr(caps_str, "SR32")))
- player->set_mode.video_zc = TRUE;
-
- if (player->pipeline->videobin == NULL) {
- /* NOTE : not make videobin because application dose not want to play it even though file has video stream. */
- /* get video surface type */
- int surface_type = 0;
- mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
- LOGD("display_surface_type(%d)\n", surface_type);
-
- if (surface_type == MM_DISPLAY_SURFACE_NULL) {
- LOGD("not make videobin because it dose not want\n");
- goto ERROR;
- }
-
- if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
- /* mark video overlay for acquire */
- if (player->video_overlay_resource == NULL) {
- if (mm_resource_manager_mark_for_acquire(player->resource_manager,
- MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
- MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
- &player->video_overlay_resource)
- != MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("could not mark video_overlay resource for acquire\n");
- goto ERROR;
- }
- }
- }
-
- player->interrupted_by_resource = FALSE;
- /* acquire resources for video overlay */
- if (mm_resource_manager_commit(player->resource_manager) !=
- MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("could not acquire resources for video playing\n");
- goto ERROR;
- }
-
- if (MM_ERROR_NONE != __mmplayer_gst_create_video_pipeline(player, caps, surface_type)) {
- LOGE("failed to create videobin. continuing without video\n");
- goto ERROR;
- }
-
- sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
- LOGD("creating videosink bin success\n");
- } else {
- reusing = TRUE;
- sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
- LOGD("re-using videobin\n");
- _mmplayer_update_content_attrs(player, ATTR_VIDEO);
- }
-
- player->videosink_linked = 1;
-
- sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "sink");
- if (!sinkpad) {
- LOGE("failed to get pad from sinkbin\n");
- goto ERROR;
- }
- } else if (strstr(name, "text")) {
- if (player->pipeline->textbin == NULL) {
- MMPlayerGstElement* mainbin = NULL;
-
- if (MM_ERROR_NONE != __mmplayer_gst_create_text_sink_bin(player)) {
- LOGE("failed to create text sink bin. continuing without text\n");
- goto ERROR;
- }
-
- sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
- LOGD("creating textsink bin success\n");
-
- /* FIXIT : track number shouldn't be hardcoded */
- mm_attrs_set_int_by_name(attrs, "content_text_track_num", 1);
-
- player->textsink_linked = 1;
- LOGI("player->textsink_linked set to 1\n");
-
- sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "text_sink");
- if (!sinkpad) {
- LOGE("failed to get pad from sinkbin\n");
- goto ERROR;
- }
-
- mainbin = player->pipeline->mainbin;
-
- if (!mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst) {
- /* input selector */
- text_selector = gst_element_factory_make("input-selector", "subtitle_inselector");
- if (!text_selector) {
- LOGE("failed to create subtitle input selector element\n");
- goto ERROR;
- }
- g_object_set(text_selector, "sync-streams", TRUE, NULL);
-
- mainbin[MMPLAYER_M_T_INPUT_SELECTOR].id = MMPLAYER_M_T_INPUT_SELECTOR;
- mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst = text_selector;
-
- /* warm up */
- if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(text_selector, GST_STATE_READY)) {
- LOGE("failed to set state(READY) to sinkbin\n");
- goto ERROR;
- }
-
- if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), text_selector)) {
- LOGW("failed to add subtitle input selector\n");
- goto ERROR;
- }
-
- LOGD("created element input-selector");
-
- } else {
- LOGD("already having subtitle input selector");
- text_selector = mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst;
- }
- } else {
- if (!player->textsink_linked) {
- LOGD("re-using textbin\n");
-
- reusing = TRUE;
- sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
-
- player->textsink_linked = 1;
- LOGI("player->textsink_linked set to 1\n");
- } else
- LOGD("ignoring internal subtutle since external subtitle is available");
- }
- } else {
- LOGW("unknown type of elementary stream!ignoring it...\n");
- goto ERROR;
- }
-
- if (sinkbin) {
- if (!reusing) {
- /* warm up */
- if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkbin, GST_STATE_READY)) {
- LOGE("failed to set state(READY) to sinkbin\n");
- goto ERROR;
- }
-
- /* Added for multi audio support to avoid adding audio bin again*/
- /* add */
- if (FALSE == gst_bin_add(GST_BIN(pipeline), sinkbin)) {
- LOGE("failed to add sinkbin to pipeline\n");
- goto ERROR;
- }
- }
-
- /* link */
- if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
- LOGE("failed to get pad from sinkbin\n");
- goto ERROR;
- }
-
- if (!reusing) {
- /* run */
- if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkbin, GST_STATE_PAUSED)) {
- LOGE("failed to set state(PAUSED) to sinkbin\n");
- goto ERROR;
- }
-
- if (text_selector) {
- if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(text_selector, GST_STATE_PAUSED)) {
- LOGE("failed to set state(PAUSED) to sinkbin\n");
- goto ERROR;
- }
- }
- }
-
- gst_object_unref(sinkpad);
- sinkpad = NULL;
- }
-
- LOGD("[handle: %p] linking sink bin success", player);
-
- /* FIXIT : we cannot hold callback for 'no-more-pad' signal because signal was emitted in
- * streaming task. if the task blocked, then buffer will not flow to the next element
- *(autoplugging element). so this is special hack for streaming. please try to remove it
- */
- /* dec stream count. we can remove fakesink if it's zero */
- if (player->num_dynamic_pad)
- player->num_dynamic_pad--;
-
- LOGD("no more pads: %d stream count dec : %d(num of dynamic pad)\n", player->no_more_pad, player->num_dynamic_pad);
-
- if ((player->no_more_pad) && (player->num_dynamic_pad == 0))
- __mmplayer_pipeline_complete(NULL, player);
-
-ERROR:
-
- MMPLAYER_FREEIF(caps_str);
-
- if (caps)
- gst_caps_unref(caps);
-
- if (sinkpad)
- gst_object_unref(GST_OBJECT(sinkpad));
-
- /* flusing out new attributes */
- if (mmf_attrs_commit(attrs))
- LOGE("failed to comit attributes\n");
-
- return;
-}
-
-static gboolean
-__mmplayer_get_property_value_for_rotation(mm_player_t* player, int rotation_angle, int *value)
-{
- int pro_value = 0; // in the case of expection, default will be returned.
- int dest_angle = rotation_angle;
- int rotation_type = -1;
-
- MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
- MMPLAYER_RETURN_VAL_IF_FAIL(value, FALSE);
- MMPLAYER_RETURN_VAL_IF_FAIL(rotation_angle >= 0, FALSE);
-
- if (rotation_angle >= 360)
- dest_angle = rotation_angle - 360;
-
- /* chech if supported or not */
- if (dest_angle % 90) {
- LOGD("not supported rotation angle = %d", rotation_angle);
- return FALSE;
- }
-
- /*
- * tizenwlsink (A)
- * custom_convert - none (B)
- * videoflip - none (C)
- */
- if (player->set_mode.video_zc) {
- if (player->pipeline->videobin[MMPLAYER_V_CONV].gst) // B
- rotation_type = ROTATION_USING_CUSTOM;
- else // A
- rotation_type = ROTATION_USING_SINK;
- } else {
- int surface_type = 0;
- rotation_type = ROTATION_USING_FLIP;
-
- mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
- LOGD("check display surface type attribute: %d", surface_type);
-
- if (surface_type == MM_DISPLAY_SURFACE_OVERLAY)
- rotation_type = ROTATION_USING_SINK;
- else
- rotation_type = ROTATION_USING_FLIP; //C
-
- LOGD("using %d type for rotation", rotation_type);
- }
-
- /* get property value for setting */
- switch (rotation_type) {
- case ROTATION_USING_SINK: // tizenwlsink
- {
- switch (dest_angle) {
- case 0:
- break;
- case 90:
- pro_value = 3; // clockwise 90
- break;
- case 180:
- pro_value = 2;
- break;
- case 270:
- pro_value = 1; // counter-clockwise 90
- break;
- }
- }
- break;
- case ROTATION_USING_CUSTOM:
- {
- gchar *ename = NULL;
- ename = GST_OBJECT_NAME(gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
-
- if (g_strrstr(ename, "fimcconvert")) {
- switch (dest_angle) {
- case 0:
- break;
- case 90:
- pro_value = 90; // clockwise 90
- break;
- case 180:
- pro_value = 180;
- break;
- case 270:
- pro_value = 270; // counter-clockwise 90
- break;
- }
- }
- }
- break;
- case ROTATION_USING_FLIP: // videoflip
- {
- switch (dest_angle) {
- case 0:
- break;
- case 90:
- pro_value = 1; // clockwise 90
- break;
- case 180:
- pro_value = 2;
- break;
- case 270:
- pro_value = 3; // counter-clockwise 90
- break;
- }
- }
- break;
- }
-
- LOGD("setting rotation property value : %d, used rotation type : %d", pro_value, rotation_type);
-
- *value = pro_value;
-
- return TRUE;
-}
-
-int
-__mmplayer_video_param_check_video_sink_bin(mm_player_t* player)
-{
- /* check video sinkbin is created */
- MMPLAYER_RETURN_VAL_IF_FAIL(player &&
- player->pipeline &&
- player->pipeline->videobin &&
- player->pipeline->videobin[MMPLAYER_V_BIN].gst &&
- player->pipeline->videobin[MMPLAYER_V_SINK].gst,
- MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- return MM_ERROR_NONE;
-}
-
-void
-__mmplayer_video_param_set_display_rotation(mm_player_t* player)
-{
- int rotation_value = 0;
- int org_angle = 0; // current supported angle values are 0, 90, 180, 270
- int user_angle = 0;
- MMPLAYER_FENTER();
-
- /* check video sinkbin is created */
- if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
- return;
-
- __mmplayer_get_video_angle(player, &user_angle, &org_angle);
-
- /* get rotation value to set */
- __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
- g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "rotate", rotation_value, NULL);
- LOGD("set video param : rotate %d", rotation_value);
-}
-
-void
-__mmplayer_video_param_set_display_visible(mm_player_t* player)
-{
- MMHandleType attrs = 0;
- int visible = 0;
- MMPLAYER_FENTER();
-
- /* check video sinkbin is created */
- if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
- return;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- MMPLAYER_RETURN_IF_FAIL(attrs);
-
- mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
- g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "visible", visible, NULL);
- LOGD("set video param : visible %d", visible);
-}
-
-void
-__mmplayer_video_param_set_display_method(mm_player_t* player)
-{
- MMHandleType attrs = 0;
- int display_method = 0;
- MMPLAYER_FENTER();
-
- /* check video sinkbin is created */
- if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
- return;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- MMPLAYER_RETURN_IF_FAIL(attrs);
-
- mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
- g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "display-geometry-method", display_method, NULL);
- LOGD("set video param : method %d", display_method);
-}
-
-void
-__mmplayer_video_param_set_render_rectangle(mm_player_t* player)
-{
- MMHandleType attrs = 0;
- void *handle = NULL;
- /*set wl_display*/
- int wl_window_x = 0;
- int wl_window_y = 0;
- int wl_window_width = 0;
- int wl_window_height = 0;
- MMPLAYER_FENTER();
-
- /* check video sinkbin is created */
- if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
- return;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- MMPLAYER_RETURN_IF_FAIL(attrs);
-
- mm_attrs_get_data_by_name(attrs, "display_overlay", &handle);
-
- if (handle) {
- /*It should be set after setting window*/
- mm_attrs_get_int_by_name(attrs, "wl_window_render_x", &wl_window_x);
- mm_attrs_get_int_by_name(attrs, "wl_window_render_y", &wl_window_y);
- mm_attrs_get_int_by_name(attrs, "wl_window_render_width", &wl_window_width);
- mm_attrs_get_int_by_name(attrs, "wl_window_render_height", &wl_window_height);
-
- /* After setting window handle, set render rectangle */
- gst_video_overlay_set_render_rectangle(
- GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
- wl_window_x, wl_window_y, wl_window_width, wl_window_height);
- LOGD("set video param : render rectangle : x(%d) y(%d) width(%d) height(%d)",
- wl_window_x, wl_window_y, wl_window_width, wl_window_height);
-
- }
-}
-void
-__mmplayer_video_param_set_display_overlay(mm_player_t* player)
-{
- MMHandleType attrs = 0;
- void *handle = NULL;
-
- /* check video sinkbin is created */
- if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
- return;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- MMPLAYER_RETURN_IF_FAIL(attrs);
-
- /* common case if using overlay surface */
- mm_attrs_get_data_by_name(attrs, "display_overlay", &handle);
-
- if (handle) {
- /* default is using wl_surface_id */
- unsigned int wl_surface_id = 0;
- wl_surface_id = *(int*)handle;
- LOGD("set video param : wl_surface_id %d %p", wl_surface_id, *(int*)handle);
- gst_video_overlay_set_wl_window_wl_surface_id(
- GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
- *(int*)handle);
- } else
- /* FIXIT : is it error case? */
- LOGW("still we don't have a window handle on player attribute. create it's own surface.");
-}
-
-
-int
-__mmplayer_update_wayland_videosink_video_param(mm_player_t* player, char *param_name)
-{
- bool update_all_param = FALSE;
- MMPLAYER_FENTER();
-
- /* check video sinkbin is created */
- if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
- return MM_ERROR_PLAYER_NOT_INITIALIZED;
-
- if (strcmp(player->ini.videosink_element_overlay, "tizenwlsink")) {
- LOGE("can not find tizenwlsink");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- LOGD("param_name : %s", param_name);
- if (!g_strcmp0(param_name, "update_all_param"))
- update_all_param = TRUE;
-
- if (update_all_param || !g_strcmp0(param_name, "display_overlay"))
- __mmplayer_video_param_set_display_overlay(player);
- if (update_all_param || !g_strcmp0(param_name, "display_method"))
- __mmplayer_video_param_set_display_method(player);
- if (update_all_param || !g_strcmp0(param_name, "wl_window_render_x"))
- __mmplayer_video_param_set_render_rectangle(player);
- if (update_all_param || !g_strcmp0(param_name, "display_visible"))
- __mmplayer_video_param_set_display_visible(player);
- if (update_all_param || !g_strcmp0(param_name, "display_rotation"))
- __mmplayer_video_param_set_display_rotation(player);
-
- return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_update_video_param(mm_player_t* player, char *param_name)
-{
- MMHandleType attrs = 0;
- int surface_type = 0;
- int ret = MM_ERROR_NONE;
-
- MMPLAYER_FENTER();
-
- /* check video sinkbin is created */
- if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
- return MM_ERROR_PLAYER_NOT_INITIALIZED;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if (!attrs) {
- LOGE("cannot get content attribute");
- return MM_ERROR_PLAYER_INTERNAL;
- }
- LOGD("param_name : %s", param_name);
-
- /* update display surface */
- mm_attrs_get_int_by_name(attrs, "display_surface_type", &surface_type);
- LOGD("check display surface type attribute: %d", surface_type);
-
- /* configuring display */
- switch (surface_type) {
- case MM_DISPLAY_SURFACE_OVERLAY:
- {
- ret = __mmplayer_update_wayland_videosink_video_param(player, param_name);
- if (ret != MM_ERROR_NONE)
- return ret;
- }
- break;
- }
-
- MMPLAYER_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
-{
- gboolean disable_overlay = FALSE;
- mm_player_t* player = (mm_player_t*) hplayer;
- int ret = MM_ERROR_NONE;
-
- MMPLAYER_FENTER();
- MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
- player->pipeline->videobin[MMPLAYER_V_SINK].gst,
- MM_ERROR_PLAYER_NO_OP); /* invalid op */
-
- if (!g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "disable-overlay")) {
- LOGW("Display control is not supported");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
-
- if (audio_only == (bool)disable_overlay) {
- LOGE("It's the same with current setting: (%d)", audio_only);
- return MM_ERROR_NONE;
- }
-
- if (audio_only) {
- LOGE("disable overlay");
- g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", TRUE, NULL);
-
- /* release overlay resource */
- if (player->video_overlay_resource != NULL) {
- ret = mm_resource_manager_mark_for_release(player->resource_manager,
- player->video_overlay_resource);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("failed to mark overlay resource for release, ret(0x%x)\n", ret);
- goto ERROR;
- }
- player->video_overlay_resource = NULL;
- }
-
- ret = mm_resource_manager_commit(player->resource_manager);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("failed to commit acquiring of overlay resource, ret(0x%x)\n", ret);
- goto ERROR;
- }
- } else {
- /* mark video overlay for acquire */
- if (player->video_overlay_resource == NULL) {
- ret = mm_resource_manager_mark_for_acquire(player->resource_manager,
- MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
- MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
- &player->video_overlay_resource);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("could not prepare for video_overlay resource\n");
- goto ERROR;
- }
- }
-
- player->interrupted_by_resource = FALSE;
- /* acquire resources for video overlay */
- ret = mm_resource_manager_commit(player->resource_manager);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("could not acquire resources for video playing\n");
- goto ERROR;
- }
-
- LOGD("enable overlay");
- __mmplayer_video_param_set_display_overlay(player);
- g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", FALSE, NULL);
- }
-
-ERROR:
- MMPLAYER_FLEAVE();
- return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only)
-{
- mm_player_t* player = (mm_player_t*) hplayer;
- gboolean disable_overlay = FALSE;
-
- MMPLAYER_FENTER();
-
- MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL(paudio_only, MM_ERROR_INVALID_ARGUMENT);
- MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
- player->pipeline->videobin[MMPLAYER_V_SINK].gst,
- MM_ERROR_PLAYER_NO_OP); /* invalid op */
-
- if (!g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "disable-overlay")) {
- LOGW("Display control is not supported");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
-
- *paudio_only = (bool)(disable_overlay);
-
- LOGD("audio_only : %d", *paudio_only);
-
- MMPLAYER_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-static int
-__mmplayer_gst_element_link_bucket(GList* element_bucket)
-{
- GList* bucket = element_bucket;
- MMPlayerGstElement* element = NULL;
- MMPlayerGstElement* prv_element = NULL;
- gint successful_link_count = 0;
-
- MMPLAYER_FENTER();
-
- MMPLAYER_RETURN_VAL_IF_FAIL(element_bucket, -1);
-
- prv_element = (MMPlayerGstElement*)bucket->data;
- bucket = bucket->next;
-
- for (; bucket; bucket = bucket->next) {
- element = (MMPlayerGstElement*)bucket->data;
-
- if (element && element->gst) {
- /* If next element is audio appsrc then make a separate audio pipeline */
- if (!strcmp(GST_ELEMENT_NAME(GST_ELEMENT(element->gst)), "audio_appsrc") ||
- !strcmp(GST_ELEMENT_NAME(GST_ELEMENT(element->gst)), "subtitle_appsrc")) {
- prv_element = element;
- continue;
- }
-
- if (prv_element && prv_element->gst) {
- if (gst_element_link(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst))) {
- LOGD("linking [%s] to [%s] success\n",
- GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
- GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
- successful_link_count++;
- } else {
- LOGD("linking [%s] to [%s] failed\n",
- GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
- GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
- return -1;
- }
- }
- }
-
- prv_element = element;
- }
-
- MMPLAYER_FLEAVE();
-
- return successful_link_count;
-}
-
-static int
-__mmplayer_gst_element_add_bucket_to_bin(GstBin* bin, GList* element_bucket)
-{
- GList* bucket = element_bucket;
- MMPlayerGstElement* element = NULL;
- int successful_add_count = 0;
-
- MMPLAYER_FENTER();
-
- MMPLAYER_RETURN_VAL_IF_FAIL(element_bucket, 0);
- MMPLAYER_RETURN_VAL_IF_FAIL(bin, 0);
-
- for (; bucket; bucket = bucket->next) {
- element = (MMPlayerGstElement*)bucket->data;
-
- if (element && element->gst) {
- if (!gst_bin_add(bin, GST_ELEMENT(element->gst))) {
- LOGD("__mmplayer_gst_element_link_bucket : Adding element [%s] to bin [%s] failed\n",
- GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
- GST_ELEMENT_NAME(GST_ELEMENT(bin)));
- return 0;
- }
- successful_add_count++;
- }
- }
-
- MMPLAYER_FLEAVE();
-
- return successful_add_count;
-}
-
-static void __mmplayer_gst_caps_notify_cb(GstPad * pad, GParamSpec * unused, gpointer data)
-{
- mm_player_t* player = (mm_player_t*) data;
- GstCaps *caps = NULL;
- GstStructure *str = NULL;
- const char *name;
-
- MMPLAYER_FENTER();
-
- MMPLAYER_RETURN_IF_FAIL(pad)
- MMPLAYER_RETURN_IF_FAIL(unused)
- MMPLAYER_RETURN_IF_FAIL(data)
-
- caps = gst_pad_get_current_caps(pad);
- if (!caps)
- return;
-
- str = gst_caps_get_structure(caps, 0);
- if (!str)
- goto ERROR;
-
- name = gst_structure_get_name(str);
- if (!name)
- goto ERROR;
-
- LOGD("name = %s\n", name);
-
- if (strstr(name, "audio")) {
- _mmplayer_update_content_attrs(player, ATTR_AUDIO);
-
- if (player->audio_stream_changed_cb) {
- LOGE("call the audio stream changed cb\n");
- player->audio_stream_changed_cb(player->audio_stream_changed_cb_user_param);
- }
- } else if (strstr(name, "video")) {
- if ((name = gst_structure_get_string(str, "format")))
- player->set_mode.video_zc = name[0] == 'S';
-
- _mmplayer_update_content_attrs(player, ATTR_VIDEO);
-
- if (player->video_stream_changed_cb) {
- LOGE("call the video stream changed cb\n");
- player->video_stream_changed_cb(player->video_stream_changed_cb_user_param);
- }
- } else
- goto ERROR;
-
-ERROR:
-
- gst_caps_unref(caps);
-
- MMPLAYER_FLEAVE();
-
- return;
-}
-
-
-
-/**
- * This function is to create audio pipeline for playing.
- *
- * @param player [in] handle of player
- *
- * @return This function returns zero on success.
- * @remark
- * @see __mmplayer_gst_create_midi_pipeline, __mmplayer_gst_create_video_pipeline
- */
-/* macro for code readability. just for sinkbin-creation functions */
-#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket, x_player) \
-do {\
- x_bin[x_id].id = x_id;\
- x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
- if (!x_bin[x_id].gst) {\
- LOGE("failed to create %s \n", x_factory);\
- goto ERROR;\
- } else {\
- if (x_player->ini.set_dump_element_flag)\
- __mmplayer_add_dump_buffer_probe(x_player, x_bin[x_id].gst);\
- } \
- if (x_add_bucket)\
- element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
-} while (0);
-
-static void
-__mmplayer_audio_stream_clear_buffer(mm_player_t* player, gboolean send_all)
-{
- GList *l = NULL;
-
- MMPLAYER_FENTER();
- MMPLAYER_RETURN_IF_FAIL(player);
-
- if (player->audio_stream_buff_list) {
- for (l = g_list_first(player->audio_stream_buff_list); l; l = g_list_next(l)) {
- mm_player_audio_stream_buff_t *tmp = (mm_player_audio_stream_buff_t *)l->data;
- if (tmp) {
- if (send_all) {
- LOGD("[%"G_GUINT64_FORMAT"] send remained data.", tmp->channel_mask);
- __mmplayer_audio_stream_send_data(player, tmp);
- }
- if (tmp->pcm_data)
- g_free(tmp->pcm_data);
- g_free(tmp);
- }
- }
- g_list_free(player->audio_stream_buff_list);
- player->audio_stream_buff_list = NULL;
- }
-
- MMPLAYER_FLEAVE();
-}
-
-static void
-__mmplayer_audio_stream_send_data(mm_player_t* player, mm_player_audio_stream_buff_t *a_buffer)
-{
- MMPlayerAudioStreamDataType audio_stream = { 0, };
-
- MMPLAYER_FENTER();
- MMPLAYER_RETURN_IF_FAIL(player && player->audio_stream_render_cb_ex);
-
- audio_stream.bitrate = a_buffer->bitrate;
- audio_stream.channel = a_buffer->channel;
- audio_stream.depth = a_buffer->depth;
- audio_stream.is_little_endian = a_buffer->is_little_endian;
- audio_stream.channel_mask = a_buffer->channel_mask;
- audio_stream.data_size = a_buffer->data_size;
- audio_stream.data = a_buffer->pcm_data;
-
- /* LOGD("[%"G_GUINT64_FORMAT"] send data size:%d, %p", audio_stream.channel_mask, audio_stream.data_size, player->audio_stream_cb_user_param); */
- player->audio_stream_render_cb_ex(&audio_stream, player->audio_stream_cb_user_param);
-
- MMPLAYER_FLEAVE();
-}
-
-static void
-__mmplayer_audio_stream_decoded_render_cb(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
-{
- mm_player_t* player = (mm_player_t*) data;
-
- gint channel = 0;
- gint rate = 0;
- gint depth = 0;
- gint endianness = 0;
- guint64 channel_mask = 0;
- void *a_data = NULL;
- gint a_size = 0;
- mm_player_audio_stream_buff_t *a_buffer = NULL;
- GstMapInfo mapinfo = GST_MAP_INFO_INIT;
- GList *l = NULL;
-
- MMPLAYER_FENTER();
- MMPLAYER_RETURN_IF_FAIL(player && player->audio_stream_render_cb_ex);
-
- gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
- a_data = mapinfo.data;
- a_size = mapinfo.size;
-
- GstCaps *caps = gst_pad_get_current_caps(pad);
- GstStructure *structure = gst_caps_get_structure(caps, 0);
-
- /* MMPLAYER_LOG_GST_CAPS_TYPE(caps); */
- gst_structure_get_int(structure, "rate", &rate);
- gst_structure_get_int(structure, "channels", &channel);
- gst_structure_get_int(structure, "depth", &depth);
- gst_structure_get_int(structure, "endianness", &endianness);
- gst_structure_get(structure, "channel-mask", GST_TYPE_BITMASK, &channel_mask, NULL);
- gst_caps_unref(GST_CAPS(caps));
-
- /* In case of the sync is false, use buffer list. *
- * The num of buffer list depends on the num of audio channels */
- if (player->audio_stream_buff_list) {
- for (l = g_list_first(player->audio_stream_buff_list); l; l = g_list_next(l)) {
- mm_player_audio_stream_buff_t *tmp = (mm_player_audio_stream_buff_t *)l->data;
- if (tmp) {
- if (channel_mask == tmp->channel_mask) {
- /* LOGD("[%"G_GUINT64_FORMAT"] total: %d, data: %d, buffer: %d", channel_mask, tmp->data_size, a_size, tmp->buff_size); */
- if (tmp->data_size + a_size < tmp->buff_size) {
- memcpy(tmp->pcm_data + tmp->data_size, a_data, a_size);
- tmp->data_size += a_size;
- } else {
- /* send data to client */
- __mmplayer_audio_stream_send_data(player, tmp);
-
- if (a_size > tmp->buff_size) {
- LOGD("[%"G_GUINT64_FORMAT"] adj buffer size %d -> %d", channel_mask, tmp->buff_size, a_size);
- tmp->pcm_data = g_realloc(tmp->pcm_data, a_size);
- if (tmp->pcm_data == NULL) {
- LOGE("failed to realloc data.");
- goto DONE;
- }
- tmp->buff_size = a_size;
- }
- memset(tmp->pcm_data, 0x00, tmp->buff_size);
- memcpy(tmp->pcm_data, a_data, a_size);
- tmp->data_size = a_size;
- }
- goto DONE;
- }
- } else {
- LOGE("data is empty in list.");
- goto DONE;
- }
- }
- }
-
- /* create new audio stream data */
- a_buffer = (mm_player_audio_stream_buff_t*)g_malloc0(sizeof(mm_player_audio_stream_buff_t));
- if (a_buffer == NULL) {
- LOGE("failed to alloc data.");
- goto DONE;
- }
- a_buffer->bitrate = rate;
- a_buffer->channel = channel;
- a_buffer->depth = depth;
- a_buffer->is_little_endian = (endianness == 1234 ? 1 : 0);
- a_buffer->channel_mask = channel_mask;
- a_buffer->data_size = a_size;
-
- if (!player->audio_stream_sink_sync) {
- /* If sync is FALSE, use buffer list to reduce the IPC. */
- a_buffer->buff_size = (a_size > player->ini.pcm_buffer_size) ? (a_size) : (player->ini.pcm_buffer_size);
- a_buffer->pcm_data = g_malloc(a_buffer->buff_size);
- if (a_buffer->pcm_data == NULL) {
- LOGE("failed to alloc data.");
- g_free(a_buffer);
- goto DONE;
- }
- memcpy(a_buffer->pcm_data, a_data, a_size);
- /* LOGD("new [%"G_GUINT64_FORMAT"] total:%d buff:%d", channel_mask, a_buffer->data_size, a_buffer->buff_size); */
- player->audio_stream_buff_list = g_list_append(player->audio_stream_buff_list, a_buffer);
- } else {
- /* If sync is TRUE, send data directly. */
- a_buffer->pcm_data = a_data;
- __mmplayer_audio_stream_send_data(player, a_buffer);
- g_free(a_buffer);
- }
-
-DONE:
- gst_buffer_unmap(buffer, &mapinfo);
- MMPLAYER_FLEAVE();
-}
-
-static void
-__mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpointer data)
-{
- mm_player_t* player = (mm_player_t*)data;
- MMPlayerGstElement* audiobin = player->pipeline->audiobin;
- GstPad* sinkpad = NULL;
- GstElement *queue = NULL, *sink = NULL;
-
- MMPLAYER_FENTER();
- MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
- queue = gst_element_factory_make("queue", NULL);
- if (queue == NULL) {
- LOGD("fail make queue\n");
- goto ERROR;
- }
-
- sink = gst_element_factory_make("fakesink", NULL);
- if (sink == NULL) {
- LOGD("fail make fakesink\n");
- goto ERROR;
- }
-
- gst_bin_add_many(GST_BIN(audiobin[MMPLAYER_A_BIN].gst), queue, sink, NULL);
-
- if (!gst_element_link_pads_full(queue, "src", sink, "sink", GST_PAD_LINK_CHECK_NOTHING)) {
- LOGW("failed to link queue & sink\n");
- goto ERROR;
- }
-
- sinkpad = gst_element_get_static_pad(queue, "sink");
-
- if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
- LOGW("failed to link [%s:%s] to queue\n", GST_DEBUG_PAD_NAME(pad));
- goto ERROR;
- }
-
- LOGE("player->audio_stream_sink_sync: %d\n", player->audio_stream_sink_sync);
-
- gst_object_unref(sinkpad);
- g_object_set(sink, "sync", player->audio_stream_sink_sync, NULL);
- g_object_set(sink, "signal-handoffs", TRUE, NULL);
-
- gst_element_set_state(sink, GST_STATE_PAUSED);
- gst_element_set_state(queue, GST_STATE_PAUSED);
-
- MMPLAYER_SIGNAL_CONNECT(player,
- G_OBJECT(sink),
- MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
- "handoff",
- G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
- (gpointer)player);
-
- MMPLAYER_FLEAVE();
- return;
-
-ERROR:
- LOGE("__mmplayer_gst_audio_deinterleave_pad_added ERROR\n");
- if (queue) {
- gst_object_unref(GST_OBJECT(queue));
- queue = NULL;
- }
- if (sink) {
- gst_object_unref(GST_OBJECT(sink));
- sink = NULL;
- }
- if (sinkpad) {
- gst_object_unref(GST_OBJECT(sinkpad));
- sinkpad = NULL;
- }
-
- return;
-}
-
-void __mmplayer_gst_set_audiosink_property(mm_player_t* player, MMHandleType attrs)
-{
- #define MAX_PROPS_LEN 128
- gint latency_mode = 0;
- gchar *stream_type = NULL;
- gchar *latency = NULL;
- gint stream_id = 0;
- gchar stream_props[MAX_PROPS_LEN] = {0,};
- GstStructure *props = NULL;
-
- /* set volume table
- * It should be set after player creation through attribute.
- * But, it can not be changed during playing.
- */
- MMPLAYER_FENTER();
- mm_attrs_get_int_by_name(attrs, "sound_stream_index", &stream_id);
- mm_attrs_get_string_by_name(attrs, "sound_stream_type", &stream_type);
-
- if (!stream_type) {
- LOGE("stream_type is null.\n");
- } else {
- if (player->sound.focus_id)
- snprintf(stream_props, sizeof(stream_props)-1, "props,media.role=%s, media.parent_id=%d, media.focus_id=%d",
- stream_type, stream_id, player->sound.focus_id);
- else
- snprintf(stream_props, sizeof(stream_props)-1, "props,media.role=%s, media.parent_id=%d",
- stream_type, stream_id);
- props = gst_structure_from_string(stream_props, NULL);
- g_object_set(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "stream-properties", props, NULL);
- LOGI("stream_type[%s], stream_id[%d], focus_id[%d], result[%s].\n",
- stream_type, stream_id, player->sound.focus_id, stream_props);
- gst_structure_free(props);
- }
-
- mm_attrs_get_int_by_name(attrs, "sound_latency_mode", &latency_mode);
-
- switch (latency_mode) {
- case AUDIO_LATENCY_MODE_LOW:
- latency = g_strndup("low", 3);
- break;
- case AUDIO_LATENCY_MODE_MID:
- latency = g_strndup("mid", 3);
- break;
- case AUDIO_LATENCY_MODE_HIGH:
- latency = g_strndup("high", 4);
- break;
- };
-
- g_object_set(player->pipeline->audiobin[MMPLAYER_A_SINK].gst,
- "latency", latency,
- NULL);
-
- LOGD("audiosink property - latency=%s \n", latency);
-
- g_free(latency);
-
- MMPLAYER_FLEAVE();
-}
-
-static int
-__mmplayer_gst_create_audio_pipeline(mm_player_t* player)