From: Eunhae Choi Date: Tue, 30 Oct 2018 11:28:22 +0000 (+0900) Subject: [0.6.137] resolve complexity issue X-Git-Tag: submit/tizen/20181109.060212~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bf57cdf96cb5b1343b87717e6afd802072be88d4;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git [0.6.137] resolve complexity issue - resolve the cyclomatic complexity issue of below functions __mmplayer_gst_create_video_pipeline __mmplayer_try_to_plug_decodebin (rename: _gst_create_decoder) Change-Id: Ia025df56396b2abfbc96ecf81211c30a7640e22f --- diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index 5d90858..ca25fff 100644 --- a/packaging/libmm-player.spec +++ b/packaging/libmm-player.spec @@ -1,6 +1,6 @@ Name: libmm-player Summary: Multimedia Framework Player Library -Version: 0.6.136 +Version: 0.6.137 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player_gst.h b/src/include/mm_player_gst.h index 7e54b7e..598dd63 100644 --- a/src/include/mm_player_gst.h +++ b/src/include/mm_player_gst.h @@ -57,11 +57,11 @@ gboolean __mmplayer_gst_seek(mm_player_t* player, GstElement * element, gdouble int __mmplayer_gst_set_position(mm_player_t* player, gint64 position, gboolean internal_called); int __mmplayer_gst_get_position(mm_player_t* player, gint64* position); int __mmplayer_gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos); +GstElement* __mmplayer_gst_create_source(mm_player_t* player); int __mmplayer_gst_build_es_pipeline(mm_player_t* player); int __mmplayer_gst_build_pd_pipeline(mm_player_t* player); int __mmplayer_gst_build_pipeline(mm_player_t* player); int __mmplayer_gst_add_bus_watch(mm_player_t* player); -GstElement* __mmplayer_gst_build_source(mm_player_t* player); #ifdef __cplusplus } diff --git a/src/include/mm_player_priv.h b/src/include/mm_player_priv.h index 827e0e1..bfd00b9 100644 --- a/src/include/mm_player_priv.h +++ b/src/include/mm_player_priv.h @@ -965,9 +965,9 @@ gboolean __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* void __mmplayer_add_signal_connection(mm_player_t* player, GObject* object, MMPlayerSignalType type, const gchar* signal, GCallback cb_funct, gpointer u_data); void __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data); gint __mmplayer_gst_decode_autoplug_select(GstElement *bin, GstPad* pad, GstCaps* caps, GstElementFactory* factory, gpointer data); -gboolean __mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps); +gboolean __mmplayer_gst_create_decoder(mm_player_t* player, GstPad *srcpad, const GstCaps *caps); void __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data); -GstElement* __mmplayer_create_decodebin(mm_player_t* player); +GstElement* __mmplayer_gst_make_decodebin(mm_player_t* player); int __mmplayer_gst_element_add_bucket_to_bin(GstBin* bin, GList* element_bucket); int __mmplayer_gst_element_link_bucket(GList* element_bucket); void __mmplayer_typefind_have_type(GstElement *tf, guint probability, GstCaps *caps, gpointer data); diff --git a/src/mm_player_gst.c b/src/mm_player_gst.c index 3b59663..97e6dd8 100644 --- a/src/mm_player_gst.c +++ b/src/mm_player_gst.c @@ -2551,7 +2551,7 @@ __mmplayer_gst_create_es_path(mm_player_t* player, MMPlayerStreamType type, GstC } if (type == MM_PLAYER_STREAM_TYPE_TEXT) { - __mmplayer_try_to_plug_decodebin(player, gst_element_get_static_pad(mainbin[queue_id].gst, "src"), caps); + __mmplayer_gst_create_decoder(player, gst_element_get_static_pad(mainbin[queue_id].gst, "src"), caps); } else { if (!__mmplayer_gst_create_es_decoder(player, type, srcpad)) { LOGE("failed to create decoder"); @@ -2644,7 +2644,7 @@ __mmplayer_gst_rtp_dynamic_pad(GstElement *element, GstPad *pad, gpointer data) /* clear previous result*/ player->have_dynamic_pad = FALSE; - if (!__mmplayer_try_to_plug_decodebin(player, pad, caps)) { + if (!__mmplayer_gst_create_decoder(player, pad, caps)) { LOGE("failed to autoplug for caps"); goto ERROR; } @@ -2757,7 +2757,7 @@ __mmplayer_gst_rtp_no_more_pads(GstElement *element, gpointer data) } static GstElement* -__mmplayer_gst_create_rtsp_src(mm_player_t* player) +__mmplayer_gst_make_rtsp_src(mm_player_t* player) { GstElement* element = NULL; gchar *user_agent = NULL; @@ -2799,7 +2799,7 @@ __mmplayer_gst_create_rtsp_src(mm_player_t* player) } static GstElement* -__mmplayer_gst_create_http_src(mm_player_t* player) +__mmplayer_gst_make_http_src(mm_player_t* player) { GstElement* element = NULL; MMHandleType attrs = 0; @@ -2860,7 +2860,7 @@ __mmplayer_gst_create_http_src(mm_player_t* player) } static GstElement* -__mmplayer_gst_create_file_src(mm_player_t* player) +__mmplayer_gst_make_file_src(mm_player_t* player) { GstElement* element = NULL; @@ -3760,6 +3760,37 @@ int __mmplayer_gst_get_buffer_position(mm_player_t* player, int format, unsigned return MM_ERROR_NONE; } +GstElement* __mmplayer_gst_create_source(mm_player_t* player) +{ + GstElement* element = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && + player->pipeline->mainbin, NULL); + + /* setup source for gapless play */ + switch (player->profile.uri_type) { + /* file source */ + case MM_PLAYER_URI_TYPE_FILE: + element = __mmplayer_gst_make_file_src(player); + break; + case MM_PLAYER_URI_TYPE_URL_HTTP: + element = __mmplayer_gst_make_http_src(player); + break; + default: + LOGE("not support uri type %d", player->profile.uri_type); + break; + } + + if (!element) { + LOGE("failed to create source element"); + return NULL; + } + + MMPLAYER_FLEAVE(); + return element; +} + int __mmplayer_gst_build_es_pipeline(mm_player_t* player) { MMHandleType attrs = 0; @@ -3874,7 +3905,7 @@ int __mmplayer_gst_build_pd_pipeline(mm_player_t* player) player->ini.http_max_size_bytes, pre_buffering_time, 1.0, player->ini.http_buffering_limit, MUXED_BUFFER_TYPE_MEM_QUEUE, NULL, 0); - pd_decodebin = __mmplayer_create_decodebin(player); + pd_decodebin = __mmplayer_gst_make_decodebin(player); if (!pd_decodebin) { LOGE("failed to create decodebin"); goto ERROR; @@ -3951,13 +3982,13 @@ int __mmplayer_gst_build_pipeline(mm_player_t* player) /* create source element */ switch (player->profile.uri_type) { case MM_PLAYER_URI_TYPE_URL_RTSP: - src_elem = __mmplayer_gst_create_rtsp_src(player); + src_elem = __mmplayer_gst_make_rtsp_src(player); break; case MM_PLAYER_URI_TYPE_URL_HTTP: - src_elem = __mmplayer_gst_create_http_src(player); + src_elem = __mmplayer_gst_make_http_src(player); break; case MM_PLAYER_URI_TYPE_FILE: - src_elem = __mmplayer_gst_create_file_src(player); + src_elem = __mmplayer_gst_make_file_src(player); break; case MM_PLAYER_URI_TYPE_SS: { @@ -4028,7 +4059,7 @@ int __mmplayer_gst_build_pipeline(mm_player_t* player) G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player); } else if (!MMPLAYER_IS_RTSP_STREAMING(player)) { autoplug_elem_id = MMPLAYER_M_AUTOPLUG; - autoplug_elem = __mmplayer_create_decodebin(player); + autoplug_elem = __mmplayer_gst_make_decodebin(player); if (!autoplug_elem) { LOGE("failed to create decodebin"); goto ERROR; @@ -4151,34 +4182,3 @@ int __mmplayer_gst_add_bus_watch(mm_player_t* player) MMPLAYER_FLEAVE(); return MM_ERROR_NONE; } - -GstElement* __mmplayer_gst_build_source(mm_player_t* player) -{ - GstElement* element = NULL; - - MMPLAYER_FENTER(); - MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && - player->pipeline->mainbin, NULL); - - /* setup source for gapless play */ - switch (player->profile.uri_type) { - /* file source */ - case MM_PLAYER_URI_TYPE_FILE: - element = __mmplayer_gst_create_file_src(player); - break; - case MM_PLAYER_URI_TYPE_URL_HTTP: - element = __mmplayer_gst_create_http_src(player); - break; - default: - LOGE("not support uri type %d", player->profile.uri_type); - break; - } - - if (!element) { - LOGE("failed to create source element"); - return NULL; - } - - MMPLAYER_FLEAVE(); - return element; -} diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index a904607..6bbea38 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -2088,10 +2088,10 @@ __mmplayer_gst_decode_callback(GstElement *elem, GstPad *pad, gpointer data) /* 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); + LOGD("display_surface_type (%d)", surface_type); if (surface_type == MM_DISPLAY_SURFACE_NULL) { - LOGD("not make videobin because it dose not want\n"); + LOGD("surface_type is NULL"); goto ERROR; } @@ -3485,7 +3485,7 @@ __mmplayer_gst_create_audio_pipeline(mm_player_t* player) goto ERROR; } - if (FALSE == gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad)) { + if (!gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad)) { LOGE("failed to add ghostpad to audiobin\n"); goto ERROR; } @@ -3914,29 +3914,100 @@ ERROR: return; } +static void +__mmplayer_gst_set_video360_property(mm_player_t *player) +{ + MMPlayerGstElement *videobin = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->videobin); + + videobin = player->pipeline->videobin; + + /* Set spatial media metadata and/or user settings to the element. + * */ + g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), + "projection-type", player->video360_metadata.projection_type, NULL); + + g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), + "stereo-mode", player->video360_metadata.stereo_mode, NULL); + + if (player->video360_metadata.full_pano_width_pixels && + player->video360_metadata.full_pano_height_pixels && + player->video360_metadata.cropped_area_image_width && + player->video360_metadata.cropped_area_image_height) { + g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), + "projection-bounds-top", player->video360_metadata.cropped_area_top, + "projection-bounds-bottom", player->video360_metadata.full_pano_height_pixels - + player->video360_metadata.cropped_area_top - player->video360_metadata.cropped_area_image_height, + "projection-bounds-left", player->video360_metadata.cropped_area_left, + "projection-bounds-right", player->video360_metadata.full_pano_width_pixels - + player->video360_metadata.cropped_area_left - player->video360_metadata.cropped_area_image_width, + NULL); + } + + if (player->video360_horizontal_fov && player->video360_vertical_fov) { + g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), + "horizontal-fov", player->video360_horizontal_fov, + "vertical-fov", player->video360_vertical_fov, NULL); + } + + if (player->video360_zoom <= VIDEO360_MAX_ZOOM && player->video360_zoom > 1.0f) { + g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), + "zoom", 1.0f / player->video360_zoom, NULL); + } + + if (player->video360_yaw_radians <= M_PI && + player->video360_yaw_radians >= -M_PI && + player->video360_pitch_radians <= M_PI_2 && + player->video360_pitch_radians >= -M_PI_2) { + g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), + "pose-yaw", (int) (player->video360_yaw_radians * 180.0 / M_PI), + "pose-pitch", (int) (player->video360_pitch_radians * 180.0 / M_PI), NULL); + } else if (player->video360_metadata.init_view_heading || player->video360_metadata.init_view_pitch) { + g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), + "pose-yaw", player->video360_metadata.init_view_heading, + "pose-pitch", player->video360_metadata.init_view_pitch, NULL); + } + + g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), + "passthrough", !player->is_video360_enabled, NULL); + + + MMPLAYER_FLEAVE(); +} + static int -__mmplayer_gst_create_video_filters(mm_player_t* player, GList** bucket) +__mmplayer_gst_create_video_filters(mm_player_t *player, MMDisplaySurfaceType surface_type, GList **bucket) { - gchar* video_csc = "videoconvert"; /* default colorspace converter */ - GList* element_bucket = NULL; + gchar *video_csc = "videoconvert"; /* default colorspace converter */ + GList *element_bucket = NULL; + MMPLAYER_FENTER(); MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->videobin, MM_ERROR_PLAYER_NOT_INITIALIZED); - MMPLAYER_FENTER(); + /* create video360 filter */ + if (player->is_360_feature_enabled && player->is_content_spherical) { + LOGD("create video360 element"); + MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_360, "video360", "video-360", TRUE, player); + __mmplayer_gst_set_video360_property(player); + goto EXIT; + } - if (player->set_mode.video_zc || (player->is_360_feature_enabled && player->is_content_spherical)) { - LOGD("do not need to add video filters."); + if (surface_type != MM_DISPLAY_SURFACE_OVERLAY || player->set_mode.video_zc) { + LOGD("skip creating the videoconv and rotator"); return MM_ERROR_NONE; } - /* in case of sw codec except 360 playback, + /* in case of sw codec & overlay surface type, except 360 playback. * if libav video decoder is selected, videoconvert is required to render the shm wl-buffer which support RGB only via tizenwlsink. */ + LOGD("create video converter: %s", video_csc); MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", TRUE, player); - LOGD("using video converter: %s", video_csc); /* set video rotator */ MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE, player); +EXIT: *bucket = element_bucket; MMPLAYER_FLEAVE(); return MM_ERROR_NONE; @@ -3949,171 +4020,82 @@ ERROR: /* refer MMPLAYER_CREATE_ELEMENT */ return MM_ERROR_PLAYER_INTERNAL; } -/** - * This function is to create video pipeline. - * - * @param player [in] handle of player - * caps [in] src caps of decoder - * surface_type [in] surface type for video rendering - * - * @return This function returns zero on success. - * @remark - * @see __mmplayer_gst_create_audio_pipeline, __mmplayer_gst_create_midi_pipeline - */ -/** - * VIDEO PIPELINE - * - video overlay surface(arm/x86) : tizenwlsink - */ -static int -__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type) +static gchar* +__mmplayer_get_videosink_factory_name(mm_player_t *player, MMDisplaySurfaceType surface_type) { - GstPad *pad = NULL; - MMHandleType attrs; - GList*element_bucket = NULL; - MMPlayerGstElement* first_element = NULL; - MMPlayerGstElement* videobin = NULL; - gchar *videosink_element = NULL; - - MMPLAYER_FENTER(); + gchar *factory_name = NULL; - MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED); - - /* alloc handles */ - videobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM); - if (!videobin) - return MM_ERROR_PLAYER_NO_FREE_SPACE; - - player->pipeline->videobin = videobin; - - attrs = MMPLAYER_GET_ATTRS(player); - if (!attrs) { - LOGE("cannot get content attribute"); - return MM_ERROR_PLAYER_INTERNAL; - } - - /* create bin */ - videobin[MMPLAYER_V_BIN].id = MMPLAYER_V_BIN; - videobin[MMPLAYER_V_BIN].gst = gst_bin_new("videobin"); - if (!videobin[MMPLAYER_V_BIN].gst) { - LOGE("failed to create videobin"); - goto ERROR; - } - - if (player->is_360_feature_enabled && player->is_content_spherical) { - LOGD("video360 elem will be added."); - - MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_360, "video360", - "video-360", TRUE, player); - - /* Set spatial media metadata and/or user settings to the element. - * */ - g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), - "projection-type", player->video360_metadata.projection_type, NULL); - - g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), - "stereo-mode", player->video360_metadata.stereo_mode, NULL); - - if (player->video360_metadata.full_pano_width_pixels && - player->video360_metadata.full_pano_height_pixels && - player->video360_metadata.cropped_area_image_width && - player->video360_metadata.cropped_area_image_height) { - g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), - "projection-bounds-top", player->video360_metadata.cropped_area_top, - "projection-bounds-bottom", player->video360_metadata.full_pano_height_pixels - - player->video360_metadata.cropped_area_top - player->video360_metadata.cropped_area_image_height, - "projection-bounds-left", player->video360_metadata.cropped_area_left, - "projection-bounds-right", player->video360_metadata.full_pano_width_pixels - - player->video360_metadata.cropped_area_left - player->video360_metadata.cropped_area_image_width, - NULL); - } - - if (player->video360_horizontal_fov && player->video360_vertical_fov) { - g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), - "horizontal-fov", player->video360_horizontal_fov, - "vertical-fov", player->video360_vertical_fov, NULL); - } - - if (player->video360_zoom <= VIDEO360_MAX_ZOOM && player->video360_zoom > 1.0f) { - g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), - "zoom", 1.0f / player->video360_zoom, NULL); - } - - if (player->video360_yaw_radians <= M_PI && - player->video360_yaw_radians >= -M_PI && - player->video360_pitch_radians <= M_PI_2 && - player->video360_pitch_radians >= -M_PI_2) { - g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), - "pose-yaw", (int) (player->video360_yaw_radians * 180.0 / M_PI), - "pose-pitch", (int) (player->video360_pitch_radians * 180.0 / M_PI), NULL); - } else if (player->video360_metadata.init_view_heading || player->video360_metadata.init_view_pitch) { - g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), - "pose-yaw", player->video360_metadata.init_view_heading, - "pose-pitch", player->video360_metadata.init_view_pitch, NULL); - } - - g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst), - "passthrough", !player->is_video360_enabled, NULL); - } - - /* set video sink */ switch (surface_type) { case MM_DISPLAY_SURFACE_OVERLAY: - if (__mmplayer_gst_create_video_filters(player, &element_bucket) != MM_ERROR_NONE) - goto ERROR; if (strlen(player->ini.videosink_element_overlay) > 0) - videosink_element = player->ini.videosink_element_overlay; - else - goto ERROR; + factory_name = player->ini.videosink_element_overlay; break; case MM_DISPLAY_SURFACE_NULL: if (strlen(player->ini.videosink_element_fake) > 0) - videosink_element = player->ini.videosink_element_fake; - else - goto ERROR; + factory_name = player->ini.videosink_element_fake; break; case MM_DISPLAY_SURFACE_REMOTE: if (strlen(player->ini.videosink_element_fake) > 0) - videosink_element = player->ini.videosink_element_fake; - else - goto ERROR; + factory_name = player->ini.videosink_element_fake; break; default: LOGE("unidentified surface type"); - goto ERROR; + break; } - LOGD("surface_type %d, selected videosink name: %s", surface_type, videosink_element); - MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_element, "videosink", TRUE, player); + LOGD("surface_type %d, videosink is %s", surface_type, factory_name); + return factory_name; +} - /* additional setting for sink plug-in */ - switch (surface_type) { - case MM_DISPLAY_SURFACE_OVERLAY: - { - bool use_tbm = (player->set_mode.video_zc || (player->is_360_feature_enabled && player->is_content_spherical)); - if (!use_tbm) { - LOGD("selected videosink name: %s", videosink_element); - - /* support shard memory with S/W codec on HawkP */ - if (strncmp(videosink_element, "tizenwlsink", strlen(videosink_element)) == 0) { - g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, - "use-tbm", use_tbm, NULL); - } - } else { - if (attrs) { - int gapless = 0; +static int +__mmplayer_gst_set_videosink_property(mm_player_t *player, MMDisplaySurfaceType surface_type) +{ + gchar *factory_name = NULL; + MMPlayerGstElement *videobin = NULL; + MMHandleType attrs; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->videobin, MM_ERROR_PLAYER_NOT_INITIALIZED); - mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless); + videobin = player->pipeline->videobin; + factory_name = GST_OBJECT_NAME(gst_element_get_factory(videobin[MMPLAYER_V_SINK].gst)); - if (gapless > 0) { - LOGD("disable last-sample"); - g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "enable-last-sample", FALSE, NULL); + attrs = MMPLAYER_GET_ATTRS(player); + if (!attrs) { + LOGE("cannot get content attribute"); + return MM_ERROR_PLAYER_INTERNAL; + } + + if (surface_type == MM_DISPLAY_SURFACE_OVERLAY || surface_type == MM_DISPLAY_SURFACE_REMOTE) { + int gapless = 0; + + if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) { + bool use_tbm = (player->set_mode.video_zc || (player->is_360_feature_enabled && player->is_content_spherical)); + LOGD("OVERLAY: selected videosink is %s", factory_name); + + if (!use_tbm) { + /* support shard memory with S/W codec on HawkP */ + if (strncmp(factory_name, "tizenwlsink", strlen(factory_name)) == 0) { + g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, + "use-tbm", use_tbm, NULL); } } + } else { + LOGE("REMOTE : add data probe at videosink"); + g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), + "sync", TRUE, "max-lateness", FAKE_SINK_MAX_LATENESS, NULL); + } + + mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless); + if (gapless > 0) { + LOGD("disable last-sample"); + g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "enable-last-sample", FALSE, NULL); } + if (player->set_mode.media_packet_video_stream) { int enable = 0; mm_attrs_get_int_by_name(player->attrs, "enable_video_decoded_cb", &enable); - if (enable) + if (enable || (surface_type == MM_DISPLAY_SURFACE_REMOTE)) g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "signal-handoffs", TRUE, NULL); __mmplayer_add_signal_connection(player, @@ -4130,47 +4112,10 @@ __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDispl G_CALLBACK(__mmplayer_video_stream_decoded_preroll_cb), (gpointer)player); } - break; - } - case MM_DISPLAY_SURFACE_REMOTE: - { - if (player->set_mode.media_packet_video_stream) { - LOGE("add data probe at videosink"); - g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), - "sync", TRUE, "signal-handoffs", TRUE, "max-lateness", FAKE_SINK_MAX_LATENESS, NULL); - - __mmplayer_add_signal_connection(player, - G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), - MM_PLAYER_SIGNAL_TYPE_VIDEOBIN, - "handoff", - G_CALLBACK(__mmplayer_video_stream_decoded_render_cb), - (gpointer)player); - - __mmplayer_add_signal_connection(player, - G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), - MM_PLAYER_SIGNAL_TYPE_VIDEOBIN, - "preroll-handoff", - G_CALLBACK(__mmplayer_video_stream_decoded_preroll_cb), - (gpointer)player); - if (attrs) { - int gapless = 0; - - mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless); - - if (gapless > 0) { - LOGD("disable last-sample"); - g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "enable-last-sample", FALSE, NULL); - } - } - } - break; - } - default: - break; } if (_mmplayer_update_video_param(player, "update_all_param") != MM_ERROR_NONE) - goto ERROR; + return MM_ERROR_PLAYER_INTERNAL; if (videobin[MMPLAYER_V_SINK].gst) { GstPad *sink_pad = NULL; @@ -4179,8 +4124,55 @@ __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDispl __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_VIDEOBIN, "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player); gst_object_unref(GST_OBJECT(sink_pad)); - } else - LOGW("failed to get sink pad from videosink\n"); + } else { + LOGE("failed to get sink pad from videosink"); + } + } + + return MM_ERROR_NONE; +} + +/** + * VIDEO PIPELINE + * - video overlay surface(arm/x86) : tizenwlsink + */ +static int +__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type) +{ + GstPad *pad = NULL; + GList *element_bucket = NULL; + MMPlayerGstElement *first_element = NULL; + MMPlayerGstElement *videobin = NULL; + gchar *videosink_factory_name = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED); + + /* alloc handles */ + videobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM); + if (!videobin) + return MM_ERROR_PLAYER_NO_FREE_SPACE; + + player->pipeline->videobin = videobin; + + /* create bin */ + videobin[MMPLAYER_V_BIN].id = MMPLAYER_V_BIN; + videobin[MMPLAYER_V_BIN].gst = gst_bin_new("videobin"); + if (!videobin[MMPLAYER_V_BIN].gst) { + LOGE("failed to create videobin"); + goto ERROR; + } + + if (__mmplayer_gst_create_video_filters(player, surface_type, &element_bucket) != MM_ERROR_NONE) + goto ERROR; + + videosink_factory_name = __mmplayer_get_videosink_factory_name(player, surface_type); + MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_factory_name, "videosink", TRUE, player); + + /* additional setting for sink plug-in */ + if (__mmplayer_gst_set_videosink_property(player, surface_type) != MM_ERROR_NONE) { + LOGE("failed to set video property"); + goto ERROR; } /* store it as it's sink element */ @@ -4188,49 +4180,46 @@ __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDispl /* adding created elements to bin */ if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket)) { - LOGE("failed to add elements\n"); + LOGE("failed to add elements"); goto ERROR; } /* Linking elements in the bucket by added order */ if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) { - LOGE("failed to link elements\n"); + LOGE("failed to link elements"); goto ERROR; } /* get first element's sinkpad for creating ghostpad */ - if (element_bucket) - first_element = (MMPlayerGstElement *)element_bucket->data; + first_element = (MMPlayerGstElement *)element_bucket->data; if (!first_element) { - LOGE("failed to get first element from bucket\n"); + LOGE("failed to get first element from bucket"); goto ERROR; } pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink"); if (!pad) { - LOGE("failed to get pad from first element\n"); + LOGE("failed to get pad from first element"); goto ERROR; } /* create ghostpad */ player->ghost_pad_for_videobin = gst_ghost_pad_new("sink", pad); - if (FALSE == gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, player->ghost_pad_for_videobin)) { - LOGE("failed to add ghostpad to videobin\n"); + if (!gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, player->ghost_pad_for_videobin)) { + LOGE("failed to add ghostpad to videobin"); goto ERROR; } gst_object_unref(pad); /* done. free allocated variables */ - if (element_bucket) - g_list_free(element_bucket); + g_list_free(element_bucket); MMPLAYER_FLEAVE(); return MM_ERROR_NONE; ERROR: - LOGE("ERROR : releasing videobin\n"); - + LOGE("ERROR : releasing videobin"); g_list_free(element_bucket); if (pad) @@ -4240,9 +4229,7 @@ ERROR: if (videobin[MMPLAYER_V_BIN].gst) gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst)); - MMPLAYER_FREEIF(videobin); - player->pipeline->videobin = NULL; return MM_ERROR_PLAYER_INTERNAL; @@ -6835,7 +6822,7 @@ GstCaps *caps, gpointer data) return; } - if (!__mmplayer_try_to_plug_decodebin(player, pad, caps)) { + if (!__mmplayer_gst_create_decoder(player, pad, caps)) { gboolean async = FALSE; LOGE("failed to autoplug %s\n", player->type); @@ -6856,7 +6843,7 @@ DONE: } GstElement * -__mmplayer_create_decodebin(mm_player_t* player) +__mmplayer_gst_make_decodebin(mm_player_t* player) { GstElement *decodebin = NULL; @@ -6908,105 +6895,122 @@ ERROR: return decodebin; } -gboolean -__mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps) +static GstElement* +__mmplayer_gst_make_queue2(mm_player_t *player) { - MMPlayerGstElement* mainbin = NULL; - GstElement* decodebin = NULL; GstElement* queue2 = NULL; - GstPad* sinkpad = NULL; - GstPad* qsrcpad = NULL; gint64 dur_bytes = 0L; - guint max_buffer_size_bytes = 0; - gint init_buffering_time = player->streamer->buffering_req.prebuffer_time; + MMPlayerGstElement *mainbin = NULL; + MuxedBufferType type = MUXED_BUFFER_TYPE_MEM_QUEUE; MMPLAYER_FENTER(); - MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, FALSE); + MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, NULL); mainbin = player->pipeline->mainbin; - if ((!MMPLAYER_IS_HTTP_PD(player)) && - (MMPLAYER_IS_HTTP_STREAMING(player))) { - LOGD("creating http streaming buffering queue(queue2)\n"); + queue2 = gst_element_factory_make("queue2", "queue2"); + if (!queue2) { + LOGE("failed to create buffering queue element"); + return NULL; + } - if (mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst) { - LOGE("MMPLAYER_M_MUXED_S_BUFFER is not null\n"); + if (!gst_element_query_duration(mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes)) + LOGE("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst)); + + LOGD("dur_bytes = %"G_GINT64_FORMAT, dur_bytes); + + if (dur_bytes > 0) { + if (MMPLAYER_USE_FILE_FOR_BUFFERING(player)) { + type = MUXED_BUFFER_TYPE_FILE; } else { - queue2 = gst_element_factory_make("queue2", "queue2"); - if (!queue2) { - LOGE("failed to create buffering queue element\n"); - goto ERROR; - } + type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER; + player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size; + } + } else { + dur_bytes = 0; + } - if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue2)) { - LOGE("failed to add buffering queue\n"); - goto ERROR; - } + /* NOTE : in case of ts streaming, player cannot get the correct duration info * + * skip the pull mode(file or ring buffering) setting. */ + if (!g_strrstr(player->type, "video/mpegts")) { + max_buffer_size_bytes = (type == MUXED_BUFFER_TYPE_FILE) ? (player->ini.http_max_size_bytes) : (5*1024*1024); + LOGD("max_buffer_size_bytes = %d", max_buffer_size_bytes); - sinkpad = gst_element_get_static_pad(queue2, "sink"); - qsrcpad = gst_element_get_static_pad(queue2, "src"); + __mm_player_streaming_set_queue2(player->streamer, + queue2, + FALSE, + max_buffer_size_bytes, + player->ini.http_buffering_time, + 1.0, /* no meaning */ + player->ini.http_buffering_limit, /* no meaning */ + type, + player->http_file_buffering_path, + (guint64)dur_bytes); + } - if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) { - LOGE("failed to link buffering queue"); - goto ERROR; - } + return queue2; +} - if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes)) - LOGE("fail to get duration"); +gboolean +__mmplayer_gst_create_decoder(mm_player_t* player, GstPad *srcpad, const GstCaps *caps) +{ + MMPlayerGstElement* mainbin = NULL; + GstElement* decodebin = NULL; + GstElement* queue2 = NULL; + GstPad* sinkpad = NULL; + GstPad* qsrcpad = NULL; + gint init_buffering_time = player->streamer->buffering_req.prebuffer_time; - LOGD("dur_bytes = %"G_GINT64_FORMAT, dur_bytes); + MMPLAYER_FENTER(); + MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, FALSE); - MuxedBufferType type = MUXED_BUFFER_TYPE_MEM_QUEUE; + mainbin = player->pipeline->mainbin; - if (dur_bytes > 0) { - if (MMPLAYER_USE_FILE_FOR_BUFFERING(player)) { - type = MUXED_BUFFER_TYPE_FILE; - } else { - type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER; - player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size; - } - } else { - dur_bytes = 0; - } + if ((!MMPLAYER_IS_HTTP_PD(player)) && (MMPLAYER_IS_HTTP_STREAMING(player))) { - /* NOTE : in case of ts streaming, player cannot get the correct duration info * - * skip the pull mode(file or ring buffering) setting. */ - if (!g_strrstr(player->type, "video/mpegts")) { - max_buffer_size_bytes = (type == MUXED_BUFFER_TYPE_FILE) ? (player->ini.http_max_size_bytes) : (5*1024*1024); - LOGD("max_buffer_size_bytes = %d", max_buffer_size_bytes); - - __mm_player_streaming_set_queue2(player->streamer, - queue2, - FALSE, - max_buffer_size_bytes, - player->ini.http_buffering_time, - 1.0, /* no meaning */ - player->ini.http_buffering_limit, /* no meaning */ - type, - player->http_file_buffering_path, - (guint64)dur_bytes); - } + if (mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst) { + LOGW("need to check: muxed buffer is not null"); + } - if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent(queue2)) { - LOGE("failed to sync queue2 state with parent\n"); - goto ERROR; - } + queue2 = __mmplayer_gst_make_queue2(player); + if (!queue2) { + LOGE("failed to make queue2"); + goto ERROR; + } - srcpad = qsrcpad; + if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue2)) { + LOGE("failed to add buffering queue"); + goto ERROR; + } - gst_object_unref(GST_OBJECT(sinkpad)); + sinkpad = gst_element_get_static_pad(queue2, "sink"); + qsrcpad = gst_element_get_static_pad(queue2, "src"); + + if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) { + LOGE("failed to link [%s:%s]-[%s:%s]", + GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad)); + goto ERROR; + } - mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER; - mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = queue2; + if (gst_element_sync_state_with_parent(queue2) == GST_STATE_CHANGE_FAILURE) { + LOGE("failed to sync queue2 state with parent"); + goto ERROR; } + + mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER; + mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = queue2; + + srcpad = qsrcpad; + + gst_object_unref(GST_OBJECT(sinkpad)); + sinkpad = NULL; } /* create decodebin */ - decodebin = __mmplayer_create_decodebin(player); - + decodebin = __mmplayer_gst_make_decodebin(player); if (!decodebin) { - LOGE("can not create autoplug element\n"); + LOGE("failed to make decodebin"); goto ERROR; } @@ -7023,11 +7027,13 @@ __mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstC sinkpad = gst_element_get_static_pad(decodebin, "sink"); if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) { - LOGE("failed to link decodebin\n"); + LOGE("failed to link [%s:%s]-[%s:%s]", + GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad)); goto ERROR; } gst_object_unref(GST_OBJECT(sinkpad)); + sinkpad = NULL; mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG; mainbin[MMPLAYER_M_AUTOPLUG].gst = decodebin; @@ -7473,7 +7479,7 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target) goto ERROR; } - element = __mmplayer_gst_build_source(player); + element = __mmplayer_gst_create_source(player); if (!element) { LOGE("no source element was created"); goto ERROR; @@ -7504,7 +7510,7 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target) MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player); } else { elemId = MMPLAYER_M_AUTOPLUG; - element = __mmplayer_create_decodebin(player); + element = __mmplayer_gst_make_decodebin(player); } /* check autoplug element is OK */