summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyunil Park <hyunil46.park@samsung.com>2015-02-26 13:42:58 +0900
committerHyunil Park <hyunil46.park@samsung.com>2015-02-26 13:48:06 +0900
commite98c086974ed3e49af64c3f056cf350092c3c246 (patch)
tree17724a64c755ffb849a9684c780f48dff9fed18f
parent3b0cc28c51008bc833ef90ff4741e1149279373f (diff)
downloadlibmm-player-e98c086974ed3e49af64c3f056cf350092c3c246.tar.gz
libmm-player-e98c086974ed3e49af64c3f056cf350092c3c246.tar.bz2
libmm-player-e98c086974ed3e49af64c3f056cf350092c3c246.zip
Change-Id: I2cbb317df13c29e660f7dee80b15c8219adf4cfd Signed-off-by: Hyunil Park <hyunil46.park@samsung.com>
-rw-r--r--packaging/libmm-player.spec2
-rwxr-xr-xsrc/include/mm_player_internal.h16
-rwxr-xr-xsrc/include/mm_player_priv_internal.h56
-rwxr-xr-xsrc/include/mm_player_priv_locl_func.h93
-rwxr-xr-xsrc/mm_player.c39
-rwxr-xr-xsrc/mm_player_capture.c24
-rwxr-xr-xsrc/mm_player_priv.c141
-rwxr-xr-xsrc/mm_player_priv_gst.c1106
-rwxr-xr-xsrc/mm_player_priv_gst_wrapper.c2940
-rwxr-xr-xsrc/mm_player_priv_internal.c1179
10 files changed, 84 insertions, 5512 deletions
diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec
index 650d566..41eb3a0 100644
--- a/packaging/libmm-player.spec
+++ b/packaging/libmm-player.spec
@@ -1,7 +1,7 @@
Name: libmm-player
Summary: Multimedia Framework Player Library
Version: 0.5.56
-Release: 0
+Release: 1
Group: Multimedia/Libraries
License: Apache-2.0
URL: http://source.tizen.org
diff --git a/src/include/mm_player_internal.h b/src/include/mm_player_internal.h
index a830a4e..e298fbf 100755
--- a/src/include/mm_player_internal.h
+++ b/src/include/mm_player_internal.h
@@ -213,6 +213,22 @@ int mm_player_set_play_speed(MMHandleType player, float rate);
int mm_player_set_video_stream_callback(MMHandleType player, mm_player_video_stream_callback callback, void *user_param);
/**
+ * This function set callback function for rendering error information of video render plug-in.
+ *
+ * @param player [in] Handle of player.
+ * @param callback [in] Frame render error callback function.
+ * @param user_param [in] User parameter which is passed to callback function.
+ *
+ * @return This function returns zero on success, or negative value with error code.
+ * @see
+ * @remark None
+ * @par Example
+ * @code
+ * @endcode
+ */
+int mm_player_set_video_frame_render_error_callback(MMHandleType player, mm_player_video_frame_render_error_callback callback, void *user_param);
+
+/**
* This function is to capture video frame.
*
* @param player [in] Handle of player.
diff --git a/src/include/mm_player_priv_internal.h b/src/include/mm_player_priv_internal.h
deleted file mode 100755
index c6588dc..0000000
--- a/src/include/mm_player_priv_internal.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * libmm-player
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __MM_PLAYER_PRIV_INTERNAL_H__
-#define __MM_PLAYER_PRIV_INTERNAL_H__
-
-#define MM_PLAYER_FADEOUT_TIME_DEFAULT 700000 // 700 msec
-
-
-/*---------------------------------------------------------------------------
-| LOCAL FUNCTION PROTOTYPES: |
----------------------------------------------------------------------------*/
-void __mmplayer_release_signal_connection(mm_player_t* player);
-gboolean __mmplayer_dump_pipeline_state(mm_player_t* player);
-int __mmplayer_gst_set_state (mm_player_t* player, GstElement * element, GstState state, gboolean async, gint timeout);
-void __mmplayer_cancel_delayed_eos(mm_player_t* player);
-gboolean __mmplayer_check_subtitle(mm_player_t* player);
-int __mmplayer_handle_missed_plugin(mm_player_t* player);
-gboolean __mmplayer_link_decoder(mm_player_t* player, GstPad *srcpad);
-gboolean __mmplayer_link_sink(mm_player_t* player , GstPad *srcpad);
-gint __gst_handle_core_error(mm_player_t* player, int code);
-gint __gst_handle_library_error(mm_player_t* player, int code);
-gint __gst_handle_resource_error(mm_player_t* player, int code);
-gint __gst_handle_stream_error(mm_player_t* player, GError* error, GstMessage * message);
-gint __gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error );
-gboolean __mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error );
-gboolean __mmplayer_handle_streaming_error ( mm_player_t* player, GstMessage * message );
-void __mmplayer_add_sink( mm_player_t* player, GstElement* sink );
-void __mmplayer_del_sink( mm_player_t* player, GstElement* sink );
-gboolean __is_rtsp_streaming ( mm_player_t* player );
-gboolean __is_http_streaming ( mm_player_t* player );
-gboolean __is_streaming ( mm_player_t* player );
-gboolean __is_live_streaming ( mm_player_t* player );
-gboolean __is_http_live_streaming( mm_player_t* player );
-gboolean __is_http_progressive_down(mm_player_t* player);
-
-#endif /* __MM_PLAYER_PRIV_INTERNAL_H__ */
-
diff --git a/src/include/mm_player_priv_locl_func.h b/src/include/mm_player_priv_locl_func.h
deleted file mode 100755
index 62f654a..0000000
--- a/src/include/mm_player_priv_locl_func.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * libmm-player
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __MM_PLAYER_LOCAL_FUNCTION_DEF_H_
-#define __MM_PLAYER_LOCAL_FUNCTION_DEF_H_
-
-
-/*---------------------------------------------------------------------------
-| LOCAL FUNCTION PROTOTYPES: |
----------------------------------------------------------------------------*/
-/* mm_player_priv.c */
-gboolean __mmplayer_set_state(mm_player_t* player, int state);
-void __mmplayer_typefind_have_type( GstElement *tf, guint probability, GstCaps *caps, gpointer data);
-gboolean __mmplayer_try_to_plug(mm_player_t* player, GstPad *pad, const GstCaps *caps);
-void __mmplayer_pipeline_complete(GstElement *decodebin, gpointer data);
-gboolean __mmplayer_update_subtitle( GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
-void __mmplayer_release_misc(mm_player_t* player);
-gboolean __mmplayer_configure_audio_callback(mm_player_t* player);
-void __mmplayer_set_antishock( mm_player_t* player, gboolean disable_by_force);
-gboolean _mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag);
-void __mmplayer_videostream_cb(GstElement *element, void *stream, int width, int height, gpointer data);
-void __mmplayer_videoframe_render_error_cb(GstElement *element, void *error_id, gpointer data);
-void __mmplayer_handle_buffering_message ( mm_player_t* player );
-int __mmplayer_set_pcm_extraction(mm_player_t* player);
-gboolean __mmplayer_can_extract_pcm( mm_player_t* player );
-void __mmplayer_do_sound_fadedown(mm_player_t* player, unsigned int time);
-void __mmplayer_undo_sound_fadedown(mm_player_t* player);
-const gchar * __get_state_name ( int state );
-GstBusSyncReply __mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data);
-void __mmplayer_post_delayed_eos( mm_player_t* player, int delay_in_ms );
-void __gst_set_async_state_change(mm_player_t* player, gboolean async);
-gboolean __mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param);
-
-/* mm_player_priv_wrapper.c */
-gboolean __mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data);
-gboolean __mmplayer_gst_handle_duration(mm_player_t* player, GstMessage* msg);
-gboolean __mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage* msg);
-void __mmplayer_gst_rtp_no_more_pads (GstElement *element, gpointer data);
-gboolean __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink);
-void __mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data);
-void __mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data);
-int __mmplayer_gst_element_link_bucket(GList* element_bucket);
-int __mmplayer_gst_element_add_bucket_to_bin(GstBin* bin, GList* element_bucket);
-int __mmplayer_gst_create_audio_pipeline(mm_player_t* player);
-int __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type);
-int __mmplayer_gst_create_text_pipeline(mm_player_t* player);
-int __mmplayer_gst_create_subtitle_src(mm_player_t* player);
-int __mmplayer_gst_create_pipeline(mm_player_t* player);
-int __mmplayer_gst_destroy_pipeline(mm_player_t* player);
-
-/* mm_player_priv_gst.c */
-int __gst_realize(mm_player_t* player);
-int __gst_unrealize(mm_player_t* player);
-int __gst_pending_seek(mm_player_t* player);
-int __gst_start(mm_player_t* player);
-int __gst_stop(mm_player_t* player);
-int __gst_pause(mm_player_t* player, gboolean async);
-int __gst_resume(mm_player_t* player, gboolean async);
-int __gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called);
-int __gst_get_position(mm_player_t* player, int format, unsigned long* position);
-int __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos);
-int __gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param);
-gboolean __gst_send_event_to_sink( mm_player_t* player, GstEvent* event );
-gboolean __gst_seek(mm_player_t* player, GstElement * element, gdouble rate,
- GstFormat format, GstSeekFlags flags, GstSeekType cur_type,
- gint64 cur, GstSeekType stop_type, gint64 stop);
-int __gst_adjust_subtitle_position(mm_player_t* player, int format, unsigned long position);
-void __gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data);
-gboolean __gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data);
-void __gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data);
-gboolean __gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data);
-gboolean __gst_appsrc_enough_data(GstElement *element, gpointer user_data);
-
-#endif /*#ifndef __MM_PLAYER_LOCAL_FUNCTION_DEF_H_*/
-
diff --git a/src/mm_player.c b/src/mm_player.c
index 75784c6..d801a98 100755
--- a/src/mm_player.c
+++ b/src/mm_player.c
@@ -57,30 +57,13 @@ int mm_player_create(MMHandleType *player)
/* create player lock */
g_mutex_init(&new_player->cmd_lock);
- if (!(&new_player->cmd_lock))
- {
- debug_error("failed to create player lock\n");
- goto ERROR;
- }
-
/* create player lock */
g_mutex_init(&new_player->playback_lock);
- if (!(&new_player->playback_lock) )
- {
- debug_error("failed to create playback_lock\n");
- goto ERROR;
- }
/* create msg callback lock */
g_mutex_init(&new_player->msg_cb_lock);
- if (!(&new_player->msg_cb_lock))
- {
- debug_error("failed to create msg cb lock\n");
- goto ERROR;
- }
-
/* load ini files */
result = mm_player_ini_load(&new_player->ini);
if(result != MM_ERROR_NONE)
@@ -114,15 +97,8 @@ ERROR:
if ( new_player )
{
- if (&new_player->cmd_lock)
- {
- g_mutex_clear(&new_player->cmd_lock);
- }
-
- if (&new_player->playback_lock)
- {
- g_mutex_clear(&new_player->playback_lock);
- }
+ g_mutex_clear(&new_player->cmd_lock);
+ g_mutex_clear(&new_player->playback_lock);
_mmplayer_destroy( (MMHandleType)new_player );
@@ -145,15 +121,8 @@ int mm_player_destroy(MMHandleType player)
MMPLAYER_CMD_UNLOCK( player );
- if (&((mm_player_t*)player)->cmd_lock)
- {
- g_mutex_clear(&((mm_player_t*)player)->cmd_lock);
- }
-
- if (&((mm_player_t*)player)->playback_lock)
- {
- g_mutex_clear(&((mm_player_t*)player)->playback_lock);
- }
+ g_mutex_clear(&((mm_player_t*)player)->cmd_lock);
+ g_mutex_clear(&((mm_player_t*)player)->playback_lock);
memset( (mm_player_t*)player, 0x00, sizeof(mm_player_t) );
diff --git a/src/mm_player_capture.c b/src/mm_player_capture.c
index e3bd5d8..e4b1083 100755
--- a/src/mm_player_capture.c
+++ b/src/mm_player_capture.c
@@ -58,19 +58,10 @@ _mmplayer_initialize_video_capture(mm_player_t* player)
return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
/* create capture mutex */
g_mutex_init(&player->capture_thread_mutex);
- if ( !(&player->capture_thread_mutex) )
- {
- debug_error("Cannot create capture mutex");
- goto ERROR;
- }
/* create capture cond */
g_cond_init(&player->capture_thread_cond);
- if (!(&player->capture_thread_cond) )
- {
- debug_error("Cannot create capture cond");
- goto ERROR;
- }
+
player->capture_thread_exit = FALSE;
@@ -87,11 +78,9 @@ _mmplayer_initialize_video_capture(mm_player_t* player)
ERROR:
/* capture thread */
- if ( &player->capture_thread_mutex )
- g_mutex_clear(&player->capture_thread_mutex );
+ g_mutex_clear(&player->capture_thread_mutex );
- if (&player->capture_thread_cond )
- g_cond_clear (&player->capture_thread_cond );
+ g_cond_clear (&player->capture_thread_cond );
return MM_ERROR_PLAYER_INTERNAL;
}
@@ -101,9 +90,7 @@ _mmplayer_release_video_capture(mm_player_t* player)
{
return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
/* release capture thread */
- if ( &player->capture_thread_cond &&
- &player->capture_thread_mutex &&
- player->capture_thread )
+ if (player->capture_thread)
{
g_mutex_lock(&player->capture_thread_mutex);
player->capture_thread_exit = TRUE;
@@ -314,11 +301,12 @@ __mmplayer_capture_thread(gpointer data)
return_val_if_fail(player, NULL);
+ g_mutex_lock(&player->capture_thread_mutex);
+
while (!player->capture_thread_exit)
{
debug_log("capture thread started. waiting for signal");
- g_mutex_lock(&player->capture_thread_mutex);
g_cond_wait(&player->capture_thread_cond, &player->capture_thread_mutex );
if ( player->capture_thread_exit )
diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c
index def0e2e..a97b693 100755
--- a/src/mm_player_priv.c
+++ b/src/mm_player_priv.c
@@ -182,7 +182,7 @@ int __mmplayer_switch_audio_sink (mm_player_t* player);
static gboolean __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink);
static int __mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command);
static GstPadProbeReturn __mmplayer_audio_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
-//static gboolean __mmplayer_video_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data);
+static GstPadProbeReturn __mmplayer_video_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
static GstPadProbeReturn __mmplayer_subtitle_adjust_position_probe (GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
static int __mmplayer_change_selector_pad (mm_player_t* player, MMPlayerTrackType type, int index);
@@ -288,6 +288,8 @@ void __mmplayer_inc_cb_score(mm_player_t* player);
void __mmplayer_post_proc_reset(mm_player_t* player);
void __mmplayer_device_change_trigger_post_process(mm_player_t* player);
static int __mmplayer_gst_create_plain_text_elements(mm_player_t* player);
+static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar* format_name);
+
/*===========================================================================================
@@ -3125,10 +3127,8 @@ __mmplayer_gst_decode_pad_added (GstElement *elem, GstPad *pad, gpointer data)
goto ERROR;
}
-#if 0
if (player->set_mode.media_packet_video_stream)
- player->video_cb_probe_id = gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_BUFFER, G_CALLBACK (__mmplayer_video_stream_probe), player, NULL);
-#endif
+ player->video_cb_probe_id = gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_BUFFER, __mmplayer_video_stream_probe, player, NULL);
g_object_set (G_OBJECT (fakesink), "async", TRUE, NULL);
g_object_set (G_OBJECT (fakesink), "sync", TRUE, NULL);
@@ -5434,25 +5434,35 @@ __mmplayer_audio_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer u_da
return GST_PAD_PROBE_OK;
}
+static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar* format_name)
+{
+ return format_name[0] | (format_name[1] << 8) | (format_name[2] << 16) | (format_name[3] << 24);
+}
-#if 0
-static gboolean
-__mmplayer_video_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer user_data)
+static GstPadProbeReturn
+__mmplayer_video_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
{
GstCaps *caps = NULL;
MMPlayerVideoStreamDataType stream;
MMPlayerMPlaneImage *scmn_imgb = NULL;
+ GstMemory *dataBlock = NULL;
+ GstMemory *metaBlock = NULL;
+ GstMapInfo mapinfo = GST_MAP_INFO_INIT;
GstStructure *structure = NULL;
unsigned int fourcc = 0;
mm_player_t* player = (mm_player_t*)user_data;
+ GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
- caps = gst_buffer_get_caps(buffer);
+ return_val_if_fail(buffer, GST_PAD_PROBE_DROP);
+ return_val_if_fail(gst_buffer_n_memory(buffer) , GST_PAD_PROBE_DROP);
+
+ caps = gst_pad_get_current_caps(pad);
if (caps == NULL) {
debug_error( "Caps is NULL." );
- return TRUE;
+ return GST_PAD_PROBE_OK;
}
- //MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+ MMPLAYER_LOG_GST_CAPS_TYPE(caps);
/* clear stream data structure */
memset(&stream, 0x0, sizeof(MMPlayerVideoStreamDataType));
@@ -5460,7 +5470,7 @@ __mmplayer_video_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer user_dat
structure = gst_caps_get_structure( caps, 0 );
gst_structure_get_int(structure, "width", &(stream.width));
gst_structure_get_int(structure, "height", &(stream.height));
- gst_structure_get_fourcc(structure, "format", &fourcc);
+ fourcc = _mmplayer_convert_fourcc_string_to_value(gst_structure_get_string(structure, "format"));
stream.format = util_get_pixtype(fourcc);
gst_caps_unref( caps );
caps = NULL;
@@ -5476,14 +5486,17 @@ __mmplayer_video_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer user_dat
}
/* set size and timestamp */
- stream.length_total = GST_BUFFER_SIZE(buffer);
- stream.timestamp = (unsigned int)(GST_BUFFER_TIMESTAMP(buffer)/1000000); /* nano sec -> mili sec */
+ dataBlock = gst_buffer_peek_memory(buffer, 0);
+ stream.length_total = gst_memory_get_sizes(dataBlock, NULL, NULL);
+ stream.timestamp = (unsigned int)(GST_BUFFER_PTS(buffer)/1000000); /* nano sec -> mili sec */
- //check zero-copy
- if (player->set_mode.video_zc
- && player->set_mode.media_packet_video_stream
- && GST_BUFFER_MALLOCDATA(buffer)) {
- scmn_imgb = (MMPlayerMPlaneImage *)GST_BUFFER_MALLOCDATA(buffer);
+ /* check zero-copy */
+ if (player->set_mode.video_zc &&
+ player->set_mode.media_packet_video_stream &&
+ gst_buffer_n_memory(buffer) > 1) {
+ metaBlock = gst_buffer_peek_memory(buffer, 1);
+ gst_memory_map(metaBlock, &mapinfo, GST_MAP_READ);
+ scmn_imgb = (MMPlayerMPlaneImage *)mapinfo.data;
}
/* set tbm bo */
@@ -5501,16 +5514,22 @@ __mmplayer_video_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer user_dat
/* set gst buffer */
stream.internal_buffer = buffer;
} else {
- stream.data = GST_BUFFER_DATA(buffer);
+ gst_memory_map(dataBlock, &mapinfo, GST_MAP_READWRITE);
+ stream.data = mapinfo.data;
}
if (player->video_stream_cb) {
player->video_stream_cb(&stream, player->video_stream_cb_user_param);
}
- return TRUE;
+ if (metaBlock) {
+ gst_memory_unmap(metaBlock, &mapinfo);
+ }else {
+ gst_memory_unmap(dataBlock, &mapinfo);
+ }
+
+ return GST_PAD_PROBE_OK;
}
-#endif
static int
__mmplayer_gst_create_video_filters(mm_player_t* player, GList** bucket, gboolean use_video_stream)
@@ -8809,6 +8828,7 @@ __mmplayer_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_com
cb_res = ASM_CB_RES_PAUSE;
}
break;
+
case ASM_COMMAND_RESUME:
{
debug_warning("Got msg from asm to Resume. So, application can resume. code (%d) \n", event_src);
@@ -8821,6 +8841,7 @@ __mmplayer_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_com
goto DONE;
}
break;
+
default:
break;
}
@@ -8878,52 +8899,23 @@ _mmplayer_create_player(MMHandleType handle) // @
/* create lock. note that g_tread_init() has already called in gst_init() */
g_mutex_init(&player->fsink_lock);
- if (!(&player->fsink_lock) )
- {
- debug_error("Cannot create mutex for command lock\n");
- goto ERROR;
- }
/* create repeat mutex */
g_mutex_init(&player->repeat_thread_mutex);
- if (!(&player->repeat_thread_mutex))
- {
- debug_error("Cannot create repeat mutex\n");
- goto ERROR;
- }
/* create repeat cond */
g_cond_init(&player->repeat_thread_cond);
- if (!(&player->repeat_thread_cond))
- {
- debug_error("Cannot create repeat cond\n");
- goto ERROR;
- }
/* create repeat thread */
player->repeat_thread =
g_thread_try_new ("repeat_thread", __mmplayer_repeat_thread, (gpointer)player, NULL);
- if ( ! player->repeat_thread )
- {
- debug_error("failed to create repeat thread");
- goto ERROR;
- }
+
/* create next play mutex */
g_mutex_init(&player->next_play_thread_mutex);
- if (!(&player->next_play_thread_mutex))
- {
- debug_error("Cannot create next_play mutex\n");
- goto ERROR;
- }
/* create next play cond */
g_cond_init(&player->next_play_thread_cond);
- if (! (&player->next_play_thread_cond))
- {
- debug_error("Cannot create next_play cond\n");
- goto ERROR;
- }
/* create next play thread */
player->next_play_thread =
@@ -8998,13 +8990,10 @@ _mmplayer_create_player(MMHandleType handle) // @
ERROR:
/* free lock */
- if ( &player->fsink_lock )
- g_mutex_clear(&player->fsink_lock );
+ g_mutex_clear(&player->fsink_lock );
/* free thread */
- if ( &player->repeat_thread_cond &&
- &player->repeat_thread_mutex &&
- player->repeat_thread )
+ if ( player->repeat_thread )
{
player->repeat_thread_exit = TRUE;
g_cond_signal( &player->repeat_thread_cond );
@@ -9019,16 +9008,11 @@ ERROR:
/* clear repeat thread mutex/cond if still alive
* this can happen if only thread creating has failed
*/
- if ( &player->repeat_thread_mutex )
- g_mutex_clear(&player->repeat_thread_mutex );
-
- if ( &player->repeat_thread_cond )
- g_cond_clear ( &player->repeat_thread_cond );
+ g_mutex_clear(&player->repeat_thread_mutex );
+ g_cond_clear ( &player->repeat_thread_cond );
/* free next play thread */
- if ( &player->next_play_thread_cond &&
- &player->next_play_thread_mutex &&
- player->next_play_thread )
+ if ( player->next_play_thread )
{
player->next_play_thread_exit = TRUE;
g_cond_signal( &player->next_play_thread_cond );
@@ -9043,11 +9027,9 @@ ERROR:
/* clear next play thread mutex/cond if still alive
* this can happen if only thread creating has failed
*/
- if ( &player->next_play_thread_mutex )
- g_mutex_clear(&player->next_play_thread_mutex );
+ g_mutex_clear(&player->next_play_thread_mutex );
- if ( &player->next_play_thread_cond )
- g_cond_clear ( &player->next_play_thread_cond );
+ g_cond_clear ( &player->next_play_thread_cond );
/* release attributes */
_mmplayer_deconstruct_attribute(handle);
@@ -9208,9 +9190,7 @@ _mmplayer_destroy(MMHandleType handle) // @
__mmplayer_destroy_streaming_ext(player);
/* release repeat thread */
- if ( &player->repeat_thread_cond &&
- &player->repeat_thread_mutex &&
- player->repeat_thread )
+ if ( player->repeat_thread )
{
player->repeat_thread_exit = TRUE;
g_cond_signal( &player->repeat_thread_cond );
@@ -9223,9 +9203,7 @@ _mmplayer_destroy(MMHandleType handle) // @
}
/* release next play thread */
- if (&player->next_play_thread_cond &&
- &player->next_play_thread_mutex &&
- player->next_play_thread )
+ if ( player->next_play_thread )
{
MMPLAYER_PLAYBACK_LOCK(player);
@@ -9307,11 +9285,9 @@ _mmplayer_destroy(MMHandleType handle) // @
__mmplayer_release_factories( player );
/* release lock */
- if ( &player->fsink_lock )
- g_mutex_clear(&player->fsink_lock );
+ g_mutex_clear(&player->fsink_lock );
- if ( &player->msg_cb_lock )
- g_mutex_clear(&player->msg_cb_lock );
+ g_mutex_clear(&player->msg_cb_lock );
MMPLAYER_FLEAVE();
@@ -12815,12 +12791,6 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
return;
}
- if ( !(&player->cmd_lock) )
- {
- debug_warning("can't get cmd lock\n");
- return;
- }
-
if (!g_mutex_trylock(&player->cmd_lock))
{
debug_warning("Fail to get cmd lock");
@@ -15850,6 +15820,7 @@ int _mmplayer_remove_audio_parser_decoder(mm_player_t* player,GstPad *inpad)
{
gst_object_unref(peer);
result = MM_ERROR_NONE;
+ g_free(Element_name);
break;
}
factory_name = GST_OBJECT_NAME(factory);
@@ -15857,6 +15828,7 @@ int _mmplayer_remove_audio_parser_decoder(mm_player_t* player,GstPad *inpad)
if(pad == NULL)
{
result = MM_ERROR_PLAYER_INTERNAL;
+ g_free(Element_name);
break;
}
gst_object_unref(peer);
@@ -15868,6 +15840,7 @@ int _mmplayer_remove_audio_parser_decoder(mm_player_t* player,GstPad *inpad)
gst_object_unref(peer);
gst_object_unref(pad);
result = MM_ERROR_PLAYER_INTERNAL;
+ g_free(Element_name);
break;
}
}
diff --git a/src/mm_player_priv_gst.c b/src/mm_player_priv_gst.c
deleted file mode 100755
index 46e8009..0000000
--- a/src/mm_player_priv_gst.c
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- * libmm-player
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/*===========================================================================================
-| |
-| INCLUDE FILES |
-| |
-========================================================================================== */
-#include "mm_player_priv.h"
-#include "mm_player_priv_internal.h"
-#include "mm_player_priv_locl_func.h"
-
-/*===========================================================================================
-| |
-| LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE |
-| |
-========================================================================================== */
-
-/*---------------------------------------------------------------------------
-| GLOBAL CONSTANT DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| IMPORTED VARIABLE DECLARATIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| IMPORTED FUNCTION DECLARATIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL #defines: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL CONSTANT DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL DATA TYPE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| GLOBAL VARIABLE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL VARIABLE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*===========================================================================================
-| |
-| FUNCTION DEFINITIONS |
-| |
-========================================================================================== */
-
-int __gst_realize(mm_player_t* player) // @
-{
- gint timeout = 0;
- int ret = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
-
- __ta__("__mmplayer_gst_create_pipeline",
- ret = __mmplayer_gst_create_pipeline(player);
- if ( ret )
- {
- debug_critical("failed to create pipeline\n");
- return ret;
- }
- )
-
- /* set pipeline state to READY */
- /* NOTE : state change to READY must be performed sync. */
- timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
- ret = __mmplayer_gst_set_state(player,
- player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout);
-
- if ( ret != MM_ERROR_NONE )
- {
- /* return error if failed to set state */
- debug_error("failed to set READY state");
- return ret;
- }
- else
- {
- MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
- }
-
- /* create dot before error-return. for debugging */
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-realize" );
-
- debug_fleave();
-
- return ret;
-}
-
-int __gst_unrealize(mm_player_t* player) // @
-{
- int ret = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NULL;
- MMPLAYER_PRINT_STATE(player);
-
- /* release miscellaneous information */
- __mmplayer_release_misc( player );
-
- /* destroy pipeline */
- ret = __mmplayer_gst_destroy_pipeline( player );
- if ( ret != MM_ERROR_NONE )
- {
- debug_error("failed to destory pipeline\n");
- return ret;
- }
-
- MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
-
- debug_fleave();
-
- return ret;
-}
-
-int __gst_pending_seek ( mm_player_t* player )
-{
- MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
- MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
- int ret = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- if ( !player->pending_seek.is_pending )
- {
- debug_log("pending seek is not reserved. nothing to do.\n" );
- return ret;
- }
-
- /* check player state if player could pending seek or not. */
- current_state = MMPLAYER_CURRENT_STATE(player);
- pending_state = MMPLAYER_PENDING_STATE(player);
-
- if ( current_state != MM_PLAYER_STATE_PAUSED && current_state != MM_PLAYER_STATE_PLAYING )
- {
- debug_warning("try to pending seek in %s state, try next time. \n",
- MMPLAYER_STATE_GET_NAME(current_state));
- return ret;
- }
-
- debug_log("trying to play from (%lu) pending position\n", player->pending_seek.pos);
-
- ret = __gst_set_position ( player, player->pending_seek.format, player->pending_seek.pos, FALSE );
-
- if ( MM_ERROR_NONE != ret )
- debug_error("failed to seek pending postion. just keep staying current position.\n");
-
- player->pending_seek.is_pending = FALSE;
-
- debug_fleave();
-
- return ret;
-}
-
-int __gst_start(mm_player_t* player) // @
-{
- gboolean sound_extraction = 0;
- int ret = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- /* get sound_extraction property */
- mm_attrs_get_int_by_name(player->attrs, "pcm_extraction", &sound_extraction);
-
- /* NOTE : if SetPosition was called before Start. do it now */
- /* streaming doesn't support it. so it should be always sync */
- /* !! create one more api to check if there is pending seek rather than checking variables */
- if ( (player->pending_seek.is_pending || sound_extraction) && !MMPLAYER_IS_STREAMING(player))
- {
- MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PAUSED;
- ret = __gst_pause(player, FALSE);
- if ( ret != MM_ERROR_NONE )
- {
- debug_error("failed to set state to PAUSED for pending seek\n");
- return ret;
- }
-
- MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
-
- if ( sound_extraction )
- {
- debug_log("setting pcm extraction\n");
-
- ret = __mmplayer_set_pcm_extraction(player);
- if ( MM_ERROR_NONE != ret )
- {
- debug_warning("failed to set pcm extraction\n");
- return ret;
- }
- }
- else
- {
- if ( MM_ERROR_NONE != __gst_pending_seek(player) )
- {
- debug_warning("failed to seek pending postion. starting from the begin of content.\n");
- }
- }
- }
-
- debug_log("current state before doing transition");
- MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
- MMPLAYER_PRINT_STATE(player);
-
- /* set pipeline state to PLAYING */
- ret = __mmplayer_gst_set_state(player,
- player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, FALSE, MMPLAYER_STATE_CHANGE_TIMEOUT(player) );
- if (ret == MM_ERROR_NONE)
- {
- MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
- }
- else
- {
- debug_error("failed to set state to PLAYING");
- return ret;
- }
-
- /* generating debug info before returning error */
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-start" );
-
- debug_fleave();
-
- return ret;
-}
-
-int __gst_stop(mm_player_t* player) // @
-{
- GstStateChangeReturn change_ret = GST_STATE_CHANGE_SUCCESS;
- MMHandleType attrs = 0;
- gboolean fadewown = FALSE;
- gboolean rewind = FALSE;
- gint timeout = 0;
- int ret = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- debug_log("current state before doing transition");
- MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
- MMPLAYER_PRINT_STATE(player);
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if ( !attrs )
- {
- debug_error("cannot get content attribute\n");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- mm_attrs_get_int_by_name(attrs,"sound_fadedown", &fadewown);
-
- /* enable fadedown */
- if (fadewown)
- __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
-
- /* Just set state to PAUESED and the rewind. it's usual player behavior. */
- timeout = MMPLAYER_STATE_CHANGE_TIMEOUT ( player );
- if ( player->profile.uri_type == MM_PLAYER_URI_TYPE_BUFF || player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS)
- {
- ret = __mmplayer_gst_set_state(player,
- player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout );
- }
- else
- {
- ret = __mmplayer_gst_set_state( player,
- player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, FALSE, timeout );
-
- if ( !MMPLAYER_IS_STREAMING(player))
- rewind = TRUE;
- }
-
- /* disable fadeout */
- if (fadewown)
- __mmplayer_undo_sound_fadedown(player);
-
-
- /* return if set_state has failed */
- if ( ret != MM_ERROR_NONE )
- {
- debug_error("failed to set state.\n");
- return ret;
- }
-
- /* rewind */
- if ( rewind )
- {
- if ( ! __gst_seek( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
- GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0,
- GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE) )
- {
- debug_warning("failed to rewind\n");
- ret = MM_ERROR_PLAYER_SEEK;
- }
- }
-
- /* initialize */
- player->sent_bos = FALSE;
-
- /* wait for seek to complete */
- change_ret = gst_element_get_state (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, NULL, NULL, timeout * GST_SECOND);
- if ( change_ret == GST_STATE_CHANGE_SUCCESS || change_ret == GST_STATE_CHANGE_NO_PREROLL )
- {
- MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
- }
- else
- {
- debug_error("fail to stop player.\n");
- ret = MM_ERROR_PLAYER_INTERNAL;
- __mmplayer_dump_pipeline_state(player);
- }
-
- /* generate dot file if enabled */
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-stop" );
-
- debug_fleave();
-
- return ret;
-}
-
-int __gst_pause(mm_player_t* player, gboolean async) // @
-{
- int ret = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
- return_val_if_fail(player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- debug_log("current state before doing transition");
- MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PAUSED;
- MMPLAYER_PRINT_STATE(player);
-
- /* set pipeline status to PAUSED */
- ret = __mmplayer_gst_set_state(player,
- player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, async, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
-
- if ( FALSE == async )
- {
- if ( ret != MM_ERROR_NONE )
- {
- GstMessage *msg = NULL;
- GTimer *timer = NULL;
- gdouble MAX_TIMEOUT_SEC = 3;
-
- debug_error("failed to set state to PAUSED");
-
- timer = g_timer_new();
- g_timer_start(timer);
-
- GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
- gboolean got_msg = FALSE;
- /* check if gst error posted or not */
- do
- {
- msg = gst_bus_timed_pop(bus, GST_SECOND /2);
- if (msg)
- {
- if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
- {
- GError *error = NULL;
-
- debug_error("parsing error posted from bus");
- /* parse error code */
- gst_message_parse_error(msg, &error, NULL);
-
- if (error->domain == GST_STREAM_ERROR)
- {
- ret = __gst_handle_stream_error( player, error, msg );
- }
- else if (error->domain == GST_RESOURCE_ERROR)
- {
- ret = __gst_handle_resource_error( player, error->code );
- }
- else if (error->domain == GST_LIBRARY_ERROR)
- {
- ret = __gst_handle_library_error( player, error->code );
- }
- else if (error->domain == GST_CORE_ERROR)
- {
- ret = __gst_handle_core_error( player, error->code );
- }
- got_msg = TRUE;
- player->msg_posted = TRUE;
- }
- gst_message_unref(msg);
- }
- } while (!got_msg && (g_timer_elapsed(timer, NULL) < MAX_TIMEOUT_SEC));
-
- /* clean */
- gst_object_unref(bus);
- g_timer_stop (timer);
- g_timer_destroy (timer);
-
- return ret;
- }
- else if ((!player->has_many_types) && (!player->pipeline->videobin) && (!player->pipeline->audiobin) )
- {
- if(MMPLAYER_IS_RTSP_STREAMING(player))
- return ret;
- player->msg_posted = TRUE; // no need to post error by message callback
- return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
- }
- else if ( ret == MM_ERROR_NONE)
- {
- MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
- }
- }
-
- /* generate dot file before returning error */
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-pause" );
-
- debug_fleave();
-
- return ret;
-}
-
-int __gst_resume(mm_player_t* player, gboolean async) // @
-{
- int ret = MM_ERROR_NONE;
- gint timeout = 0;
- GstBus *bus = NULL;
-
- debug_fenter();
-
- return_val_if_fail(player && player->pipeline,
- MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- debug_log("current state before doing transition");
- MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
- MMPLAYER_PRINT_STATE(player);
-
- /* generate dot file before returning error */
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
-
- __mmplayer_set_antishock( player , FALSE );
-
- if ( async )
- debug_log("do async state transition to PLAYING.\n");
-
- /* clean bus sync handler because it's not needed any more */
- bus = gst_pipeline_get_bus (GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
- gst_bus_set_sync_handler (bus, NULL, NULL, NULL);
- gst_object_unref(bus);
-
- /* set pipeline state to PLAYING */
- timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
-
- ret = __mmplayer_gst_set_state(player,
- player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, async, timeout );
- if (ret != MM_ERROR_NONE)
- {
- debug_error("failed to set state to PLAYING\n");
-
- return ret;
- }
- else
- {
- if (async == FALSE)
- {
- MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING );
- }
- }
-
- /* FIXIT : analyze so called "async problem" */
- /* set async off */
- __gst_set_async_state_change( player, FALSE );
-
- /* generate dot file before returning error */
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
-
- debug_fleave();
-
- return ret;
-}
-
-int
-__gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called) // @
-{
- GstFormat fmt = GST_FORMAT_TIME;
- unsigned long dur_msec = 0;
- gint64 dur_nsec = 0;
- gint64 pos_nsec = 0;
- gboolean ret = TRUE;
- gboolean accurated = FALSE;
- GstSeekFlags seek_flags = GST_SEEK_FLAG_FLUSH;
-
- debug_fenter();
- return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
- return_val_if_fail ( !MMPLAYER_IS_LIVE_STREAMING(player), MM_ERROR_PLAYER_NO_OP );
-
- if ( MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING
- && MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED )
- goto PENDING;
-
- /* check duration */
- /* NOTE : duration cannot be zero except live streaming.
- * Since some element could have some timing problemn with quering duration, try again.
- */
- if ( !player->duration )
- {
- if ( !gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, fmt, &dur_nsec ))
- {
- goto SEEK_ERROR;
- }
- player->duration = dur_nsec;
- }
-
- if ( player->duration )
- {
- dur_msec = GST_TIME_AS_MSECONDS(player->duration);
- }
- else
- {
- debug_error("could not get the duration. fail to seek.\n");
- goto SEEK_ERROR;
- }
-
- debug_log("playback rate: %f\n", player->playback_rate);
-
- mm_attrs_get_int_by_name(player->attrs,"accurate_seek", &accurated);
- if (accurated)
- {
- seek_flags |= GST_SEEK_FLAG_ACCURATE;
- }
- else
- {
- seek_flags |= GST_SEEK_FLAG_KEY_UNIT;
- }
-
- /* do seek */
- switch ( format )
- {
- case MM_PLAYER_POS_FORMAT_TIME:
- {
- /* check position is valid or not */
- if ( position > dur_msec )
- goto INVALID_ARGS;
-
- debug_log("seeking to (%lu) msec, duration is %d msec\n", position, dur_msec);
-
- if (player->doing_seek)
- {
- debug_log("not completed seek");
- return MM_ERROR_PLAYER_DOING_SEEK;
- }
-
- if ( !internal_called)
- player->doing_seek = TRUE;
-
- pos_nsec = position * G_GINT64_CONSTANT(1000000);
- ret = __gst_seek ( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
- GST_FORMAT_TIME, seek_flags,
- GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
- if ( !ret )
- {
- debug_error("failed to set position. dur[%lu] pos[%lu] pos_msec[%llu]\n", dur_msec, position, pos_nsec);
- goto SEEK_ERROR;
- }
- }
- break;
-
- case MM_PLAYER_POS_FORMAT_PERCENT:
- {
- debug_log("seeking to (%lu)%% \n", position);
-
- if (player->doing_seek)
- {
- debug_log("not completed seek");
- return MM_ERROR_PLAYER_DOING_SEEK;
- }
-
- if ( !internal_called)
- player->doing_seek = TRUE;
-
- /* FIXIT : why don't we use 'GST_FORMAT_PERCENT' */
- pos_nsec = (gint64) ( ( position * player->duration ) / 100 );
- ret = __gst_seek ( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
- GST_FORMAT_TIME, seek_flags,
- GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
- if ( !ret )
- {
- debug_error("failed to set position. dur[%lud] pos[%lud] pos_msec[%llud]\n", dur_msec, position, pos_nsec);
- goto SEEK_ERROR;
- }
- }
- break;
-
- default:
- goto INVALID_ARGS;
-
- }
-
- /* NOTE : store last seeking point to overcome some bad operation
- * ( returning zero when getting current position ) of some elements
- */
- player->last_position = pos_nsec;
-
- /* MSL should guarante playback rate when seek is selected during trick play of fast forward. */
- if ( player->playback_rate > 1.0 )
- _mmplayer_set_playspeed ( (MMHandleType)player, player->playback_rate );
-
- debug_fleave();
- return MM_ERROR_NONE;
-
-PENDING:
- player->pending_seek.is_pending = TRUE;
- player->pending_seek.format = format;
- player->pending_seek.pos = position;
-
- debug_warning("player current-state : %s, pending-state : %s, just preserve pending position(%lu).\n",
- MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), MMPLAYER_STATE_GET_NAME(MMPLAYER_PENDING_STATE(player)), player->pending_seek.pos);
-
- return MM_ERROR_NONE;
-
-INVALID_ARGS:
- debug_error("invalid arguments, position : %ld dur : %ld format : %d \n", position, dur_msec, format);
- return MM_ERROR_INVALID_ARGUMENT;
-
-SEEK_ERROR:
- player->doing_seek = FALSE;
- return MM_ERROR_PLAYER_SEEK;
-}
-
-#define TRICKPLAY_OFFSET GST_MSECOND
-
-int
-__gst_get_position(mm_player_t* player, int format, unsigned long* position) // @
-{
- MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
- GstFormat fmt = GST_FORMAT_TIME;
- signed long long pos_msec = 0;
- gboolean ret = TRUE;
-
- return_val_if_fail( player && position && player->pipeline && player->pipeline->mainbin,
- MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- current_state = MMPLAYER_CURRENT_STATE(player);
-
- /* NOTE : query position except paused state to overcome some bad operation
- * please refer to below comments in details
- */
- if ( current_state != MM_PLAYER_STATE_PAUSED )
- {
- ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, fmt, &pos_msec);
- }
-
- /* NOTE : get last point to overcome some bad operation of some elements
- * ( returning zero when getting current position in paused state
- * and when failed to get postion during seeking
- */
- if ( ( current_state == MM_PLAYER_STATE_PAUSED )
- || ( ! ret ))
- //|| ( player->last_position != 0 && pos_msec == 0 ) )
- {
- debug_warning ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
-
- if(player->playback_rate < 0.0)
- pos_msec = player->last_position - TRICKPLAY_OFFSET;
- else
- pos_msec = player->last_position;
-
- if (!ret)
- pos_msec = player->last_position;
- else
- player->last_position = pos_msec;
-
- debug_warning("returning last point : %"GST_TIME_FORMAT, GST_TIME_ARGS(pos_msec));
-
- }
- else
- {
- player->last_position = pos_msec;
- }
-
- switch (format) {
- case MM_PLAYER_POS_FORMAT_TIME:
- *position = GST_TIME_AS_MSECONDS(pos_msec);
- break;
-
- case MM_PLAYER_POS_FORMAT_PERCENT:
- {
- int dur = 0;
- int pos = 0;
-
- dur = player->duration / GST_SECOND;
- if (dur <= 0)
- {
- debug_log ("duration is [%d], so returning position 0\n",dur);
- *position = 0;
- }
- else
- {
- pos = pos_msec / GST_SECOND;
- *position = pos * 100 / dur;
- }
- break;
- }
- default:
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- debug_log("current position : %lu\n", *position);
-
-
- return MM_ERROR_NONE;
-}
-
-int __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos)
-{
- GstElement *element = NULL;
- GstQuery *query = NULL;
-
- return_val_if_fail( player &&
- player->pipeline &&
- player->pipeline->mainbin,
- MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- return_val_if_fail( start_pos && stop_pos, MM_ERROR_INVALID_ARGUMENT );
-
- if ( MMPLAYER_IS_HTTP_STREAMING ( player ))
- {
- /* Note : In case of http streaming or HLS, the buffering queue [ queue2 ] could handle buffering query. */
- element = GST_ELEMENT ( player->pipeline->mainbin[MMPLAYER_M_S_BUFFER].gst );
- }
- else if ( MMPLAYER_IS_RTSP_STREAMING ( player ) )
- {
- debug_warning ( "it's not supported yet.\n" );
- return MM_ERROR_NONE;
- }
- else
- {
- debug_warning ( "it's only used for streaming case.\n" );
- return MM_ERROR_NONE;
- }
-
- *start_pos = 0;
- *stop_pos = 0;
-
- switch ( format )
- {
- case MM_PLAYER_POS_FORMAT_PERCENT :
- {
- query = gst_query_new_buffering ( GST_FORMAT_PERCENT );
- if ( gst_element_query ( element, query ) )
- {
- gint64 start, stop;
- GstFormat format;
- gboolean busy;
- gint percent;
-
- gst_query_parse_buffering_percent ( query, &busy, &percent);
- gst_query_parse_buffering_range ( query, &format, &start, &stop, NULL );
-
- debug_log ( "buffering start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT "\n", start, stop);
-
- if ( start != -1)
- *start_pos = 100 * start / GST_FORMAT_PERCENT_MAX;
- else
- *start_pos = 0;
-
- if ( stop != -1)
- *stop_pos = 100 * stop / GST_FORMAT_PERCENT_MAX;
- else
- *stop_pos = 0;
- }
- gst_query_unref (query);
- }
- break;
-
- case MM_PLAYER_POS_FORMAT_TIME :
- debug_warning ( "Time format is not supported yet.\n" );
- break;
-
- default :
- break;
- }
-
-debug_log("current buffer position : %lu~%lu \n", *start_pos, *stop_pos );
-
- return MM_ERROR_NONE;
-}
-
-int
-__gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param) // @
-{
- debug_fenter();
-
- if ( !player )
- {
- debug_warning("set_message_callback is called with invalid player handle\n");
- return MM_ERROR_PLAYER_NOT_INITIALIZED;
- }
-
- player->msg_cb = callback;
- player->msg_cb_param = user_param;
-
- debug_log("msg_cb : 0x%x msg_cb_param : 0x%x\n", (guint)callback, (guint)user_param);
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-}
-
-/* sending event to one of sinkelements */
-gboolean
-__gst_send_event_to_sink( mm_player_t* player, GstEvent* event )
-{
- GstEvent * event2 = NULL;
- GList *sinks = NULL;
- gboolean res = FALSE;
-
- debug_fenter();
-
- return_val_if_fail( player, FALSE );
- return_val_if_fail ( event, FALSE );
-
- if ( player->play_subtitle && !player->use_textoverlay)
- event2 = gst_event_copy((const GstEvent *)event);
-
- sinks = player->sink_elements;
- while (sinks)
- {
- GstElement *sink = GST_ELEMENT_CAST (sinks->data);
-
- if (GST_IS_ELEMENT(sink))
- {
- /* in the case of some video/audio file,
- * it's possible video sink don't consider same position seek
- * with current postion
- */
- if ( !MMPLAYER_IS_STREAMING(player) && player->pipeline->videobin
- && player->pipeline->audiobin && (!g_strrstr(GST_ELEMENT_NAME(sink), "audiosink")) )
- {
- sinks = g_list_next (sinks);
- continue;
- }
-
- /* keep ref to the event */
- gst_event_ref (event);
-
- if ( (res = gst_element_send_event (sink, event)) )
- {
- debug_log("sending event[%s] to sink element [%s] success!\n",
- GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink) );
- break;
- }
-
- debug_log("sending event[%s] to sink element [%s] failed. try with next one.\n",
- GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink) );
- }
-
- sinks = g_list_next (sinks);
- }
-
- /* Note : Textbin is not linked to the video or audio bin.
- * It needs to send the event to the text sink seperatelly.
- */
- if ( player->play_subtitle && !player->use_textoverlay)
- {
- GstElement *text_sink = GST_ELEMENT_CAST (player->pipeline->textbin[MMPLAYER_T_SINK].gst);
-
- if (GST_IS_ELEMENT(text_sink))
- {
- /* keep ref to the event */
- gst_event_ref (event2);
-
- if ( (res != gst_element_send_event (text_sink, event2)) )
- {
- debug_error("sending event[%s] to subtitle sink element [%s] failed!\n",
- GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink) );
- }
- else
- {
- debug_log("sending event[%s] to subtitle sink element [%s] success!\n",
- GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink) );
- }
-
- gst_event_unref (event2);
- }
- }
-
- gst_event_unref (event);
-
- debug_fleave();
-
- return res;
-}
-
-gboolean
-__gst_seek(mm_player_t* player, GstElement * element, gdouble rate,
- GstFormat format, GstSeekFlags flags, GstSeekType cur_type,
- gint64 cur, GstSeekType stop_type, gint64 stop )
-{
- GstEvent* event = NULL;
- gboolean result = FALSE;
-
- debug_fenter();
-
- return_val_if_fail( player, FALSE );
-
- event = gst_event_new_seek (rate, format, flags, cur_type,
- cur, stop_type, stop);
-
- result = __gst_send_event_to_sink( player, event );
-
- debug_fleave();
-
- return result;
-}
-
-int __gst_adjust_subtitle_position(mm_player_t* player, int format, unsigned long position)
-{
- GstEvent* event = NULL;
- unsigned long current_pos = 0;
- unsigned long adusted_pos = 0;
-
- debug_fenter();
-
- /* check player and subtitlebin are created */
- return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
- return_val_if_fail ( player->play_subtitle, MM_ERROR_NOT_SUPPORT_API );
-
- if (position == 0)
- {
- debug_log ("nothing to do\n");
- return MM_ERROR_NONE;
- }
-
- switch (format)
- {
- case MM_PLAYER_POS_FORMAT_TIME:
- {
- /* check current postion */
- if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &current_pos ))
- {
- debug_error("failed to get position");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- adusted_pos = current_pos + (position * G_GINT64_CONSTANT(1000000));
- if (adusted_pos < 0)
- adusted_pos = G_GUINT64_CONSTANT(0);
- debug_log("adjust subtitle postion : %lu -> %lu [msec]\n", GST_TIME_AS_MSECONDS(current_pos), GST_TIME_AS_MSECONDS(adusted_pos));
-
- event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
- ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
- GST_SEEK_TYPE_SET, adusted_pos,
- GST_SEEK_TYPE_SET, -1);
- }
- break;
-
- default:
- {
- debug_warning("invalid format.\n");
- return MM_ERROR_INVALID_ARGUMENT;
- }
- }
-
- /* keep ref to the event */
- gst_event_ref (event);
-
- debug_log("sending event[%s] to subparse element [%s]\n",
- GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst) );
-
- if (gst_element_send_event (player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst, event))
- {
- debug_log("sending event[%s] to subparse element [%s] success!\n",
- GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst) );
- }
-
- /* unref to the event */
- gst_event_unref (event);
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-}
-
-void
-__gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data) // @
-{
- GstElement *appsrc = element;
- tBuffer *buf = (tBuffer *)user_data;
- GstBuffer *buffer = NULL;
- GstFlowReturn ret = GST_FLOW_OK;
- gint len = size;
-
- return_if_fail ( element );
- return_if_fail ( buf );
-
- buffer = gst_buffer_new ();
-
- if (buf->offset >= buf->len)
- {
- debug_log("call eos appsrc\n");
- g_signal_emit_by_name (appsrc, "end-of-stream", &ret);
- return;
- }
-
- if ( buf->len - buf->offset < size)
- {
- len = buf->len - buf->offset + buf->offset;
- }
-
- gst_buffer_insert_memory(buffer, -1, gst_memory_new_wrapped(0, (guint8*)(buf->buf + buf->offset), len, 0, len, (guint8*)(buf->buf + buf->offset), g_free));
-
- GST_BUFFER_OFFSET(buffer) = buf->offset;
- GST_BUFFER_OFFSET_END(buffer) = buf->offset + len;
-
- debug_log("feed buffer %p, offset %u-%u length %u\n", buffer, buf->offset, buf->len,len);
- g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
-
- buf->offset += len;
-}
-
-gboolean
-__gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data) // @
-{
- tBuffer *buf = (tBuffer *)user_data;
-
- return_val_if_fail ( buf, FALSE );
-
- buf->offset = (int)size;
-
- return TRUE;
-}
-
-void
-__gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data) // @
-{
- mm_player_t *player = (mm_player_t*)user_data;
-
- return_if_fail ( player );
-
- debug_msg("app-src: feed data\n");
-
- if(player->need_data_cb)
- player->need_data_cb(size, player->buffer_cb_user_param);
-}
-
-gboolean
-__gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data) // @
-{
- mm_player_t *player = (mm_player_t*)user_data;
-
- return_val_if_fail ( player, FALSE );
-
- debug_msg("app-src: seek data\n");
-
- if(player->seek_data_cb)
- player->seek_data_cb(offset, player->buffer_cb_user_param);
-
- return TRUE;
-}
-
-
-gboolean
-__gst_appsrc_enough_data(GstElement *element, gpointer user_data) // @
-{
- mm_player_t *player = (mm_player_t*)user_data;
-
- return_val_if_fail ( player, FALSE );
-
- debug_msg("app-src: enough data:%p\n", player->enough_data_cb);
-
- if(player->enough_data_cb)
- player->enough_data_cb(player->buffer_cb_user_param);
-
- return TRUE;
-}
diff --git a/src/mm_player_priv_gst_wrapper.c b/src/mm_player_priv_gst_wrapper.c
deleted file mode 100755
index 0e94aea..0000000
--- a/src/mm_player_priv_gst_wrapper.c
+++ /dev/null
@@ -1,2940 +0,0 @@
-/*
- * libmm-player
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/*===========================================================================================
-| |
-| INCLUDE FILES |
-| |
-========================================================================================== */
-#if 0
-#include <glib.h>
-#include <gst/gst.h>
-#ifndef GST_API_VERSION_1
-#include <gst/interfaces/xoverlay.h>
-#else
-#include <gst/video/videooverlay.h>
-#endif
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-
-#include <mm_error.h>
-//#include <mm_attrs.h>
-//#include <mm_attrs_private.h>
-#include <mm_debug.h>
-
-#include "mm_player_ini.h"
-#include "mm_player_attrs.h"
-#include "mm_player_capture.h"
-#endif
-#include <gst/app/gstappsrc.h>
-
-#include "mm_player_priv.h"
-#include "mm_player_priv_internal.h"
-#include "mm_player_priv_locl_func.h"
-
-/*===========================================================================================
-| |
-| LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE |
-| |
-========================================================================================== */
-
-/*---------------------------------------------------------------------------
-| GLOBAL CONSTANT DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| IMPORTED VARIABLE DECLARATIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| IMPORTED FUNCTION DECLARATIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL #defines: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL CONSTANT DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL DATA TYPE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| GLOBAL VARIABLE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL VARIABLE DEFINITIONS: |
----------------------------------------------------------------------------*/
-/* video capture callback*/
-gulong ahs_appsrc_cb_probe_id = 0;
-
-/*---------------------------------------------------------------------------
-| LOCAL FUNCTION PROTOTYPES: |
----------------------------------------------------------------------------*/
-
-/*===========================================================================================
-| |
-| FUNCTION DEFINITIONS |
-| |
-========================================================================================== */
-
-gboolean
-__mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data) // @
-{
- mm_player_t* player = (mm_player_t*) data;
- gboolean ret = TRUE;
- static gboolean async_done = FALSE;
-
- return_val_if_fail ( player, FALSE );
- return_val_if_fail ( msg && GST_IS_MESSAGE(msg), FALSE );
-
- switch ( GST_MESSAGE_TYPE( msg ) )
- {
- case GST_MESSAGE_UNKNOWN:
- debug_warning("unknown message received\n");
- break;
-
- case GST_MESSAGE_EOS:
- {
- MMHandleType attrs = 0;
- gint count = 0;
-
- debug_log("GST_MESSAGE_EOS received\n");
-
- /* NOTE : EOS event is comming multiple time. watch out it */
- /* check state. we only process EOS when pipeline state goes to PLAYING */
- if ( ! (player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME) )
- {
- debug_warning("EOS received on non-playing state. ignoring it\n");
- break;
- }
-
- if ( (player->audio_stream_cb) && (player->is_sound_extraction) )
- {
- GstPad *pad = NULL;
-
- pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
-
- debug_error("release audio callback\n");
-
- /* release audio callback */
- gst_pad_remove_probe (pad, player->audio_cb_probe_id);
- player->audio_cb_probe_id = 0;
- /* audio callback should be free because it can be called even though probe remove.*/
- player->audio_stream_cb = NULL;
- player->audio_stream_cb_user_param = NULL;
-
- }
-
- /* rewind if repeat count is greater then zero */
- /* get play count */
- attrs = MMPLAYER_GET_ATTRS(player);
-
- if ( attrs )
- {
- gboolean smooth_repeat = FALSE;
-
- mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
- mm_attrs_get_int_by_name(attrs, "profile_smooth_repeat", &smooth_repeat);
-
- debug_log("remaining play count: %d, playback rate: %f\n", count, player->playback_rate);
-
- if ( count > 1 || count == -1 || player->playback_rate < 0.0 ) /* default value is 1 */
- {
- if ( smooth_repeat )
- {
- debug_log("smooth repeat enabled. seeking operation will be excuted in new thread\n");
-
- g_cond_signal( player->repeat_thread_cond );
-
- break;
- }
- else
- {
- gint ret_value = 0;
-
- if ( player->section_repeat )
- {
- ret_value = _mmplayer_activate_section_repeat((MMHandleType)player, player->section_repeat_start, player->section_repeat_end);
- }
- else
- {
-
- if ( player->playback_rate < 0.0 )
- {
- player->resumed_by_rewind = TRUE;
- _mmplayer_set_mute((MMHandleType)player, 0);
- MMPLAYER_POST_MSG( player, MM_MESSAGE_RESUMED_BY_REW, NULL );
- }
-
- ret_value = __gst_set_position( player, MM_PLAYER_POS_FORMAT_TIME, 0, TRUE);
-
- /* initialize */
- player->sent_bos = FALSE;
- }
-
- if ( MM_ERROR_NONE != ret_value )
- {
- debug_error("failed to set position to zero for rewind\n");
- }
- else
- {
- if ( count > 1 )
- {
- /* we successeded to rewind. update play count and then wait for next EOS */
- count--;
-
- mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
-
- if ( mmf_attrs_commit ( attrs ) )
- debug_error("failed to commit attrs\n");
- }
- }
-
- break;
- }
- }
- }
-
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-eos" );
-
- /* post eos message to application */
- __mmplayer_post_delayed_eos( player, PLAYER_INI()->eos_delay );
-
- /* reset last position */
- player->last_position = 0;
- }
- break;
-
- case GST_MESSAGE_ERROR:
- {
- GError *error = NULL;
- gchar* debug = NULL;
- gchar *msg_src_element = NULL;
-
- /* generating debug info before returning error */
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-error" );
-
- /* get error code */
- gst_message_parse_error( msg, &error, &debug );
-
- msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( msg->src ) );
- if ( gst_structure_has_name ( gst_message_get_structure(msg), "streaming_error" ) )
- {
- /* Note : the streaming error from the streaming source is handled
- * using __mmplayer_handle_streaming_error.
- */
- __mmplayer_handle_streaming_error ( player, msg );
-
- /* dump state of all element */
- __mmplayer_dump_pipeline_state( player );
- }
- else
- {
- /* traslate gst error code to msl error code. then post it
- * to application if needed
- */
- __mmplayer_handle_gst_error( player, msg, error );
-
- /* dump state of all element */
- __mmplayer_dump_pipeline_state( player );
-
- }
-
- if (MMPLAYER_IS_HTTP_PD(player))
- {
- _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
- }
-
- MMPLAYER_FREEIF( debug );
- g_error_free( error );
- }
- break;
-
- case GST_MESSAGE_WARNING:
- {
- char* debug = NULL;
- GError* error = NULL;
-
- gst_message_parse_warning(msg, &error, &debug);
-
- debug_warning("warning : %s\n", error->message);
- debug_warning("debug : %s\n", debug);
-
- MMPLAYER_POST_MSG( player, MM_MESSAGE_WARNING, NULL );
-
- MMPLAYER_FREEIF( debug );
- g_error_free( error );
- }
- break;
-
- case GST_MESSAGE_INFO: debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
-
- case GST_MESSAGE_TAG:
- {
- debug_log("GST_MESSAGE_TAG\n");
- if ( ! __mmplayer_gst_extract_tag_from_msg( player, msg ) )
- {
- debug_warning("failed to extract tags from gstmessage\n");
- }
- }
- break;
-
- case GST_MESSAGE_BUFFERING:
- {
- MMMessageParamType msg_param = {0, };
- gboolean update_buffering_percent = TRUE;
-
- if ( !MMPLAYER_IS_STREAMING(player) || (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS) ) // pure hlsdemux case, don't consider buffering of msl currently
- break;
-
- __mm_player_streaming_buffering (player->streamer, msg);
-
- __mmplayer_handle_buffering_message ( player );
-
- update_buffering_percent = (player->pipeline_is_constructed || MMPLAYER_IS_RTSP_STREAMING(player) );
- if (update_buffering_percent)
- {
- msg_param.connection.buffering = player->streamer->buffering_percent;
- MMPLAYER_POST_MSG ( player, MM_MESSAGE_BUFFERING, &msg_param );
- }
- }
- break;
-
- case GST_MESSAGE_STATE_CHANGED:
- {
- MMPlayerGstElement *mainbin;
- const GValue *voldstate, *vnewstate, *vpending;
- GstState oldstate, newstate, pending;
-
- if ( ! ( player->pipeline && player->pipeline->mainbin ) )
- {
- debug_error("player pipeline handle is null");
- break;
- }
-
- mainbin = player->pipeline->mainbin;
-
- /* we only handle messages from pipeline */
- if( msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst )
- break;
-
- /* get state info from msg */
- voldstate = gst_structure_get_value (gst_message_get_structure(msg), "old-state");
- vnewstate = gst_structure_get_value (gst_message_get_structure(msg), "new-state");
- vpending = gst_structure_get_value (gst_message_get_structure(msg), "pending-state");
-
- oldstate = (GstState)voldstate->data[0].v_int;
- newstate = (GstState)vnewstate->data[0].v_int;
- pending = (GstState)vpending->data[0].v_int;
-
- debug_log("state changed [%s] : %s ---> %s final : %s\n",
- GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)),
- gst_element_state_get_name( (GstState)oldstate ),
- gst_element_state_get_name( (GstState)newstate ),
- gst_element_state_get_name( (GstState)pending ) );
-
- if (oldstate == newstate)
- {
- debug_warning("pipeline reports state transition to old state");
- break;
- }
-
- switch(newstate)
- {
- case GST_STATE_VOID_PENDING:
- break;
-
- case GST_STATE_NULL:
- break;
-
- case GST_STATE_READY:
- break;
-
- case GST_STATE_PAUSED:
- {
- gboolean prepare_async = FALSE;
-
- if ( ! player->audio_cb_probe_id && player->is_sound_extraction )
- __mmplayer_configure_audio_callback(player);
-
- if ( ! player->sent_bos && oldstate == GST_STATE_READY) // managed prepare async case
- {
- mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &prepare_async);
- debug_log("checking prepare mode for async transition - %d", prepare_async);
- }
-
- if ( MMPLAYER_IS_STREAMING(player) || prepare_async )
- {
- MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
-
- if (player->streamer)
- {
- __mm_player_streaming_set_content_bitrate(player->streamer,
- player->total_maximum_bitrate, player->total_bitrate);
- }
- }
- }
- break;
-
- case GST_STATE_PLAYING:
- {
- if (player->doing_seek && async_done)
- {
- player->doing_seek = FALSE;
- async_done = FALSE;
- MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, NULL );
- }
-
- if ( MMPLAYER_IS_STREAMING(player) ) // managed prepare async case when buffering is completed
- {
- // pending state should be reset oyherwise, it's still playing even though it's resumed after bufferging.
- MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING);
- }
- }
- break;
-
- default:
- break;
- }
- }
- break;
-
- case GST_MESSAGE_STATE_DIRTY: debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
- case GST_MESSAGE_STEP_DONE: debug_log("GST_MESSAGE_STEP_DONE\n"); break;
- case GST_MESSAGE_CLOCK_PROVIDE: debug_log("GST_MESSAGE_CLOCK_PROVIDE\n"); break;
-
- case GST_MESSAGE_CLOCK_LOST:
- {
- GstClock *clock = NULL;
- gst_message_parse_clock_lost (msg, &clock);
- debug_log("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
- g_print ("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
-
- if (PLAYER_INI()->provide_clock)
- {
- debug_log ("Provide clock is TRUE, do pause->resume\n");
- __gst_pause(player, FALSE);
- __gst_resume(player, FALSE);
- }
- }
- break;
-
- case GST_MESSAGE_NEW_CLOCK:
- {
- GstClock *clock = NULL;
- gst_message_parse_new_clock (msg, &clock);
- debug_log("GST_MESSAGE_NEW_CLOCK : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
- }
- break;
-
- case GST_MESSAGE_STRUCTURE_CHANGE: debug_log("GST_MESSAGE_STRUCTURE_CHANGE\n"); break;
- case GST_MESSAGE_STREAM_STATUS: debug_log("GST_MESSAGE_STREAM_STATUS\n"); break;
- case GST_MESSAGE_APPLICATION: debug_log("GST_MESSAGE_APPLICATION\n"); break;
-
- case GST_MESSAGE_ELEMENT:
- {
- debug_log("GST_MESSAGE_ELEMENT\n");
- }
- break;
-
- case GST_MESSAGE_SEGMENT_START: debug_log("GST_MESSAGE_SEGMENT_START\n"); break;
- case GST_MESSAGE_SEGMENT_DONE: debug_log("GST_MESSAGE_SEGMENT_DONE\n"); break;
-
- case GST_MESSAGE_DURATION:
- {
- debug_log("GST_MESSAGE_DURATION\n");
- ret = __mmplayer_gst_handle_duration(player, msg);
- if (!ret)
- {
- debug_warning("failed to update duration");
- }
- }
-
- break;
-
-
- case GST_MESSAGE_LATENCY: debug_log("GST_MESSAGE_LATENCY\n"); break;
- case GST_MESSAGE_ASYNC_START: debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg))); break;
-
- case GST_MESSAGE_ASYNC_DONE:
- {
- debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg)));
-
- /* we only handle message from pipeline */
- if (msg->src != (GstObject *)player->pipeline->mainbin[MMPLAYER_M_PIPE].gst)
- break;
-
- if (player->doing_seek)
- {
- if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED)
- {
- player->doing_seek = FALSE;
- MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, NULL );
- }
- else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING)
- {
- async_done = TRUE;
- }
- }
- }
- break;
-
- case GST_MESSAGE_REQUEST_STATE: debug_log("GST_MESSAGE_REQUEST_STATE\n"); break;
- case GST_MESSAGE_STEP_START: debug_log("GST_MESSAGE_STEP_START\n"); break;
- case GST_MESSAGE_QOS: debug_log("GST_MESSAGE_QOS\n"); break;
- case GST_MESSAGE_PROGRESS: debug_log("GST_MESSAGE_PROGRESS\n"); break;
- case GST_MESSAGE_ANY: debug_log("GST_MESSAGE_ANY\n"); break;
-
- default:
- debug_warning("unhandled message\n");
- break;
- }
-
- /* FIXIT : this cause so many warnings/errors from glib/gstreamer. we should not call it since
- * gst_element_post_message api takes ownership of the message.
- */
- //gst_message_unref( msg );
-
- return ret;
-}
-
-gboolean
-__mmplayer_gst_handle_duration(mm_player_t* player, GstMessage* msg)
-{
- GstFormat format;
- gint64 bytes = 0;
-
- debug_fenter();
-
- return_val_if_fail(player, FALSE);
- return_val_if_fail(msg, FALSE);
-
- gst_message_parse_duration (msg, &format, &bytes);
-
- if (MMPLAYER_IS_HTTP_STREAMING(player) && format == GST_FORMAT_BYTES )
- {
- debug_log("data total size of http content: %lld", bytes);
- player->http_content_size = bytes;
- }
- else if (format == GST_FORMAT_TIME)
- {
- /* handling audio clip which has vbr. means duration is keep changing */
- _mmplayer_update_content_attrs (player, ATTR_DURATION );
- }
- else
- {
- debug_warning("duration is neither BYTES or TIME");
- return FALSE;
- }
-
- debug_fleave();
-
- return TRUE;
-}
-
-gboolean
-__mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage* msg) // @
-{
-
-/* macro for better code readability */
-#define MMPLAYER_UPDATE_TAG_STRING(gsttag, attribute, playertag) \
-if (gst_tag_list_get_string(tag_list, gsttag, &string)) \
-{\
- if (string != NULL)\
- {\
- debug_log ( "update tag string : %s\n", string); \
- mm_attrs_set_string_by_name(attribute, playertag, string); \
- g_free(string);\
- string = NULL;\
- }\
-}
-
-#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, attribute, playertag) \
-value = gst_tag_list_get_value_index(tag_list, gsttag, index); \
-if (value) \
-{\
- GstMapInfo info; \
- gst_buffer_map (buffer, &info, GST_MAP_WRITE); \
- buffer = gst_value_get_buffer (value); \
- debug_log ( "update album cover data : %p, size : %d\n", info.data, info.size); \
- player->album_art = (gchar *)g_malloc(info.size); \
- if (player->album_art); \
- { \
- memcpy(player->album_art, info.data, info.size); \
- mm_attrs_set_data_by_name(attribute, playertag, (void *)player->album_art, info.size); \
- } \
-gst_buffer_unmap (buffer, &info); \
-}
-
-#define MMPLAYER_UPDATE_TAG_UINT(gsttag, attribute, playertag) \
-if (gst_tag_list_get_uint(tag_list, gsttag, &v_uint))\
-{\
- if(v_uint)\
- {\
- if(strcmp(gsttag, GST_TAG_BITRATE) == 0)\
- {\
- if (player->updated_bitrate_count == 0) \
- mm_attrs_set_int_by_name(attribute, "content_audio_bitrate", v_uint); \
- if (player->updated_bitrate_count<MM_PLAYER_STREAM_COUNT_MAX) \
- {\
- player->bitrate[player->updated_bitrate_count] = v_uint;\
- player->total_bitrate += player->bitrate[player->updated_maximum_bitrate_count]; \
- player->updated_bitrate_count++; \
- mm_attrs_set_int_by_name(attribute, playertag, player->total_bitrate);\
- debug_log ( "update bitrate %d[bps] of stream #%d.\n", v_uint, player->updated_bitrate_count);\
- }\
- }\
- else if (strcmp(gsttag, GST_TAG_MAXIMUM_BITRATE))\
- {\
- if (player->updated_maximum_bitrate_count<MM_PLAYER_STREAM_COUNT_MAX) \
- {\
- player->maximum_bitrate[player->updated_maximum_bitrate_count] = v_uint;\
- player->total_maximum_bitrate += player->maximum_bitrate[player->updated_maximum_bitrate_count]; \
- player->updated_maximum_bitrate_count++; \
- mm_attrs_set_int_by_name(attribute, playertag, player->total_maximum_bitrate); \
- debug_log ( "update maximum bitrate %d[bps] of stream #%d\n", v_uint, player->updated_maximum_bitrate_count);\
- }\
- }\
- else\
- {\
- mm_attrs_set_int_by_name(attribute, playertag, v_uint); \
- }\
- v_uint = 0;\
- }\
-}
-
-#define MMPLAYER_UPDATE_TAG_DATE(gsttag, attribute, playertag) \
-if (gst_tag_list_get_date(tag_list, gsttag, &date))\
-{\
- if (date != NULL)\
- {\
- string = g_strdup_printf("%d", g_date_get_year(date));\
- mm_attrs_set_string_by_name(attribute, playertag, string);\
- debug_log ( "metainfo year : %s\n", string);\
- MMPLAYER_FREEIF(string);\
- g_date_free(date);\
- }\
-}
-
-#define MMPLAYER_UPDATE_TAG_UINT64(gsttag, attribute, playertag) \
-if(gst_tag_list_get_uint64(tag_list, gsttag, &v_uint64))\
-{\
- if(v_uint64)\
- {\
- /* FIXIT : don't know how to store date */\
- g_assert(1);\
- v_uint64 = 0;\
- }\
-}
-
-#define MMPLAYER_UPDATE_TAG_DOUBLE(gsttag, attribute, playertag) \
-if(gst_tag_list_get_double(tag_list, gsttag, &v_double))\
-{\
- if(v_double)\
- {\
- /* FIXIT : don't know how to store date */\
- g_assert(1);\
- v_double = 0;\
- }\
-}
-
- /* function start */
- GstTagList* tag_list = NULL;
-
- MMHandleType attrs = 0;
-
- char *string = NULL;
- guint v_uint = 0;
- GDate *date = NULL;
- /* album cover */
- GstBuffer *buffer = NULL;
- gint index = 0;
- const GValue *value;
-
- /* currently not used. but those are needed for above macro */
- //guint64 v_uint64 = 0;
- //gdouble v_double = 0;
-
- return_val_if_fail( player && msg, FALSE );
-
- attrs = MMPLAYER_GET_ATTRS(player);
-
- return_val_if_fail( attrs, FALSE );
-
- /* get tag list from gst message */
- gst_message_parse_tag(msg, &tag_list);
-
- /* store tags to player attributes */
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE, attrs, "tag_title");
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE_SORTNAME, ?, ?); */
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST, attrs, "tag_artist");
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST_SORTNAME, ?, ?); */
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM, attrs, "tag_album");
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM_SORTNAME, ?, ?); */
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMPOSER, attrs, "tag_author");
- MMPLAYER_UPDATE_TAG_DATE(GST_TAG_DATE, attrs, "tag_date");
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_GENRE, attrs, "tag_genre");
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMMENT, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_EXTENDED_COMMENT, ?, ?); */
- MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_NUMBER, attrs, "tag_track_num");
- /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_COUNT, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ALBUM_VOLUME_NUMBER, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ALBUM_VOLUME_COUNT, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LOCATION, ?, ?); */
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_DESCRIPTION, attrs, "tag_description");
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VERSION, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ISRC, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ORGANIZATION, ?, ?); */
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT, attrs, "tag_copyright");
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT_URI, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_CONTACT, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LICENSE, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LICENSE_URI, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_PERFORMER, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_UINT64(GST_TAG_DURATION, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_CODEC, ?, ?); */
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VIDEO_CODEC, attrs, "content_video_codec");
- MMPLAYER_UPDATE_TAG_STRING(GST_TAG_AUDIO_CODEC, attrs, "content_audio_codec");
- MMPLAYER_UPDATE_TAG_UINT(GST_TAG_BITRATE, attrs, "content_bitrate");
- MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MAXIMUM_BITRATE, attrs, "content_max_bitrate");
- MMPLAYER_UPDATE_TAG_IMAGE(GST_TAG_IMAGE, attrs, "tag_album_cover");
- /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_NOMINAL_BITRATE, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MINIMUM_BITRATE, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_SERIAL, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ENCODER, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ENCODER_VERSION, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_TRACK_GAIN, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_TRACK_PEAK, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_ALBUM_GAIN, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_ALBUM_PEAK, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_REFERENCE_LEVEL, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LANGUAGE_CODE, ?, ?); */
- /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_BEATS_PER_MINUTE, ?, ?); */
-
- if ( mmf_attrs_commit ( attrs ) )
- debug_error("failed to commit.\n");
-
- gst_tag_list_free(tag_list);
-
- return TRUE;
-}
-
-void
-__mmplayer_gst_rtp_no_more_pads (GstElement *element, gpointer data) // @
-{
- mm_player_t* player = (mm_player_t*) data;
-
- debug_fenter();
-
- /* NOTE : we can remove fakesink here if there's no rtp_dynamic_pad. because whenever
- * we connect autoplugging element to the pad which is just added to rtspsrc, we increase
- * num_dynamic_pad. and this is no-more-pad situation which means mo more pad will be added.
- * So we can say this. if num_dynamic_pad is zero, it must be one of followings
-
- * [1] audio and video will be dumped with filesink.
- * [2] autoplugging is done by just using pad caps.
- * [3] typefinding has happend in audio but audiosink is created already before no-more-pad signal
- * and the video will be dumped via filesink.
- */
- if ( player->num_dynamic_pad == 0 )
- {
- debug_log("it seems pad caps is directely used for autoplugging. removing fakesink now\n");
-
- if ( ! __mmplayer_gst_remove_fakesink( player,
- &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]) )
- {
- /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
- * signaling mechanism ( pad-added, no-more-pad, new-decoded-pad ) from various
- * source element are not same. To overcome this situation, this function will called
- * several places and several times. Therefore, this is not an error case.
- */
- return;
- }
- }
-
- /* create dot before error-return. for debugging */
- MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-no-more-pad" );
-
- /* NOTE : if rtspsrc goes to PLAYING before adding it's src pads, a/v sink elements will
- * not goes to PLAYING. they will just remain in PAUSED state. simply we are giving
- * PLAYING state again.
- */
- __mmplayer_gst_set_state(player,
- player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, TRUE, 5000 );
-
- player->no_more_pad = TRUE;
-
- debug_fleave();
-}
-
-gboolean
-__mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink) // @
-{
- GstElement* parent = NULL;
-
- return_val_if_fail(player && player->pipeline && fakesink, FALSE);
-
- /* lock */
- g_mutex_lock( player->fsink_lock );
-
- if ( ! fakesink->gst )
- {
- goto ERROR;
- }
-
- /* get parent of fakesink */
- parent = (GstElement*)gst_object_get_parent( (GstObject*)fakesink->gst );
- if ( ! parent )
- {
- debug_log("fakesink already removed\n");
- goto ERROR;
- }
-
- gst_element_set_locked_state( fakesink->gst, TRUE );
-
- /* setting the state to NULL never returns async
- * so no need to wait for completion of state transiton
- */
- if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (fakesink->gst, GST_STATE_NULL) )
- {
- debug_error("fakesink state change failure!\n");
-
- /* FIXIT : should I return here? or try to proceed to next? */
- /* return FALSE; */
- }
-
- /* remove fakesink from it's parent */
- if ( ! gst_bin_remove( GST_BIN( parent ), fakesink->gst ) )
- {
- debug_error("failed to remove fakesink\n");
-
- gst_object_unref( parent );
-
- goto ERROR;
- }
-
- gst_object_unref( parent );
-
- debug_log("state-holder removed\n");
-
- gst_element_set_locked_state( fakesink->gst, FALSE );
-
- g_mutex_unlock( player->fsink_lock );
- return TRUE;
-
-ERROR:
- if ( fakesink->gst )
- {
- gst_element_set_locked_state( fakesink->gst, FALSE );
- }
-
- g_mutex_unlock( player->fsink_lock );
- return FALSE;
-}
-
-void
-__mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data) // @
-{
- GstPad *sinkpad = NULL;
- GstCaps* caps = NULL;
- GstElement* new_element = NULL;
-
- mm_player_t* player = (mm_player_t*) data;
-
- debug_fenter();
-
- return_if_fail( element && pad );
- return_if_fail( player &&
- player->pipeline &&
- player->pipeline->mainbin );
-
-
- /* payload type is recognizable. increase num_dynamic and wait for sinkbin creation.
- * num_dynamic_pad will decreased after creating a sinkbin.
- */
- player->num_dynamic_pad++;
- debug_log("stream count inc : %d\n", player->num_dynamic_pad);
-
- /* perform autoplugging if dump is disabled */
- if ( PLAYER_INI()->rtsp_do_typefinding )
- {
- /* create typefind */
- new_element = gst_element_factory_make( "typefind", NULL );
- if ( ! new_element )
- {
- debug_error("failed to create typefind\n");
- goto ERROR;
- }
-
- MMPLAYER_SIGNAL_CONNECT( player,
- G_OBJECT(new_element),
- "have-type",
- G_CALLBACK(__mmplayer_typefind_have_type),
- (gpointer)player);
-
- /* FIXIT : try to remove it */
- player->have_dynamic_pad = FALSE;
- }
- else /* NOTE : use pad's caps directely. if enabled. what I am assuming is there's no elemnt has dynamic pad */
- {
- debug_log("using pad caps to autopluging instead of doing typefind\n");
-
- caps = gst_pad_query_caps( pad, NULL );
-
- MMPLAYER_CHECK_NULL( caps );
-
- /* clear previous result*/
- player->have_dynamic_pad = FALSE;
-
- if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
- {
- debug_error("failed to autoplug for caps : %s\n", gst_caps_to_string( caps ) );
- goto ERROR;
- }
-
- /* check if there's dynamic pad*/
- if( player->have_dynamic_pad )
- {
- debug_error("using pad caps assums there's no dynamic pad !\n");
- debug_error("try with enalbing rtsp_do_typefinding\n");
- goto ERROR;
- }
-
- gst_caps_unref( caps );
- caps = NULL;
- }
-
- /* excute new_element if created*/
- if ( new_element )
- {
- debug_log("adding new element to pipeline\n");
-
- /* set state to READY before add to bin */
- MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_READY );
-
- /* add new element to the pipeline */
- if ( FALSE == gst_bin_add( GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), new_element) )
- {
- debug_error("failed to add autoplug element to bin\n");
- goto ERROR;
- }
-
- /* get pad from element */
- sinkpad = gst_element_get_static_pad ( GST_ELEMENT(new_element), "sink" );
- if ( !sinkpad )
- {
- debug_error("failed to get sinkpad from autoplug element\n");
- goto ERROR;
- }
-
- /* link it */
- if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
- {
- debug_error("failed to link autoplug element\n");
- goto ERROR;
- }
-
- gst_object_unref (sinkpad);
- sinkpad = NULL;
-
- /* run. setting PLAYING here since streamming source is live source */
- MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_PLAYING );
- }
-
- debug_fleave();
-
- return;
-
-STATE_CHANGE_FAILED:
-ERROR:
- /* FIXIT : take care if new_element has already added to pipeline */
- if ( new_element )
- gst_object_unref(GST_OBJECT(new_element));
-
- if ( sinkpad )
- gst_object_unref(GST_OBJECT(sinkpad));
-
- if ( caps )
- gst_object_unref(GST_OBJECT(caps));
-
- /* FIXIT : how to inform this error to MSL ????? */
- /* FIXIT : I think we'd better to use g_idle_add() to destroy pipeline and
- * then post an error to application
- */
-}
-
-void
-__mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data) // @
-{
- mm_player_t* player = NULL;
- MMHandleType attrs = 0;
- GstElement* pipeline = NULL;
- GstCaps* caps = NULL;
- GstStructure* str = NULL;
- const gchar* name = NULL;
- GstPad* sinkpad = NULL;
- GstElement* sinkbin = NULL;
-
- /* check handles */
- player = (mm_player_t*) data;
-
- return_if_fail( decodebin && pad );
- return_if_fail(player && player->pipeline && player->pipeline->mainbin);
-
- pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if ( !attrs )
- {
- debug_error("cannot get content attribute\n");
- goto ERROR;
- }
-
- /* get mimetype from caps */
- caps = gst_pad_query_caps( pad, NULL );
- if ( !caps )
- {
- debug_error("cannot get caps from pad.\n");
- goto ERROR;
- }
-
- str = gst_caps_get_structure( caps, 0 );
- if ( ! str )
- {
- debug_error("cannot get structure from capse.\n");
- goto ERROR;
- }
-
- name = gst_structure_get_name(str);
- if ( ! name )
- {
- debug_error("cannot get mimetype from structure.\n");
- goto ERROR;
- }
-
- debug_log("detected mimetype : %s\n", name);
-
- if (strstr(name, "audio"))
- {
- if (player->pipeline->audiobin == NULL)
- {
- __ta__("__mmplayer_gst_create_audio_pipeline",
- if (MM_ERROR_NONE != __mmplayer_gst_create_audio_pipeline(player))
- {
- debug_error("failed to create audiobin. continuing without audio\n");
- goto ERROR;
- }
- )
-
- sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
- debug_log("creating audiosink bin success\n");
- }
- else
- {
- sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
- debug_log("re-using audiobin\n");
- }
-
- /* FIXIT : track number shouldn't be hardcoded */
- 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 )
- {
- debug_error("failed to get pad from sinkbin\n");
- goto ERROR;
- }
- }
- else if (strstr(name, "video"))
- {
- 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);
-
- if (surface_type == MM_DISPLAY_SURFACE_NULL)
- {
- debug_log("not make videobin because it dose not want\n");
- goto ERROR;
- }
-
- __ta__("__mmplayer_gst_create_video_pipeline",
- if (MM_ERROR_NONE != __mmplayer_gst_create_video_pipeline(player, caps, surface_type) )
- {
- debug_error("failed to create videobin. continuing without video\n");
- goto ERROR;
- }
- )
-
- sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
- debug_log("creating videosink bin success\n");
- }
- else
- {
- sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
- debug_log("re-using videobin\n");
- }
-
- /* FIXIT : track number shouldn't be hardcoded */
- mm_attrs_set_int_by_name(attrs, "content_video_track_num", 1);
- player->videosink_linked = 1;
-
- sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "sink" );
- if ( !sinkpad )
- {
- debug_error("failed to get pad from sinkbin\n");
- goto ERROR;
- }
- }
- else if (strstr(name, "text"))
- {
- if (player->pipeline->textbin == NULL)
- {
- __ta__("__mmplayer_gst_create_text_pipeline",
- if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player))
- {
- debug_error("failed to create textbin. continuing without text\n");
- goto ERROR;
- }
- )
-
- sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
- debug_log("creating textink bin success\n");
- }
- else
- {
- sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
- debug_log("re-using textbin\n");
- }
-
- /* FIXIT : track number shouldn't be hardcoded */
- mm_attrs_set_int_by_name(attrs, "content_text_track_num", 1);
-
- player->textsink_linked = 1;
- debug_msg("player->textsink_linked set to 1\n");
-
- sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "text_sink" );
- if ( !sinkpad )
- {
- debug_error("failed to get pad from sinkbin\n");
- goto ERROR;
- }
- }
- else
- {
- debug_warning("unknown type of elementary stream! ignoring it...\n");
- goto ERROR;
- }
-
- if ( sinkbin )
- {
- /* warm up */
- if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state( sinkbin, GST_STATE_READY ) )
- {
- debug_error("failed to set state(READY) to sinkbin\n");
- goto ERROR;
- }
-
- /* add */
- if ( FALSE == gst_bin_add( GST_BIN(pipeline), sinkbin ) )
- {
- debug_error("failed to add sinkbin to pipeline\n");
- goto ERROR;
- }
-
- /* link */
- if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
- {
- debug_error("failed to get pad from sinkbin\n");
- goto ERROR;
- }
-
- /* run */
- if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state( sinkbin, GST_STATE_PAUSED ) )
- {
- debug_error("failed to set state(PLAYING) to sinkbin\n");
- goto ERROR;
- }
-
- gst_object_unref( sinkpad );
- sinkpad = NULL;
- }
-
- debug_log("linking sink bin success\n");
-
- /* 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 */
- player->num_dynamic_pad--;
-
- debug_log("stream count dec : %d (num of dynamic pad)\n", player->num_dynamic_pad);
-
- if ( ( player->no_more_pad ) && ( player->num_dynamic_pad == 0 ) )
- {
- __mmplayer_pipeline_complete( NULL, player );
- }
-
-ERROR:
- if ( caps )
- gst_caps_unref( caps );
-
- if ( sinkpad )
- gst_object_unref(GST_OBJECT(sinkpad));
-
- /* flusing out new attributes */
- if ( mmf_attrs_commit ( attrs ) )
- {
- debug_error("failed to comit attributes\n");
- }
-
- return;
-}
-
-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;
-
- debug_fenter();
-
- 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 ( GST_ELEMENT_LINK(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst)) )
- {
- debug_log("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
- {
- debug_log("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;
- }
-
- debug_fleave();
-
- return successful_link_count;
-}
-
-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;
-
- debug_fenter();
-
- return_val_if_fail(element_bucket, 0);
- 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)) )
- {
- debug_log("__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 ++;
- }
- }
-
- debug_fleave();
-
- return successful_add_count;
-}
-
-/**
- * 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
- */
-#define MMPLAYER_CREATEONLY_ELEMENT(x_bin, x_id, x_factory, x_name) \
-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 )\
-{\
- debug_critical("failed to create %s \n", x_factory);\
- goto ERROR;\
-}\
-
-#define MMPLAYER_CREATE_ELEMENT_ADD_BIN(x_bin, x_id, x_factory, x_name, y_bin) \
-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 )\
-{\
- debug_critical("failed to create %s \n", x_factory);\
- goto ERROR;\
-}\
-if( !gst_bin_add(GST_BIN(y_bin), GST_ELEMENT(x_bin[x_id].gst)))\
-{\
- debug_log("__mmplayer_gst_element_link_bucket : Adding element [%s] to bin [%s] failed\n",\
- GST_ELEMENT_NAME(GST_ELEMENT(x_bin[x_id].gst)),\
- GST_ELEMENT_NAME(GST_ELEMENT(y_bin) ) );\
- goto ERROR;\
-}\
-
-/* macro for code readability. just for sinkbin-creation functions */
-#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket) \
-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 )\
- {\
- debug_critical("failed to create %s \n", x_factory);\
- goto ERROR;\
- }\
- if ( x_add_bucket )\
- element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
-} while(0);
-
-/**
- * AUDIO PIPELINE
- * - Local playback : audioconvert !volume ! capsfilter ! audioeq ! audiosink
- * - Streaming : audioconvert !volume ! audiosink
- * - PCM extraction : audioconvert ! audioresample ! capsfilter ! fakesink
- */
-int
-__mmplayer_gst_create_audio_pipeline(mm_player_t* player)
-{
- MMPlayerGstElement* first_element = NULL;
- MMPlayerGstElement* audiobin = NULL;
- MMHandleType attrs = 0;
- GstPad *pad = NULL;
- GstPad *ghostpad = NULL;
- GList* element_bucket = NULL;
- char *device_name = NULL;
- gboolean link_audio_sink_now = TRUE;
- int i =0;
-
- debug_fenter();
-
- return_val_if_fail( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- /* alloc handles */
- audiobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_A_NUM);
- if ( ! audiobin )
- {
- debug_error("failed to allocate memory for audiobin\n");
- return MM_ERROR_PLAYER_NO_FREE_SPACE;
- }
-
- attrs = MMPLAYER_GET_ATTRS(player);
-
- /* create bin */
- audiobin[MMPLAYER_A_BIN].id = MMPLAYER_A_BIN;
- audiobin[MMPLAYER_A_BIN].gst = gst_bin_new("audiobin");
- if ( !audiobin[MMPLAYER_A_BIN].gst )
- {
- debug_critical("failed to create audiobin\n");
- goto ERROR;
- }
-
- /* take it */
- player->pipeline->audiobin = audiobin;
-
- player->is_sound_extraction = __mmplayer_can_extract_pcm(player);
-
- /* Adding audiotp plugin for reverse trickplay feature */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TP, "audiotp", "audiotrickplay", TRUE);
-
- /* converter */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audioconverter", TRUE);
-
- /* resampler */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER, "audioresample", "resampler", TRUE);
-
- if ( ! player->is_sound_extraction )
- {
- GstCaps* caps = NULL;
- gint channels = 0;
-
- /* for logical volume control */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", TRUE);
- g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
-
- if (player->sound.mute)
- {
- debug_log("mute enabled\n");
- g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
- }
-
- /*capsfilter */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE);
-
- caps = gst_caps_from_string( "audio/x-raw,"
- "format = (string)S16LE,"
- "layout = (string)interleaved" );
-
- g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
-
- gst_caps_unref( caps );
-
- /* chech if multi-chennels */
- if (player->pipeline->mainbin && player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst)
- {
- GstPad *srcpad = NULL;
- GstCaps *caps = NULL;
-
- if ((srcpad = gst_element_get_static_pad(player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst, "src")))
- {
- if ((caps = gst_pad_query_caps(srcpad,NULL)))
- {
- MMPLAYER_LOG_GST_CAPS_TYPE(caps);
- GstStructure *str = gst_caps_get_structure(caps, 0);
- if (str)
- gst_structure_get_int (str, "channels", &channels);
- gst_caps_unref(caps);
- }
- gst_object_unref(srcpad);
- }
- }
-
- /* audio effect element. if audio effect is enabled */
- if ( channels <= 2 && (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
- {
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, PLAYER_INI()->name_of_audio_effect, "audiofilter", TRUE);
- }
-
- /* create audio sink */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, PLAYER_INI()->name_of_audiosink,
- "audiosink", link_audio_sink_now);
-
- /* sync on */
- if (MMPLAYER_IS_RTSP_STREAMING(player))
- g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL); /* sync off */
- else
- g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE, NULL); /* sync on */
-
- /* qos on */
- g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL); /* qos on */
-
- /* FIXIT : using system clock. isn't there another way? */
- g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "provide-clock", PLAYER_INI()->provide_clock, NULL);
-
- __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
-
- if(player->audio_buffer_cb)
- {
- g_object_set(audiobin[MMPLAYER_A_SINK].gst, "audio-handle", player->audio_buffer_cb_user_param, NULL);
- g_object_set(audiobin[MMPLAYER_A_SINK].gst, "audio-callback", player->audio_buffer_cb, NULL);
- }
-
- if ( g_strrstr(PLAYER_INI()->name_of_audiosink, "avsysaudiosink") )
- {
- gint volume_type = 0;
- gint audio_route = 0;
- gint sound_priority = FALSE;
- gint is_spk_out_only = 0;
- gint latency_mode = 0;
-
- /* set volume table
- * It should be set after player creation through attribute.
- * But, it can not be changed during playing.
- */
- mm_attrs_get_int_by_name(attrs, "sound_volume_type", &volume_type);
- mm_attrs_get_int_by_name(attrs, "sound_route", &audio_route);
- mm_attrs_get_int_by_name(attrs, "sound_priority", &sound_priority);
- mm_attrs_get_int_by_name(attrs, "sound_spk_out_only", &is_spk_out_only);
- mm_attrs_get_int_by_name(attrs, "audio_latency_mode", &latency_mode);
-
- /* hook sound_type if emergency case */
- if ( player->sm.event == ASM_EVENT_EMERGENCY)
- {
- debug_log ("This is emergency session, hook sound_type from [%d] to [%d]\n", volume_type, MM_SOUND_VOLUME_TYPE_EMERGENCY);
- volume_type = MM_SOUND_VOLUME_TYPE_EMERGENCY;
- }
-
- g_object_set(audiobin[MMPLAYER_A_SINK].gst,
- "volumetype", volume_type,
- "audio-route", audio_route,
- "priority", sound_priority,
- "user-route", is_spk_out_only,
- "latency", latency_mode,
- NULL);
-
- debug_log("audiosink property status...volume type:%d, route:%d, priority=%d, user-route=%d, latency=%d\n",
- volume_type, audio_route, sound_priority, is_spk_out_only, latency_mode);
- }
-
- /* Antishock can be enabled when player is resumed by soundCM.
- * But, it's not used in MMS, setting and etc.
- * Because, player start seems like late.
- */
- __mmplayer_set_antishock( player , FALSE );
- }
- else // pcm extraction only and no sound output
- {
- int dst_samplerate = 0;
- int dst_channels = 0;
- int dst_depth = 0;
- char *caps_type = NULL;
- GstCaps* caps = NULL;
-
- /* get conf. values */
- mm_attrs_multiple_get(player->attrs,
- NULL,
- "pcm_extraction_samplerate", &dst_samplerate,
- "pcm_extraction_channels", &dst_channels,
- "pcm_extraction_depth", &dst_depth,
- NULL);
- /* capsfilter */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE);
-
- caps = gst_caps_new_simple ("audio/x-raw",
- "format", G_TYPE_STRING, "S16LE",
- "rate", G_TYPE_INT, dst_samplerate,
- "channels", G_TYPE_INT, dst_channels,
- "layout", G_TYPE_STRING, "interleaved",
- NULL);
-
- caps_type = gst_caps_to_string(caps);
- debug_log("resampler new caps : %s\n", caps_type);
-
- g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
-
- /* clean */
- gst_caps_unref( caps );
- MMPLAYER_FREEIF( caps_type );
-
- /* fake sink */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "fakesink", "fakesink", TRUE);
-
- /* set sync */
- g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);
-
- __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
- }
-
- /* adding created elements to bin */
- debug_log("adding created elements to bin\n");
- if( !__mmplayer_gst_element_add_bucket_to_bin( GST_BIN(audiobin[MMPLAYER_A_BIN].gst), element_bucket ))
- {
- debug_error("failed to add elements\n");
- goto ERROR;
- }
-
- /* linking elements in the bucket by added order. */
- debug_log("Linking elements in the bucket by added order.\n");
- if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
- {
- debug_error("failed to link elements\n");
- goto ERROR;
- }
-
- /* get first element's sinkpad for creating ghostpad */
- first_element = (MMPlayerGstElement *)element_bucket->data;
-
- pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
- if ( ! pad )
- {
- debug_error("failed to get pad from first element of audiobin\n");
- goto ERROR;
- }
-
- ghostpad = gst_ghost_pad_new("sink", pad);
- if ( ! ghostpad )
- {
- debug_error("failed to create ghostpad\n");
- goto ERROR;
- }
-
- if ( FALSE == gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad) )
- {
- debug_error("failed to add ghostpad to audiobin\n");
- goto ERROR;
- }
-
- gst_object_unref(pad);
-
- if ( !player->bypass_audio_effect && (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
- {
- if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_PRESET )
- {
- if (!_mmplayer_audio_effect_preset_apply(player, player->audio_effect_info.preset))
- {
- debug_msg("apply audio effect(preset:%d) setting success\n",player->audio_effect_info.preset);
- }
- }
- else if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM )
- {
- if (!_mmplayer_audio_effect_custom_apply(player))
- {
- debug_msg("apply audio effect(custom) setting success\n");
- }
- }
- }
-
- /* done. free allocated variables */
- MMPLAYER_FREEIF( device_name );
- g_list_free(element_bucket);
-
- mm_attrs_set_int_by_name(attrs, "content_audio_found", TRUE);
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-
-ERROR:
-
- debug_log("ERROR : releasing audiobin\n");
-
- MMPLAYER_FREEIF( device_name );
-
- if ( pad )
- gst_object_unref(GST_OBJECT(pad));
-
- if ( ghostpad )
- gst_object_unref(GST_OBJECT(ghostpad));
-
- g_list_free( element_bucket );
-
-
- /* release element which are not added to bin */
- for ( i = 1; i < MMPLAYER_A_NUM; i++ ) /* NOTE : skip bin */
- {
- if ( audiobin[i].gst )
- {
- GstObject* parent = NULL;
- parent = gst_element_get_parent( audiobin[i].gst );
-
- if ( !parent )
- {
- gst_object_unref(GST_OBJECT(audiobin[i].gst));
- audiobin[i].gst = NULL;
- }
- else
- {
- gst_object_unref(GST_OBJECT(parent));
- }
- }
- }
-
- /* release audiobin with it's childs */
- if ( audiobin[MMPLAYER_A_BIN].gst )
- {
- gst_object_unref(GST_OBJECT(audiobin[MMPLAYER_A_BIN].gst));
- }
-
- MMPLAYER_FREEIF( audiobin );
-
- player->pipeline->audiobin = NULL;
-
- 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
- * - x surface (arm/x86) : videoflip ! xvimagesink
- * - evas surface (arm) : fimcconvert ! evasimagesink
- * - evas surface (x86) : videoconvertor ! videoflip ! evasimagesink
- */
-int
-__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type)
-{
- GstPad *pad = NULL;
- MMHandleType attrs;
- GList*element_bucket = NULL;
- MMPlayerGstElement* first_element = NULL;
- MMPlayerGstElement* videobin = NULL;
- gchar* vconv_factory = NULL;
- gchar *videosink_element = NULL;
-
- debug_fenter();
-
- 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 )
- {
- debug_error("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 )
- {
- debug_critical("failed to create videobin");
- goto ERROR;
- }
-
- if( player->use_video_stream ) // video stream callback, so send raw video data to application
- {
- GstStructure *str = NULL;
- gint ret = 0;
-
- debug_log("using memsink\n");
-
- /* first, create colorspace convert */
- if (player->is_nv12_tiled)
- {
- vconv_factory = "fimcconvert";
- }
- else // get video converter from player ini file
- {
- if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
- {
- vconv_factory = PLAYER_INI()->name_of_video_converter;
- }
- }
-
- if (vconv_factory)
- {
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
- }
-
- if ( !player->is_nv12_tiled)
- {
- gint width = 0; //width of video
- gint height = 0; //height of video
- GstCaps* video_caps = NULL;
-
- /* rotator, scaler and capsfilter */
- if (strncmp(PLAYER_INI()->videosink_element_x, "vaapisink", strlen("vaapisink"))){
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE);
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "video scaler", TRUE);
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CAPS, "capsfilter", "videocapsfilter", TRUE);
- }
-
- /* get video stream caps parsed by demuxer */
- str = gst_caps_get_structure (player->v_stream_caps, 0);
- if ( !str )
- {
- debug_error("cannot get structure");
- goto ERROR;
- }
-
- mm_attrs_get_int_by_name(attrs, "display_width", &width);
- mm_attrs_get_int_by_name(attrs, "display_height", &height);
- if (!width || !height) {
- /* we set width/height of original media's size to capsfilter for scaling video */
- ret = gst_structure_get_int (str, "width", &width);
- if ( !ret )
- {
- debug_error("cannot get width");
- goto ERROR;
- }
-
- ret = gst_structure_get_int(str, "height", &height);
- if ( !ret )
- {
- debug_error("cannot get height");
- goto ERROR;
- }
- }
-
- video_caps = gst_caps_new_simple( "video/x-raw",
- "width", G_TYPE_INT, width,
- "height", G_TYPE_INT, height,
- NULL);
-
- g_object_set (GST_ELEMENT(videobin[MMPLAYER_V_CAPS].gst), "caps", video_caps, NULL );
-
- gst_caps_unref( video_caps );
- }
-
- /* finally, create video sink. output will be BGRA8888. */
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, "avsysmemsink", "videosink", TRUE);
-
- MMPLAYER_SIGNAL_CONNECT( player,
- videobin[MMPLAYER_V_SINK].gst,
- "video-stream",
- G_CALLBACK(__mmplayer_videostream_cb),
- player );
- }
- else // render video data using sink plugin like xvimagesink
- {
- debug_log("using videosink");
-
- /* set video converter */
- if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
- {
- vconv_factory = PLAYER_INI()->name_of_video_converter;
-
- if ( (player->is_nv12_tiled && (surface_type == MM_DISPLAY_SURFACE_EVAS) &&
- !strcmp(PLAYER_INI()->videosink_element_evas, "evasimagesink") ) )
- {
- vconv_factory = "fimcconvert";
- }
- else if (player->is_nv12_tiled)
- {
- vconv_factory = NULL;
- }
-
- if (vconv_factory)
- {
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
- debug_log("using video converter: %s", vconv_factory);
- }
- }
-
- if (strncmp(PLAYER_INI()->videosink_element_x,"vaapisink", strlen("vaapisink"))){
- /* set video rotator */
- if ( !player->is_nv12_tiled )
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE);
-
- /* videoscaler */
- #if !defined(__arm__)
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "videoscaler", TRUE);
- #endif
- }
-
- /* set video sink */
- switch (surface_type)
- {
- case MM_DISPLAY_SURFACE_X:
- if (strlen(PLAYER_INI()->videosink_element_x) > 0)
- videosink_element = PLAYER_INI()->videosink_element_x;
- else
- goto ERROR;
- break;
- case MM_DISPLAY_SURFACE_EVAS:
- if (strlen(PLAYER_INI()->videosink_element_evas) > 0)
- videosink_element = PLAYER_INI()->videosink_element_evas;
- else
- goto ERROR;
- break;
- case MM_DISPLAY_SURFACE_X_EXT:
- {
- void *pixmap_id_cb = NULL;
- mm_attrs_get_data_by_name(attrs, "display_overlay", &pixmap_id_cb);
- if (pixmap_id_cb) /* this is used for the videoTextue(canvasTexture) overlay */
- {
- videosink_element = PLAYER_INI()->videosink_element_x;
- }
- else
- {
- debug_error("something wrong.. callback function for getting pixmap id is null");
- goto ERROR;
- }
- break;
- }
- case MM_DISPLAY_SURFACE_NULL:
- if (strlen(PLAYER_INI()->videosink_element_fake) > 0)
- videosink_element = PLAYER_INI()->videosink_element_fake;
- else
- goto ERROR;
- break;
- default:
- debug_error("unidentified surface type");
- goto ERROR;
- }
-
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_element, videosink_element, TRUE);
- debug_log("selected videosink name: %s", videosink_element);
-
- /* connect signal handlers for sink plug-in */
- switch (surface_type) {
- case MM_DISPLAY_SURFACE_X_EXT:
- MMPLAYER_SIGNAL_CONNECT( player,
- player->pipeline->videobin[MMPLAYER_V_SINK].gst,
- "frame-render-error",
- G_CALLBACK(__mmplayer_videoframe_render_error_cb),
- player );
- debug_log("videoTexture usage, connect a signal handler for pixmap rendering error");
- break;
- default:
- break;
- }
- }
-
- if ( _mmplayer_update_video_param(player) != MM_ERROR_NONE)
- goto ERROR;
-
- /* qos on */
- g_object_set (G_OBJECT (videobin[MMPLAYER_V_SINK].gst), "qos", TRUE, NULL);
-
- /* store it as it's sink element */
- __mmplayer_add_sink( player, videobin[MMPLAYER_V_SINK].gst );
-
- /* adding created elements to bin */
- if( ! __mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket) )
- {
- debug_error("failed to add elements\n");
- goto ERROR;
- }
-
- /* Linking elements in the bucket by added order */
- if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
- {
- debug_error("failed to link elements\n");
- goto ERROR;
- }
-
- /* get first element's sinkpad for creating ghostpad */
- first_element = (MMPlayerGstElement *)element_bucket->data;
- if ( !first_element )
- {
- debug_error("failed to get first element from bucket\n");
- goto ERROR;
- }
-
- pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
- if ( !pad )
- {
- debug_error("failed to get pad from first element\n");
- goto ERROR;
- }
-
- /* create ghostpad */
- if (FALSE == gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, gst_ghost_pad_new("sink", pad)))
- {
- debug_error("failed to add ghostpad to videobin\n");
- goto ERROR;
- }
- gst_object_unref(pad);
-
- /* done. free allocated variables */
- g_list_free(element_bucket);
-
- mm_attrs_set_int_by_name(attrs, "content_video_found", TRUE);
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-
-ERROR:
- debug_error("ERROR : releasing videobin\n");
-
- g_list_free( element_bucket );
-
- if (pad)
- gst_object_unref(GST_OBJECT(pad));
-
- /* release videobin with it's childs */
- 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;
-}
-
-int __mmplayer_gst_create_text_pipeline(mm_player_t* player)
-{
- MMPlayerGstElement* textbin = NULL;
- GList* element_bucket = NULL;
- GstPad *pad = NULL;
- GstPad *ghostpad = NULL;
- gint i = 0;
-
- debug_fenter();
-
- return_val_if_fail( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- /* alloc handles */
- textbin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_T_NUM);
- if ( ! textbin )
- {
- debug_error("failed to allocate memory for textbin\n");
- return MM_ERROR_PLAYER_NO_FREE_SPACE;
- }
-
- /* create bin */
- textbin[MMPLAYER_T_BIN].id = MMPLAYER_T_BIN;
- textbin[MMPLAYER_T_BIN].gst = gst_bin_new("textbin");
- if ( !textbin[MMPLAYER_T_BIN].gst )
- {
- debug_critical("failed to create textbin\n");
- goto ERROR;
- }
-
- /* take it */
- player->pipeline->textbin = textbin;
-
- /* fakesink */
- if (player->use_textoverlay)
- {
- debug_log ("use textoverlay for displaying \n");
-
- MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_t_queue", textbin[MMPLAYER_T_BIN].gst);
-
- MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_QUEUE, "queue", "text_v_queue", textbin[MMPLAYER_T_BIN].gst);
-
- MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_CONVERTER, "fimcconvert", "text_v_converter", textbin[MMPLAYER_T_BIN].gst);
-
- MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_OVERLAY, "textoverlay", "text_overlay", textbin[MMPLAYER_T_BIN].gst);
-
- if (!gst_element_link_pads (textbin[MMPLAYER_T_VIDEO_QUEUE].gst, "src", textbin[MMPLAYER_T_VIDEO_CONVERTER].gst, "sink"))
- {
- debug_error("failed to link queue and converter\n");
- goto ERROR;
- }
-
- if (!gst_element_link_pads (textbin[MMPLAYER_T_VIDEO_CONVERTER].gst, "src", textbin[MMPLAYER_T_OVERLAY].gst, "video_sink"))
- {
- debug_error("failed to link queue and textoverlay\n");
- goto ERROR;
- }
-
- if (!gst_element_link_pads (textbin[MMPLAYER_T_TEXT_QUEUE].gst, "src", textbin[MMPLAYER_T_OVERLAY].gst, "text_sink"))
- {
- debug_error("failed to link queue and textoverlay\n");
- goto ERROR;
- }
-
- }
- else
- {
- debug_log ("use subtitle message for displaying \n");
-
- MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_queue", TRUE);
-
- MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_SINK, "fakesink", "text_sink", TRUE);
-
- g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "sync", TRUE, NULL);
- g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "async", FALSE, NULL);
- g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "signal-handoffs", TRUE, NULL);
-
- MMPLAYER_SIGNAL_CONNECT( player,
- G_OBJECT(textbin[MMPLAYER_T_SINK].gst),
- "handoff",
- G_CALLBACK(__mmplayer_update_subtitle),
- (gpointer)player );
-
- if (!player->play_subtitle)
- {
- debug_log ("add textbin sink as sink element of whole pipeline.\n");
- __mmplayer_add_sink (player, GST_ELEMENT(textbin[MMPLAYER_T_SINK].gst));
- }
-
- /* adding created elements to bin */
- debug_log("adding created elements to bin\n");
- if( !__mmplayer_gst_element_add_bucket_to_bin( GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket ))
- {
- debug_error("failed to add elements\n");
- goto ERROR;
- }
-
- /* linking elements in the bucket by added order. */
- debug_log("Linking elements in the bucket by added order.\n");
- if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
- {
- debug_error("failed to link elements\n");
- goto ERROR;
- }
-
- /* done. free allocated variables */
- g_list_free(element_bucket);
- }
-
- if (textbin[MMPLAYER_T_TEXT_QUEUE].gst)
- {
- pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_TEXT_QUEUE].gst), "sink");
- if (!pad)
- {
- debug_error("failed to get text pad of textbin\n");
- goto ERROR;
- }
-
- ghostpad = gst_ghost_pad_new("text_sink", pad);
- if (!ghostpad)
- {
- debug_error("failed to create ghostpad of textbin\n");
- goto ERROR;
- }
-
- if ( FALSE == gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad) )
- {
- debug_error("failed to add ghostpad to textbin\n");
- goto ERROR;
- }
- }
-
- if (textbin[MMPLAYER_T_VIDEO_QUEUE].gst)
- {
- pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_VIDEO_QUEUE].gst), "sink");
- if (!pad)
- {
- debug_error("failed to get video pad of textbin\n");
- goto ERROR;
- }
-
- ghostpad = gst_ghost_pad_new("video_sink", pad);
- if (!ghostpad)
- {
- debug_error("failed to create ghostpad of textbin\n");
- goto ERROR;
- }
-
- if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
- {
- debug_error("failed to add ghostpad to textbin\n");
- goto ERROR;
- }
- }
-
- if (textbin[MMPLAYER_T_OVERLAY].gst)
- {
- pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_OVERLAY].gst), "src");
- if (!pad)
- {
- debug_error("failed to get src pad of textbin\n");
- goto ERROR;
- }
-
- ghostpad = gst_ghost_pad_new("src", pad);
- if (!ghostpad)
- {
- debug_error("failed to create ghostpad of textbin\n");
- goto ERROR;
- }
-
- if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
- {
- debug_error("failed to add ghostpad to textbin\n");
- goto ERROR;
- }
- }
-
- gst_object_unref(pad);
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-
-ERROR:
-
- debug_log("ERROR : releasing textbin\n");
-
- if ( pad )
- gst_object_unref(GST_OBJECT(pad));
-
- if ( ghostpad )
- gst_object_unref(GST_OBJECT(ghostpad));
-
- g_list_free( element_bucket );
-
-
- /* release element which are not added to bin */
- for ( i = 1; i < MMPLAYER_T_NUM; i++ ) /* NOTE : skip bin */
- {
- if ( textbin[i].gst )
- {
- GstObject* parent = NULL;
- parent = gst_element_get_parent( textbin[i].gst );
-
- if ( !parent )
- {
- gst_object_unref(GST_OBJECT(textbin[i].gst));
- textbin[i].gst = NULL;
- }
- else
- {
- gst_object_unref(GST_OBJECT(parent));
- }
- }
- }
-
- /* release textbin with it's childs */
- if ( textbin[MMPLAYER_T_BIN].gst )
- {
- gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
- }
-
- MMPLAYER_FREEIF( textbin );
-
- player->pipeline->textbin = NULL;
-
- return MM_ERROR_PLAYER_INTERNAL;
-}
-
-int
-__mmplayer_gst_create_subtitle_src(mm_player_t* player)
-{
- MMPlayerGstElement* mainbin = NULL;
- MMHandleType attrs = 0;
- GstElement * pipeline = NULL;
- GstElement *subsrc = NULL;
- GstElement *subparse = NULL;
- gchar *subtitle_uri =NULL;
- gchar *charset = NULL;
-
- debug_fenter();
-
- /* get mainbin */
- return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
- mainbin = player->pipeline->mainbin;
-
- attrs = MMPLAYER_GET_ATTRS(player);
- if ( !attrs )
- {
- debug_error("cannot get content attribute\n");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- mm_attrs_get_string_by_name ( attrs, "subtitle_uri", &subtitle_uri );
- if ( !subtitle_uri || strlen(subtitle_uri) < 1)
- {
- debug_error("subtitle uri is not proper filepath.\n");
- return MM_ERROR_PLAYER_INVALID_URI;
- }
- debug_log("subtitle file path is [%s].\n", subtitle_uri);
-
-
- /* create the subtitle source */
- subsrc = gst_element_factory_make("filesrc", "subtitle_source");
- if ( !subsrc )
- {
- debug_error ( "failed to create filesrc element\n" );
- goto ERROR;
- }
- g_object_set(G_OBJECT (subsrc), "location", subtitle_uri, NULL);
-
- mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_SUBSRC;
- mainbin[MMPLAYER_M_SUBSRC].gst = subsrc;
-
- if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subsrc))
- {
- debug_warning("failed to add queue\n");
- goto ERROR;
- }
-
- /* subparse */
- subparse = gst_element_factory_make("subparse", "subtitle_parser");
- if ( !subparse )
- {
- debug_error ( "failed to create subparse element\n" );
- goto ERROR;
- }
-
- charset = util_get_charset(subtitle_uri);
- if (charset)
- {
- debug_log ("detected charset is %s\n", charset );
- g_object_set (G_OBJECT (subparse), "subtitle-encoding", charset, NULL);
- }
-
- mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_SUBPARSE;
- mainbin[MMPLAYER_M_SUBPARSE].gst = subparse;
-
- if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subparse))
- {
- debug_warning("failed to add subparse\n");
- goto ERROR;
- }
-
- if (!gst_element_link_pads (subsrc, "src", subparse, "sink"))
- {
- debug_warning("failed to link subsrc and subparse\n");
- goto ERROR;
- }
-
- player->play_subtitle = TRUE;
- debug_log ("play subtitle using subtitle file\n");
-
- if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player))
- {
- debug_error("failed to create textbin. continuing without text\n");
- goto ERROR;
- }
-
- if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), GST_ELEMENT(player->pipeline->textbin[MMPLAYER_T_BIN].gst)))
- {
- debug_warning("failed to add textbin\n");
- goto ERROR;
- }
-
- if (!gst_element_link_pads (subparse, "src", player->pipeline->textbin[MMPLAYER_T_BIN].gst, "text_sink"))
- {
- debug_warning("failed to link subparse and textbin\n");
- goto ERROR;
- }
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-
-
-ERROR:
- return MM_ERROR_PLAYER_INTERNAL;
-}
-
-/**
- * This function is to create audio or video pipeline for playing.
- *
- * @param player [in] handle of player
- *
- * @return This function returns zero on success.
- * @remark
- * @see
- */
-int
-__mmplayer_gst_create_pipeline(mm_player_t* player) // @
-{
- GstBus *bus = NULL;
- MMPlayerGstElement *mainbin = NULL;
- MMHandleType attrs = 0;
- GstElement* element = NULL;
- GList* element_bucket = NULL;
- gboolean need_state_holder = TRUE;
- gint i = 0;
-
- debug_fenter();
-
- return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- /* get profile attribute */
- attrs = MMPLAYER_GET_ATTRS(player);
- if ( !attrs )
- {
- debug_error("cannot get content attribute\n");
- goto INIT_ERROR;
- }
-
- /* create pipeline handles */
- if ( player->pipeline )
- {
- debug_warning("pipeline should be released before create new one\n");
- goto INIT_ERROR;
- }
-
- player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0( sizeof(MMPlayerGstPipelineInfo) );
- if (player->pipeline == NULL)
- goto INIT_ERROR;
-
- memset( player->pipeline, 0, sizeof(MMPlayerGstPipelineInfo) );
-
-
- /* create mainbin */
- mainbin = (MMPlayerGstElement*) g_malloc0( sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM );
- if (mainbin == NULL)
- goto INIT_ERROR;
-
- memset( mainbin, 0, sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
-
-
- /* create pipeline */
- mainbin[MMPLAYER_M_PIPE].id = MMPLAYER_M_PIPE;
- mainbin[MMPLAYER_M_PIPE].gst = gst_pipeline_new("player");
- if ( ! mainbin[MMPLAYER_M_PIPE].gst )
- {
- debug_error("failed to create pipeline\n");
- goto INIT_ERROR;
- }
-
-
- /* create source element */
- switch ( player->profile.uri_type )
- {
- /* rtsp streamming */
- case MM_PLAYER_URI_TYPE_URL_RTSP:
- {
- gint network_bandwidth;
- gchar *user_agent, *wap_profile;
-
- element = gst_element_factory_make(PLAYER_INI()->name_of_rtspsrc, "streaming_source");
-
- if ( !element )
- {
- debug_critical("failed to create streaming source element\n");
- break;
- }
-
- debug_log("using streamming source [%s].\n", PLAYER_INI()->name_of_rtspsrc);
-
- /* make it zero */
- network_bandwidth = 0;
- user_agent = wap_profile = NULL;
-
- /* get attribute */
- mm_attrs_get_string_by_name ( attrs, "streaming_user_agent", &user_agent );
- mm_attrs_get_string_by_name ( attrs,"streaming_wap_profile", &wap_profile );
- mm_attrs_get_int_by_name ( attrs, "streaming_network_bandwidth", &network_bandwidth );
-
- debug_log("setting streaming source ----------------\n");
- debug_log("user_agent : %s\n", user_agent);
- debug_log("wap_profile : %s\n", wap_profile);
- debug_log("network_bandwidth : %d\n", network_bandwidth);
- debug_log("buffering time : %d\n", PLAYER_INI()->rtsp_buffering_time);
- debug_log("rebuffering time : %d\n", PLAYER_INI()->rtsp_rebuffering_time);
- debug_log("-----------------------------------------\n");
-
- /* setting property to streaming source */
- g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
- g_object_set(G_OBJECT(element), "bandwidth", network_bandwidth, NULL);
- g_object_set(G_OBJECT(element), "buffering_time", PLAYER_INI()->rtsp_buffering_time, NULL);
- g_object_set(G_OBJECT(element), "rebuffering_time", PLAYER_INI()->rtsp_rebuffering_time, NULL);
- if ( user_agent )
- g_object_set(G_OBJECT(element), "user_agent", user_agent, NULL);
- if ( wap_profile )
- g_object_set(G_OBJECT(element), "wap_profile", wap_profile, NULL);
-
- MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), "pad-added",
- G_CALLBACK (__mmplayer_gst_rtp_dynamic_pad), player );
- MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), "no-more-pads",
- G_CALLBACK (__mmplayer_gst_rtp_no_more_pads), player );
-
- player->no_more_pad = FALSE;
- player->num_dynamic_pad = 0;
-
- /* NOTE : we cannot determine it yet. this filed will be filled by
- * _mmplayer_update_content_attrs() after START.
- */
- player->streaming_type = STREAMING_SERVICE_NONE;
- }
- break;
-
- /* http streaming*/
- case MM_PLAYER_URI_TYPE_URL_HTTP:
- {
- gchar *user_agent, *proxy, *cookies, **cookie_list;
- user_agent = proxy = cookies = NULL;
- cookie_list = NULL;
- gint mode = MM_PLAYER_PD_MODE_NONE;
-
- mm_attrs_get_int_by_name ( attrs, "pd_mode", &mode );
-
- player->pd_mode = mode;
-
- debug_log("http playback, PD mode : %d\n", player->pd_mode);
-
- if ( ! MMPLAYER_IS_HTTP_PD(player) )
- {
- element = gst_element_factory_make(PLAYER_INI()->name_of_httpsrc, "http_streaming_source");
- if ( !element )
- {
- debug_critical("failed to create http streaming source element[%s].\n", PLAYER_INI()->name_of_httpsrc);
- break;
- }
- debug_log("using http streamming source [%s].\n", PLAYER_INI()->name_of_httpsrc);
-
- /* get attribute */
- mm_attrs_get_string_by_name ( attrs, "streaming_cookie", &cookies );
- mm_attrs_get_string_by_name ( attrs, "streaming_user_agent", &user_agent );
- mm_attrs_get_string_by_name ( attrs, "streaming_proxy", &proxy );
-
- /* get attribute */
- debug_log("setting http streaming source ----------------\n");
- debug_log("location : %s\n", player->profile.uri);
- debug_log("cookies : %s\n", cookies);
- debug_log("proxy : %s\n", proxy);
- debug_log("user_agent : %s\n", user_agent);
- debug_log("timeout : %d\n", PLAYER_INI()->http_timeout);
- debug_log("-----------------------------------------\n");
-
- /* setting property to streaming source */
- g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
- g_object_set(G_OBJECT(element), "timeout", PLAYER_INI()->http_timeout, NULL);
- /* check if prosy is vailid or not */
- if ( util_check_valid_url ( proxy ) )
- g_object_set(G_OBJECT(element), "proxy", proxy, NULL);
- /* parsing cookies */
- if ( ( cookie_list = util_get_cookie_list ((const char*)cookies) ) )
- g_object_set(G_OBJECT(element), "cookies", cookie_list, NULL);
- if ( user_agent )
- g_object_set(G_OBJECT(element), "user_agent", user_agent, NULL);
- }
- else // progressive download
- {
- if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
- {
- gchar *path = NULL;
-
- mm_attrs_get_string_by_name ( attrs, "pd_location", &path );
-
- MMPLAYER_FREEIF(player->pd_file_save_path);
-
- debug_log("PD Location : %s\n", path);
-
- if ( path )
- {
- player->pd_file_save_path = g_strdup(path);
- }
- else
- {
- debug_error("can't find pd location so, it should be set \n");
- return MM_ERROR_PLAYER_FILE_NOT_FOUND;
- }
- }
-
- element = gst_element_factory_make("pdpushsrc", "PD pushsrc");
- if ( !element )
- {
- debug_critical("failed to create PD push source element[%s].\n", "pdpushsrc");
- break;
- }
-
- g_object_set(G_OBJECT(element), "location", player->pd_file_save_path, NULL);
- }
-
- player->streaming_type = STREAMING_SERVICE_NONE;
- }
- break;
-
- /* file source */
- case MM_PLAYER_URI_TYPE_FILE:
- {
- char* drmsrc = PLAYER_INI()->name_of_drmsrc;
-
- debug_log("using [%s] for 'file://' handler.\n", drmsrc);
-
- element = gst_element_factory_make(drmsrc, "source");
- if ( !element )
- {
- debug_critical("failed to create %s\n", drmsrc);
- break;
- }
-
- g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL); /* uri+7 -> remove "file:// */
- //g_object_set(G_OBJECT(element), "use-mmap", TRUE, NULL);
- }
- break;
-
- /* appsrc */
- case MM_PLAYER_URI_TYPE_BUFF:
- {
- guint64 stream_type = GST_APP_STREAM_TYPE_STREAM;
-
- debug_log("mem src is selected\n");
-
- element = gst_element_factory_make("appsrc", "buff-source");
- if ( !element )
- {
- debug_critical("failed to create appsrc element\n");
- break;
- }
-
- g_object_set( element, "stream-type", stream_type, NULL );
- //g_object_set( element, "size", player->mem_buf.len, NULL );
- //g_object_set( element, "blocksize", (guint64)20480, NULL );
-
- MMPLAYER_SIGNAL_CONNECT( player, element, "seek-data",
- G_CALLBACK(__gst_appsrc_seek_data), player);
- MMPLAYER_SIGNAL_CONNECT( player, element, "need-data",
- G_CALLBACK(__gst_appsrc_feed_data), player);
- MMPLAYER_SIGNAL_CONNECT( player, element, "enough-data",
- G_CALLBACK(__gst_appsrc_enough_data), player);
- }
- break;
-
- /* appsrc */
- case MM_PLAYER_URI_TYPE_MEM:
- {
- guint64 stream_type = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
-
- debug_log("mem src is selected\n");
-
- element = gst_element_factory_make("appsrc", "mem-source");
- if ( !element )
- {
- debug_critical("failed to create appsrc element\n");
- break;
- }
-
- g_object_set( element, "stream-type", stream_type, NULL );
- g_object_set( element, "size", player->mem_buf.len, NULL );
- g_object_set( element, "blocksize", (guint64)20480, NULL );
-
- MMPLAYER_SIGNAL_CONNECT( player, element, "seek-data",
- G_CALLBACK(__gst_appsrc_seek_data_mem), &player->mem_buf );
- MMPLAYER_SIGNAL_CONNECT( player, element, "need-data",
- G_CALLBACK(__gst_appsrc_feed_data_mem), &player->mem_buf );
- }
- break;
- case MM_PLAYER_URI_TYPE_URL:
- break;
-
- case MM_PLAYER_URI_TYPE_TEMP:
- break;
-
- case MM_PLAYER_URI_TYPE_NONE:
- default:
- break;
- }
-
- /* check source element is OK */
- if ( ! element )
- {
- debug_critical("no source element was created.\n");
- goto INIT_ERROR;
- }
-
- /* take source element */
- mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
- mainbin[MMPLAYER_M_SRC].gst = element;
- element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]);
-
- if (MMPLAYER_IS_STREAMING(player))
- {
- player->streamer = __mm_player_streaming_create();
- __mm_player_streaming_initialize(player->streamer);
- }
-
- if ( MMPLAYER_IS_HTTP_PD(player) )
- {
- debug_log ("Picked queue2 element....\n");
- element = gst_element_factory_make("queue2", "hls_stream_buffer");
- if ( !element )
- {
- debug_critical ( "failed to create http streaming buffer element\n" );
- goto INIT_ERROR;
- }
-
- /* take it */
- mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_S_BUFFER;
- mainbin[MMPLAYER_M_S_BUFFER].gst = element;
- element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_S_BUFFER]);
-
- __mm_player_streaming_set_buffer(player->streamer,
- element,
- TRUE,
- PLAYER_INI()->http_max_size_bytes,
- 1.0,
- PLAYER_INI()->http_buffering_limit,
- PLAYER_INI()->http_buffering_time,
- FALSE,
- NULL,
- 0);
- }
-
- /* create autoplugging element if src element is not a streamming src */
- if ( player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_RTSP )
- {
- element = NULL;
-
- if( PLAYER_INI()->use_decodebin )
- {
- /* create decodebin */
- element = gst_element_factory_make("decodebin", "decodebin");
-
- g_object_set(G_OBJECT(element), "async-handling", TRUE, NULL);
-
- /* set signal handler */
- MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(element), "new-decoded-pad",
- G_CALLBACK(__mmplayer_gst_decode_callback), player);
-
- /* we don't need state holder, bcz decodebin is doing well by itself */
- need_state_holder = FALSE;
- }
- else
- {
- element = gst_element_factory_make("typefind", "typefinder");
- MMPLAYER_SIGNAL_CONNECT( player, element, "have-type",
- G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player );
- }
-
- /* check autoplug element is OK */
- if ( ! element )
- {
- debug_critical("can not create autoplug element\n");
- goto INIT_ERROR;
- }
-
- mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
- mainbin[MMPLAYER_M_AUTOPLUG].gst = element;
-
- element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_AUTOPLUG]);
- }
-
-
- /* add elements to pipeline */
- if( !__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket))
- {
- debug_error("Failed to add elements to pipeline\n");
- goto INIT_ERROR;
- }
-
-
- /* linking elements in the bucket by added order. */
- if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
- {
- debug_error("Failed to link some elements\n");
- goto INIT_ERROR;
- }
-
-
- /* create fakesink element for keeping the pipeline state PAUSED. if needed */
- if ( need_state_holder )
- {
- /* create */
- mainbin[MMPLAYER_M_SRC_FAKESINK].id = MMPLAYER_M_SRC_FAKESINK;
- mainbin[MMPLAYER_M_SRC_FAKESINK].gst = gst_element_factory_make ("fakesink", "state-holder");
-
- if (!mainbin[MMPLAYER_M_SRC_FAKESINK].gst)
- {
- debug_error ("fakesink element could not be created\n");
- goto INIT_ERROR;
- }
- GST_OBJECT_FLAG_UNSET (mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_FLAG_SINK);
-
- /* take ownership of fakesink. we are reusing it */
- gst_object_ref( mainbin[MMPLAYER_M_SRC_FAKESINK].gst );
-
- /* add */
- if ( FALSE == gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst),
- mainbin[MMPLAYER_M_SRC_FAKESINK].gst) )
- {
- debug_error("failed to add fakesink to bin\n");
- goto INIT_ERROR;
- }
- }
-
- /* now we have completed mainbin. take it */
- player->pipeline->mainbin = mainbin;
-
- /* connect bus callback */
- bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
- if ( !bus )
- {
- debug_error ("cannot get bus from pipeline.\n");
- goto INIT_ERROR;
- }
- player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_callback, player);
-
- /* Note : check whether subtitle atrribute uri is set. If uri is set, then tyr to play subtitle file */
- if ( __mmplayer_check_subtitle ( player ) )
- {
- if ( MM_ERROR_NONE != __mmplayer_gst_create_subtitle_src(player) )
- debug_error("fail to create subtitle src\n");
- }
-
- /* set sync handler to get tag synchronously */
- gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player, NULL);
-
- /* finished */
- gst_object_unref(GST_OBJECT(bus));
- g_list_free(element_bucket);
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-
-INIT_ERROR:
-
- __mmplayer_gst_destroy_pipeline(player);
- g_list_free(element_bucket);
-
- /* release element which are not added to bin */
- for ( i = 1; i < MMPLAYER_M_NUM; i++ ) /* NOTE : skip pipeline */
- {
- if ( mainbin[i].gst )
- {
- GstObject* parent = NULL;
- parent = gst_element_get_parent( mainbin[i].gst );
-
- if ( !parent )
- {
- gst_object_unref(GST_OBJECT(mainbin[i].gst));
- mainbin[i].gst = NULL;
- }
- else
- {
- gst_object_unref(GST_OBJECT(parent));
- }
- }
- }
-
- /* release pipeline with it's childs */
- if ( mainbin[MMPLAYER_M_PIPE].gst )
- {
- gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
- }
-
- MMPLAYER_FREEIF( player->pipeline );
- MMPLAYER_FREEIF( mainbin );
-
- return MM_ERROR_PLAYER_INTERNAL;
-}
-
-int
-__mmplayer_gst_destroy_pipeline(mm_player_t* player) // @
-{
- gint timeout = 0;
- int ret = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail ( player, MM_ERROR_INVALID_HANDLE );
-
- /* cleanup stuffs */
- MMPLAYER_FREEIF(player->type);
- player->have_dynamic_pad = FALSE;
- player->no_more_pad = FALSE;
- player->num_dynamic_pad = 0;
-
- if (player->v_stream_caps)
- {
- gst_caps_unref(player->v_stream_caps);
- player->v_stream_caps = NULL;
- }
-
- if (ahs_appsrc_cb_probe_id )
- {
- GstPad *pad = NULL;
- pad = gst_element_get_static_pad(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "src" );
-
- gst_pad_remove_probe (pad, ahs_appsrc_cb_probe_id);
- gst_object_unref(pad);
- pad = NULL;
- ahs_appsrc_cb_probe_id = 0;
- }
-
- if ( player->sink_elements )
- g_list_free ( player->sink_elements );
- player->sink_elements = NULL;
-
- /* cleanup unlinked mime type */
- MMPLAYER_FREEIF(player->unlinked_audio_mime);
- MMPLAYER_FREEIF(player->unlinked_video_mime);
- MMPLAYER_FREEIF(player->unlinked_demuxer_mime);
-
- /* cleanup running stuffs */
- __mmplayer_cancel_delayed_eos( player );
-
- /* cleanup gst stuffs */
- if ( player->pipeline )
- {
- MMPlayerGstElement* mainbin = player->pipeline->mainbin;
- GstTagList* tag_list = player->pipeline->tag_list;
-
- /* first we need to disconnect all signal hander */
- __mmplayer_release_signal_connection( player );
-
- /* disconnecting bus watch */
- if ( player->bus_watcher )
- __mmplayer_remove_g_source_from_context(player->bus_watcher);
- player->bus_watcher = 0;
-
- if ( mainbin )
- {
- MMPlayerGstElement* audiobin = player->pipeline->audiobin;
- MMPlayerGstElement* videobin = player->pipeline->videobin;
- MMPlayerGstElement* textbin = player->pipeline->textbin;
- GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mainbin[MMPLAYER_M_PIPE].gst));
- gst_bus_set_sync_handler (bus, NULL, NULL, NULL);
- gst_object_unref(bus);
-
- debug_log("pipeline status before set state to NULL\n");
- __mmplayer_dump_pipeline_state( player );
-
- timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
- ret = __mmplayer_gst_set_state ( player, mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_NULL, FALSE, timeout );
- if ( ret != MM_ERROR_NONE )
- {
- debug_error("fail to change state to NULL\n");
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- debug_log("pipeline status before unrefering pipeline\n");
- __mmplayer_dump_pipeline_state( player );
-
- gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
-
- /* free fakesink */
- if ( mainbin[MMPLAYER_M_SRC_FAKESINK].gst )
- gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
-
- /* free avsysaudiosink
- avsysaudiosink should be unref when destory pipeline just after start play with BT.
- Because audiosink is created but never added to bin, and therefore it will not be unref when pipeline is destroyed.
- */
- MMPLAYER_FREEIF( audiobin );
- MMPLAYER_FREEIF( videobin );
- MMPLAYER_FREEIF( textbin );
- MMPLAYER_FREEIF( mainbin );
- }
-
- if ( tag_list )
- gst_tag_list_free(tag_list);
-
- MMPLAYER_FREEIF( player->pipeline );
- }
-
- player->pipeline_is_constructed = FALSE;
-
- debug_fleave();
-
- return ret;
-}
-
diff --git a/src/mm_player_priv_internal.c b/src/mm_player_priv_internal.c
deleted file mode 100755
index b663f18..0000000
--- a/src/mm_player_priv_internal.c
+++ /dev/null
@@ -1,1179 +0,0 @@
-/*
- * libmm-player
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/*===========================================================================================
-| |
-| INCLUDE FILES |
-| |
-========================================================================================== */
-#include "mm_player_priv.h"
-#include "mm_player_priv_internal.h"
-#include "mm_player_priv_locl_func.h"
-
-
-/*===========================================================================================
-| |
-| LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE |
-| |
-========================================================================================== */
-
-/*---------------------------------------------------------------------------
-| GLOBAL CONSTANT DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| IMPORTED VARIABLE DECLARATIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| IMPORTED FUNCTION DECLARATIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL #defines: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL CONSTANT DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL DATA TYPE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| GLOBAL VARIABLE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL VARIABLE DEFINITIONS: |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-| LOCAL FUNCTION PROTOTYPES: |
----------------------------------------------------------------------------*/
-
-/*===========================================================================================
-| |
-| FUNCTION DEFINITIONS |
-| |
-========================================================================================== */
-/* NOTE : be careful with calling this api. please refer to below glib comment
- * glib comment : Note that there is a bug in GObject that makes this function much
- * less useful than it might seem otherwise. Once gobject is disposed, the callback
- * will no longer be called, but, the signal handler is not currently disconnected.
- * If the instance is itself being freed at the same time than this doesn't matter,
- * since the signal will automatically be removed, but if instance persists,
- * then the signal handler will leak. You should not remove the signal yourself
- * because in a future versions of GObject, the handler will automatically be
- * disconnected.
- *
- * It's possible to work around this problem in a way that will continue to work
- * with future versions of GObject by checking that the signal handler is still
- * connected before disconnected it:
- *
- * if (g_signal_handler_is_connected (instance, id))
- * g_signal_handler_disconnect (instance, id);
- */
-void
-__mmplayer_release_signal_connection(mm_player_t* player)
-{
- GList* sig_list = player->signals;
- MMPlayerSignalItem* item = NULL;
-
- debug_fenter();
-
- return_if_fail( player );
- return_if_fail( player->signals );
-
- for ( ; sig_list; sig_list = sig_list->next )
- {
- item = sig_list->data;
-
- if ( item && item->obj && GST_IS_ELEMENT(item->obj) )
- {
- debug_log("checking signal connection : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
-
- if ( g_signal_handler_is_connected ( item->obj, item->sig ) )
- {
- debug_log("signal disconnecting : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
- g_signal_handler_disconnect ( item->obj, item->sig );
- }
- }
-
- MMPLAYER_FREEIF( item );
-
- }
- g_list_free ( player->signals );
- player->signals = NULL;
-
- debug_fleave();
-
- return;
-}
-
-gboolean
-__mmplayer_dump_pipeline_state( mm_player_t* player )
-{
- GstIterator*iter = NULL;
- gboolean done = FALSE;
-
- GValue item = { 0, };
- GstElement *element;
-
- GstElementFactory *factory = NULL;
-
- GstState state = GST_STATE_VOID_PENDING;
- GstState pending = GST_STATE_VOID_PENDING;
- GstClockTime time = 200*GST_MSECOND;
-
- debug_fenter();
-
- return_val_if_fail ( player &&
- player->pipeline &&
- player->pipeline->mainbin,
- FALSE );
-
- iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) );
-
- if ( iter != NULL )
- {
- while (!done) {
- switch ( gst_iterator_next (iter, &item) )
- {
- case GST_ITERATOR_OK:
- element = g_value_get_object (&item);
- gst_element_get_state(element,&state, &pending,time);
-
- factory = gst_element_get_factory (element) ;
-
- if (factory)
- {
- debug_error("%s:%s : From:%s To:%s refcount : %d\n", GST_OBJECT_NAME(factory) , GST_ELEMENT_NAME(element) ,
- gst_element_state_get_name(state), gst_element_state_get_name(pending) , GST_OBJECT_REFCOUNT_VALUE(element));
- }
- g_value_reset(&item);
- break;
- case GST_ITERATOR_RESYNC:
- gst_iterator_resync (iter);
- break;
- case GST_ITERATOR_ERROR:
- done = TRUE;
- break;
- case GST_ITERATOR_DONE:
- done = TRUE;
- break;
- }
- }
- }
-
- element = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
-
- gst_element_get_state(element,&state, &pending,time);
-
- factory = gst_element_get_factory (element) ;
-
- if (!factory)
- {
- debug_error("%s:%s : From:%s To:%s refcount : %d\n",
- GST_OBJECT_NAME(factory),
- GST_ELEMENT_NAME(element),
- gst_element_state_get_name(state),
- gst_element_state_get_name(pending),
- GST_OBJECT_REFCOUNT_VALUE(element) );
- }
-
- g_value_unset (&item);
-
- if ( iter )
- gst_iterator_free (iter);
-
- debug_fleave();
-
- return FALSE;
-}
-
-int
-__mmplayer_gst_set_state (mm_player_t* player, GstElement * element, GstState state, gboolean async, gint timeout) // @
-{
- GstState element_state = GST_STATE_VOID_PENDING;
- GstState element_pending_state = GST_STATE_VOID_PENDING;
- GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
-
- debug_fenter();
-
- return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
- return_val_if_fail ( element, MM_ERROR_INVALID_ARGUMENT );
-
- debug_log("setting [%s] element state to : %d\n", GST_ELEMENT_NAME(element), state);
-
- /* set state */
- ret = gst_element_set_state(element, state);
-
- if ( ret == GST_STATE_CHANGE_FAILURE )
- {
- debug_error("failed to set [%s] state to [%d]\n", GST_ELEMENT_NAME(element), state);
-
- /* dump state of all element */
- __mmplayer_dump_pipeline_state( player );
-
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- /* return here so state transition to be done in async mode */
- if ( async )
- {
- debug_log("async state transition. not waiting for state complete.\n");
- return MM_ERROR_NONE;
- }
-
- /* wait for state transition */
- ret = gst_element_get_state( element, &element_state, &element_pending_state, timeout * GST_SECOND );
-
- if ( ret == GST_STATE_CHANGE_FAILURE || ( state != element_state ) )
- {
- if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_READY)
- __mmplayer_release_signal_connection( player );
-
- debug_error("failed to change [%s] element state to [%s] within %d sec\n",
- GST_ELEMENT_NAME(element),
- gst_element_state_get_name(state), timeout );
-
- debug_error(" [%s] state : %s pending : %s \n",
- GST_ELEMENT_NAME(element),
- gst_element_state_get_name(element_state),
- gst_element_state_get_name(element_pending_state) );
-
- /* dump state of all element */
- __mmplayer_dump_pipeline_state( player );
-
- return MM_ERROR_PLAYER_INTERNAL;
- }
-
- debug_log("[%s] element state has changed to %s \n",
- GST_ELEMENT_NAME(element),
- gst_element_state_get_name(element_state));
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-}
-
-void
-__mmplayer_cancel_delayed_eos( mm_player_t* player )
-{
- debug_fenter();
-
- return_if_fail( player );
-
- if ( player->eos_timer )
- {
- __mmplayer_remove_g_source_from_context( player->eos_timer );
- }
-
- player->eos_timer = 0;
-
- debug_fleave();
-
- return;
-}
-
-gboolean
-__mmplayer_check_subtitle( mm_player_t* player )
-{
- MMHandleType attrs = 0;
- char *subtitle_uri = NULL;
-
- debug_fenter();
-
- return_val_if_fail( player, FALSE );
-
- /* get subtitle attribute */
- attrs = MMPLAYER_GET_ATTRS(player);
- if ( !attrs )
- return FALSE;
-
- mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
- if ( !subtitle_uri || !strlen(subtitle_uri))
- return FALSE;
-
- debug_log ("subtite uri is %s[%d]\n", subtitle_uri, strlen(subtitle_uri));
-
- debug_fleave();
-
- return TRUE;
-}
-
-/* NOTE: post "not supported codec message" to application
- * when one codec is not found during AUTOPLUGGING in MSL.
- * So, it's separated with error of __mmplayer_gst_callback().
- * And, if any codec is not found, don't send message here.
- * Because GST_ERROR_MESSAGE is posted by other plugin internally.
- */
-int
-__mmplayer_handle_missed_plugin(mm_player_t* player)
-{
- MMMessageParamType msg_param;
- memset (&msg_param, 0, sizeof(MMMessageParamType));
- gboolean post_msg_direct = FALSE;
-
- debug_fenter();
-
- return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- debug_log("not_supported_codec = 0x%02x, can_support_codec = 0x%02x\n",
- player->not_supported_codec, player->can_support_codec);
-
- if( player->not_found_demuxer )
- {
- msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
- msg_param.data = g_strdup_printf("%s", player->unlinked_demuxer_mime);
-
- MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
- MMPLAYER_FREEIF(msg_param.data);
-
- return MM_ERROR_NONE;
- }
-
- if (player->not_supported_codec)
- {
- if ( player->can_support_codec ) // There is one codec to play
- {
- post_msg_direct = TRUE;
- }
- else
- {
- if ( player->pipeline->audiobin ) // Some content has only PCM data in container.
- post_msg_direct = TRUE;
- }
-
- if ( post_msg_direct )
- {
- MMMessageParamType msg_param;
- memset (&msg_param, 0, sizeof(MMMessageParamType));
-
- if ( player->not_supported_codec == MISSING_PLUGIN_AUDIO )
- {
- debug_warning("not found AUDIO codec, posting error code to application.\n");
-
- msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
- msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
- }
- else if ( player->not_supported_codec == MISSING_PLUGIN_VIDEO )
- {
- debug_warning("not found VIDEO codec, posting error code to application.\n");
-
- msg_param.code = MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
- msg_param.data = g_strdup_printf("%s", player->unlinked_video_mime);
- }
-
- MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-
- MMPLAYER_FREEIF(msg_param.data);
-
- return MM_ERROR_NONE;
- }
- else // no any supported codec case
- {
- debug_warning("not found any codec, posting error code to application.\n");
-
- if ( player->not_supported_codec == MISSING_PLUGIN_AUDIO )
- {
- msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
- msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
- }
- else
- {
- msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
- msg_param.data = g_strdup_printf("%s, %s", player->unlinked_video_mime, player->unlinked_audio_mime);
- }
-
- MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-
- MMPLAYER_FREEIF(msg_param.data);
- }
- }
-
- debug_fleave();
-
- return MM_ERROR_NONE;
-}
-
-gboolean
-__mmplayer_link_decoder( mm_player_t* player, GstPad *srcpad)
-{
- const gchar* name = NULL;
- GstStructure* str = NULL;
- GstCaps* srccaps = NULL;
-
- debug_fenter();
-
- return_val_if_fail( player, FALSE );
- return_val_if_fail ( srcpad, FALSE );
-
- /* to check any of the decoder (video/audio) need to be linked to parser*/
- srccaps = gst_pad_query_caps( srcpad, NULL );
- if ( !srccaps )
- goto ERROR;
-
- str = gst_caps_get_structure( srccaps, 0 );
- if ( ! str )
- goto ERROR;
-
- name = gst_structure_get_name(str);
- if ( ! name )
- goto ERROR;
-
- if (strstr(name, "video"))
- {
- if(player->videodec_linked)
- {
- debug_msg("Video decoder already linked\n");
- return FALSE;
- }
- }
- if (strstr(name, "audio"))
- {
- if(player->audiodec_linked)
- {
- debug_msg("Audio decoder already linked\n");
- return FALSE;
- }
- }
-
- gst_caps_unref( srccaps );
-
- debug_fleave();
-
- return TRUE;
-
-ERROR:
- if ( srccaps )
- gst_caps_unref( srccaps );
-
- return FALSE;
-}
-
-gboolean
-__mmplayer_link_sink( mm_player_t* player , GstPad *srcpad)
-{
- const gchar* name = NULL;
- GstStructure* str = NULL;
- GstCaps* srccaps = NULL;
-
- debug_fenter();
-
- return_val_if_fail ( player, FALSE );
- return_val_if_fail ( srcpad, FALSE );
-
- /* to check any of the decoder (video/audio) need to be linked to parser*/
- srccaps = gst_pad_query_caps( srcpad, NULL );
- if ( !srccaps )
- goto ERROR;
-
- str = gst_caps_get_structure( srccaps, 0 );
- if ( ! str )
- goto ERROR;
-
- name = gst_structure_get_name(str);
- if ( ! name )
- goto ERROR;
-
- if (strstr(name, "video"))
- {
- if(player->videosink_linked)
- {
- debug_msg("Video Sink already linked\n");
- return FALSE;
- }
- }
- if (strstr(name, "audio"))
- {
- if(player->audiosink_linked)
- {
- debug_msg("Audio Sink already linked\n");
- return FALSE;
- }
- }
- if (strstr(name, "text"))
- {
- if(player->textsink_linked)
- {
- debug_msg("Text Sink already linked\n");
- return FALSE;
- }
- }
-
- gst_caps_unref( srccaps );
-
- debug_fleave();
-
- return TRUE;
- //return (!player->videosink_linked || !player->audiosink_linked);
-
-ERROR:
- if ( srccaps )
- gst_caps_unref( srccaps );
-
- return FALSE;
-}
-
-gint
-__gst_handle_core_error( mm_player_t* player, int code )
-{
- gint trans_err = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- switch ( code )
- {
- case GST_CORE_ERROR_STATE_CHANGE:
- case GST_CORE_ERROR_MISSING_PLUGIN:
- case GST_CORE_ERROR_SEEK:
- case GST_CORE_ERROR_NOT_IMPLEMENTED:
- case GST_CORE_ERROR_FAILED:
- case GST_CORE_ERROR_TOO_LAZY:
- case GST_CORE_ERROR_PAD:
- case GST_CORE_ERROR_THREAD:
- case GST_CORE_ERROR_NEGOTIATION:
- case GST_CORE_ERROR_EVENT:
- case GST_CORE_ERROR_CAPS:
- case GST_CORE_ERROR_TAG:
- case GST_CORE_ERROR_CLOCK:
- case GST_CORE_ERROR_DISABLED:
- default:
- trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
- break;
- }
-
- debug_fleave();
-
- return trans_err;
-}
-
-gint
-__gst_handle_library_error( mm_player_t* player, int code )
-{
- gint trans_err = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- switch ( code )
- {
- case GST_LIBRARY_ERROR_FAILED:
- case GST_LIBRARY_ERROR_TOO_LAZY:
- case GST_LIBRARY_ERROR_INIT:
- case GST_LIBRARY_ERROR_SHUTDOWN:
- case GST_LIBRARY_ERROR_SETTINGS:
- case GST_LIBRARY_ERROR_ENCODE:
- default:
- trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
- break;
- }
-
- debug_fleave();
-
- return trans_err;
-}
-
-gint
-__gst_handle_resource_error( mm_player_t* player, int code )
-{
- gint trans_err = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
- switch ( code )
- {
- case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
- trans_err = MM_ERROR_PLAYER_NO_FREE_SPACE;
- break;
- case GST_RESOURCE_ERROR_NOT_FOUND:
- case GST_RESOURCE_ERROR_OPEN_READ:
- if ( MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
- || MMPLAYER_IS_RTSP_STREAMING(player))
- {
- trans_err = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
- break;
- }
- case GST_RESOURCE_ERROR_READ:
- if ( MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
- || MMPLAYER_IS_RTSP_STREAMING(player))
- {
- trans_err = MM_ERROR_PLAYER_STREAMING_FAIL;
- break;
- }
- case GST_RESOURCE_ERROR_WRITE:
- case GST_RESOURCE_ERROR_FAILED:
- trans_err = MM_ERROR_PLAYER_INTERNAL;
- break;
-
- case GST_RESOURCE_ERROR_SEEK:
- case GST_RESOURCE_ERROR_TOO_LAZY:
- case GST_RESOURCE_ERROR_BUSY:
- case GST_RESOURCE_ERROR_OPEN_WRITE:
- case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
- case GST_RESOURCE_ERROR_CLOSE:
- case GST_RESOURCE_ERROR_SYNC:
- case GST_RESOURCE_ERROR_SETTINGS:
- default:
- trans_err = MM_ERROR_PLAYER_FILE_NOT_FOUND;
- break;
- }
-
- debug_fleave();
-
- return trans_err;
-}
-
-gint
-__gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message )
-{
- gint trans_err = MM_ERROR_NONE;
-
- debug_fenter();
-
- return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
- return_val_if_fail( error, MM_ERROR_INVALID_ARGUMENT );
- return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
-
- switch ( error->code )
- {
- case GST_STREAM_ERROR_FAILED:
- case GST_STREAM_ERROR_TYPE_NOT_FOUND:
- case GST_STREAM_ERROR_DECODE:
- case GST_STREAM_ERROR_WRONG_TYPE:
- case GST_STREAM_ERROR_DECRYPT:
- case GST_STREAM_ERROR_DECRYPT_NOKEY:
- trans_err = __gst_transform_gsterror( player, message, error );
- break;
-
- case GST_STREAM_ERROR_CODEC_NOT_FOUND:
- case GST_STREAM_ERROR_NOT_IMPLEMENTED:
- case GST_STREAM_ERROR_TOO_LAZY:
- case GST_STREAM_ERROR_ENCODE:
- case GST_STREAM_ERROR_DEMUX:
- case GST_STREAM_ERROR_MUX:
- case GST_STREAM_ERROR_FORMAT:
- default:
- trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
- break;
- }
-
- debug_fleave();
-
- return trans_err;
-}
-
-/* NOTE : decide gstreamer state whether there is some playable track or not. */
-gint
-__gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error )
-{
- gchar *src_element_name = NULL;
- GstElement *src_element = NULL;
- GstElementFactory *factory = NULL;
- const gchar* klass = NULL;
-
- debug_fenter();
-
- /* FIXIT */
- return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
- return_val_if_fail ( message->src, MM_ERROR_INVALID_ARGUMENT );
- return_val_if_fail ( error, MM_ERROR_INVALID_ARGUMENT );
-
- src_element = GST_ELEMENT_CAST(message->src);
- if ( !src_element )
- goto INTERNAL_ERROR;
-
- src_element_name = GST_ELEMENT_NAME(src_element);
- if ( !src_element_name )
- goto INTERNAL_ERROR;
-
- factory = gst_element_get_factory(src_element);
- if ( !factory )
- goto INTERNAL_ERROR;
-
- klass = gst_element_factory_get_klass(factory);
- if ( !klass )
- goto INTERNAL_ERROR;
-
- debug_log("error code=%d, msg=%s, src element=%s, class=%s\n",
- error->code, error->message, src_element_name, klass);
-
- switch ( error->code )
- {
- case GST_STREAM_ERROR_DECODE:
- {
- /* Demuxer can't parse one track because it's corrupted.
- * So, the decoder for it is not linked.
- * But, it has one playable track.
- */
- if ( g_strrstr(klass, "Demux") )
- {
- if ( player->can_support_codec == FOUND_PLUGIN_VIDEO )
- {
- return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
- }
- else if ( player->can_support_codec == FOUND_PLUGIN_AUDIO )
- {
- return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
- }
- else
- {
- if ( player->pipeline->audiobin ) // PCM
- {
- return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
- }
- else
- {
- goto CODEC_NOT_FOUND;
- }
- }
- }
- return MM_ERROR_PLAYER_INVALID_STREAM;
- }
- break;
-
- case GST_STREAM_ERROR_WRONG_TYPE:
- {
- return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
- }
- break;
-
- case GST_STREAM_ERROR_FAILED:
- {
- /* Decoder Custom Message */
- if ( strstr(error->message, "ongoing") )
- {
- if ( strncasecmp(klass, "audio", 5) )
- {
- if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) )
- {
- debug_log("Video can keep playing.\n");
- return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
- }
- else
- {
- goto CODEC_NOT_FOUND;
- }
-
- }
- else if ( strncasecmp(klass, "video", 5) )
- {
- if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) )
- {
- debug_log("Audio can keep playing.\n");
- return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
- }
- else
- {
- goto CODEC_NOT_FOUND;
- }
- }
- }
- return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
- }
- break;
-
- case GST_STREAM_ERROR_TYPE_NOT_FOUND:
- return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
- break;
-
- case GST_STREAM_ERROR_DECRYPT:
- case GST_STREAM_ERROR_DECRYPT_NOKEY:
- {
- debug_error("decryption error, [%s] failed, reason : [%s]\n", src_element_name, error->message);
-
- if ( strstr(error->message, "rights expired") )
- {
- return MM_ERROR_PLAYER_DRM_EXPIRED;
- }
- else if ( strstr(error->message, "no rights") )
- {
- return MM_ERROR_PLAYER_DRM_NO_LICENSE;
- }
- else if ( strstr(error->message, "has future rights") )
- {
- return MM_ERROR_PLAYER_DRM_FUTURE_USE;
- }
- else if ( strstr(error->message, "opl violation") )
- {
- return MM_ERROR_PLAYER_DRM_OUTPUT_PROTECTION;
- }
- return MM_ERROR_PLAYER_DRM_NOT_AUTHORIZED;
- }
- break;
-
- default:
- break;
- }
-
- debug_fleave();
-
- return MM_ERROR_PLAYER_INVALID_STREAM;
-
-INTERNAL_ERROR:
- return MM_ERROR_PLAYER_INTERNAL;
-
-CODEC_NOT_FOUND:
- debug_log("not found any available codec. Player should be destroyed.\n");
- return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
-}
-
-gboolean
-__mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error )
-{
- MMMessageParamType msg_param;
- gchar *msg_src_element;
-
- debug_fenter();
-
- return_val_if_fail( player, FALSE );
- return_val_if_fail( error, FALSE );
-
- /* NOTE : do somthing necessary inside of __gst_handle_XXX_error. not here */
-
- memset (&msg_param, 0, sizeof(MMMessageParamType));
-
- if ( error->domain == GST_CORE_ERROR )
- {
- msg_param.code = __gst_handle_core_error( player, error->code );
- }
- else if ( error->domain == GST_LIBRARY_ERROR )
- {
- msg_param.code = __gst_handle_library_error( player, error->code );
- }
- else if ( error->domain == GST_RESOURCE_ERROR )
- {
- msg_param.code = __gst_handle_resource_error( player, error->code );
- }
- else if ( error->domain == GST_STREAM_ERROR )
- {
- msg_param.code = __gst_handle_stream_error( player, error, message );
- }
- else
- {
- debug_warning("This error domain is not defined.\n");
-
- /* we treat system error as an internal error */
- msg_param.code = MM_ERROR_PLAYER_INVALID_STREAM;
- }
-
- if ( message->src )
- {
- msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
-
- msg_param.data = (void *) error->message;
-
- debug_error("-Msg src : [%s] Domain : [%s] Error : [%s] Code : [%d] is tranlated to error code : [0x%x]\n",
- msg_src_element, g_quark_to_string (error->domain), error->message, error->code, msg_param.code);
- }
-
- /* post error to application */
- if ( ! player->msg_posted )
- {
- MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
- /* don't post more if one was sent already */
- player->msg_posted = TRUE;
- }
- else
- {
- debug_log("skip error post because it's sent already.\n");
- }
-
- debug_fleave();
-
- return TRUE;
-}
-
-gboolean
-__mmplayer_handle_streaming_error ( mm_player_t* player, GstMessage * message )
-{
- debug_log("\n");
- MMMessageParamType msg_param;
- gchar *msg_src_element = NULL;
- GstStructure *s = NULL;
- guint error_id = 0;
- gchar *error_string = NULL;
-
- debug_fenter();
-
- return_val_if_fail ( player, FALSE );
- return_val_if_fail ( message, FALSE );
-
- s = malloc( sizeof(GstStructure) );
- memcpy ( s, gst_message_get_structure ( message ), sizeof(GstStructure));
-
- if ( !gst_structure_get_uint (s, "error_id", &error_id) )
- error_id = MMPLAYER_STREAMING_ERROR_NONE;
-
- switch ( error_id )
- {
- case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_AUDIO:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_AUDIO;
- break;
- case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_VIDEO:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_VIDEO;
- break;
- case MMPLAYER_STREAMING_ERROR_CONNECTION_FAIL:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
- break;
- case MMPLAYER_STREAMING_ERROR_DNS_FAIL:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_DNS_FAIL;
- break;
- case MMPLAYER_STREAMING_ERROR_SERVER_DISCONNECTED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVER_DISCONNECTED;
- break;
- case MMPLAYER_STREAMING_ERROR_BAD_SERVER:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_SERVER;
- break;
- case MMPLAYER_STREAMING_ERROR_INVALID_PROTOCOL:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_PROTOCOL;
- break;
- case MMPLAYER_STREAMING_ERROR_INVALID_URL:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_URL;
- break;
- case MMPLAYER_STREAMING_ERROR_UNEXPECTED_MSG:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_UNEXPECTED_MSG;
- break;
- case MMPLAYER_STREAMING_ERROR_OUT_OF_MEMORIES:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_OUT_OF_MEMORIES;
- break;
- case MMPLAYER_STREAMING_ERROR_RTSP_TIMEOUT:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_RTSP_TIMEOUT;
- break;
- case MMPLAYER_STREAMING_ERROR_BAD_REQUEST:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_REQUEST;
- break;
- case MMPLAYER_STREAMING_ERROR_NOT_AUTHORIZED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_AUTHORIZED;
- break;
- case MMPLAYER_STREAMING_ERROR_PAYMENT_REQUIRED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_PAYMENT_REQUIRED;
- break;
- case MMPLAYER_STREAMING_ERROR_FORBIDDEN:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_FORBIDDEN;
- break;
- case MMPLAYER_STREAMING_ERROR_CONTENT_NOT_FOUND:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_CONTENT_NOT_FOUND;
- break;
- case MMPLAYER_STREAMING_ERROR_METHOD_NOT_ALLOWED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_METHOD_NOT_ALLOWED;
- break;
- case MMPLAYER_STREAMING_ERROR_NOT_ACCEPTABLE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_ACCEPTABLE;
- break;
- case MMPLAYER_STREAMING_ERROR_PROXY_AUTHENTICATION_REQUIRED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_PROXY_AUTHENTICATION_REQUIRED;
- break;
- case MMPLAYER_STREAMING_ERROR_SERVER_TIMEOUT:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVER_TIMEOUT;
- break;
- case MMPLAYER_STREAMING_ERROR_GONE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_GONE;
- break;
- case MMPLAYER_STREAMING_ERROR_LENGTH_REQUIRED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_LENGTH_REQUIRED;
- break;
- case MMPLAYER_STREAMING_ERROR_PRECONDITION_FAILED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_PRECONDITION_FAILED;
- break;
- case MMPLAYER_STREAMING_ERROR_REQUEST_ENTITY_TOO_LARGE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_REQUEST_ENTITY_TOO_LARGE;
- break;
- case MMPLAYER_STREAMING_ERROR_REQUEST_URI_TOO_LARGE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_REQUEST_URI_TOO_LARGE;
- break;
- case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_MEDIA_TYPE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_MEDIA_TYPE;
- break;
- case MMPLAYER_STREAMING_ERROR_PARAMETER_NOT_UNDERSTOOD:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_PARAMETER_NOT_UNDERSTOOD;
- break;
- case MMPLAYER_STREAMING_ERROR_CONFERENCE_NOT_FOUND:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_CONFERENCE_NOT_FOUND;
- break;
- case MMPLAYER_STREAMING_ERROR_NOT_ENOUGH_BANDWIDTH:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_ENOUGH_BANDWIDTH;
- break;
- case MMPLAYER_STREAMING_ERROR_NO_SESSION_ID:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_NO_SESSION_ID;
- break;
- case MMPLAYER_STREAMING_ERROR_METHOD_NOT_VALID_IN_THIS_STATE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_METHOD_NOT_VALID_IN_THIS_STATE;
- break;
- case MMPLAYER_STREAMING_ERROR_HEADER_FIELD_NOT_VALID_FOR_SOURCE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_HEADER_FIELD_NOT_VALID_FOR_SOURCE;
- break;
- case MMPLAYER_STREAMING_ERROR_INVALID_RANGE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_RANGE;
- break;
- case MMPLAYER_STREAMING_ERROR_PARAMETER_IS_READONLY:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_PARAMETER_IS_READONLY;
- break;
- case MMPLAYER_STREAMING_ERROR_AGGREGATE_OP_NOT_ALLOWED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_AGGREGATE_OP_NOT_ALLOWED;
- break;
- case MMPLAYER_STREAMING_ERROR_ONLY_AGGREGATE_OP_ALLOWED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_ONLY_AGGREGATE_OP_ALLOWED;
- break;
- case MMPLAYER_STREAMING_ERROR_BAD_TRANSPORT:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_TRANSPORT;
- break;
- case MMPLAYER_STREAMING_ERROR_DESTINATION_UNREACHABLE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_DESTINATION_UNREACHABLE;
- break;
- case MMPLAYER_STREAMING_ERROR_INTERNAL_SERVER_ERROR:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_INTERNAL_SERVER_ERROR;
- break;
- case MMPLAYER_STREAMING_ERROR_NOT_IMPLEMENTED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_IMPLEMENTED;
- break;
- case MMPLAYER_STREAMING_ERROR_BAD_GATEWAY:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_GATEWAY;
- break;
- case MMPLAYER_STREAMING_ERROR_SERVICE_UNAVAILABLE:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVICE_UNAVAILABLE;
- break;
- case MMPLAYER_STREAMING_ERROR_GATEWAY_TIME_OUT:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_GATEWAY_TIME_OUT;
- break;
- case MMPLAYER_STREAMING_ERROR_RTSP_VERSION_NOT_SUPPORTED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_RTSP_VERSION_NOT_SUPPORTED;
- break;
- case MMPLAYER_STREAMING_ERROR_OPTION_NOT_SUPPORTED:
- msg_param.code = MM_ERROR_PLAYER_STREAMING_OPTION_NOT_SUPPORTED;
- break;
- default:
- return MM_ERROR_PLAYER_STREAMING_FAIL;
- }
-
- error_string = g_strdup(gst_structure_get_string (s, "error_string"));
- if ( error_string )
- msg_param.data = (void *) error_string;
-
- if ( message->src )
- {
- msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
-
- debug_error("-Msg src : [%s] Code : [%x] Error : [%s] \n",
- msg_src_element, msg_param.code, (char*)msg_param.data );
- }
-
- /* post error to application */
- if ( ! player->msg_posted )
- {
- MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-
- /* don't post more if one was sent already */
- player->msg_posted = TRUE;
- }
- else
- {
- debug_log("skip error post because it's sent already.\n");
- }
-
- debug_fleave();
-
- return TRUE;
-
-}
-void
-__mmplayer_add_sink( mm_player_t* player, GstElement* sink )
-{
- debug_fenter();
-
- return_if_fail ( player );
- return_if_fail ( sink );
-
- player->sink_elements =
- g_list_append(player->sink_elements, sink);
-
- debug_fleave();
-}
-void
-__mmplayer_del_sink( mm_player_t* player, GstElement* sink )
-{
- debug_fenter();
-
- return_if_fail ( player );
- return_if_fail ( sink );
-
- player->sink_elements =
- g_list_remove(player->sink_elements, sink);
-
- debug_fleave();
-}
-
-gboolean
-__is_rtsp_streaming ( mm_player_t* player )
-{
- return_val_if_fail ( player, FALSE );
-
- return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP ) ? TRUE : FALSE;
-}
-
-gboolean
-__is_http_streaming ( mm_player_t* player )
-{
- return_val_if_fail ( player, FALSE );
-
- return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_HTTP ) ? TRUE : FALSE;
-}
-
-gboolean
-__is_streaming ( mm_player_t* player )
-{
- return_val_if_fail ( player, FALSE );
-
- return ( __is_rtsp_streaming ( player ) || __is_http_streaming ( player ) || __is_http_live_streaming ( player )) ? TRUE : FALSE;
-}
-
-gboolean
-__is_live_streaming ( mm_player_t* player )
-{
- return_val_if_fail ( player, FALSE );
-
- return ( __is_rtsp_streaming ( player ) && player->streaming_type == STREAMING_SERVICE_LIVE ) ? TRUE : FALSE;
-}
-
-gboolean
-__is_http_live_streaming( mm_player_t* player )
-{
- return_val_if_fail( player, FALSE );
-
- return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS ) ? TRUE : FALSE;
-}
-
-gboolean
-__is_http_progressive_down(mm_player_t* player)
-{
- return_val_if_fail( player, FALSE );
-
- return ((player->pd_mode) ? TRUE:FALSE);
-}
-