AC_SUBST(GST_APP_CFLAGS)
AC_SUBST(GST_APP_LIBS)
+PKG_CHECK_MODULES(STORAGE, storage)
+AC_SUBST(STORAGE_CFLAGS)
+AC_SUBST(STORAGE_LIBS)
+
+PKG_CHECK_MODULES(TZPLATFORM_CONFIG, libtzplatform-config)
+AC_SUBST(TZPLATFORM_CONFIG_CFLAGS)
+AC_SUBST(TZPLATFORM_CONFIG_LIBS)
+
PKG_CHECK_MODULES(APPFWK, appcore-efl)
AC_SUBST(APPFWK_CFLAGS)
AC_SUBST(APPFWK_LIBS)
Name: libmm-player
Summary: Multimedia Framework Player Library
-Version: 0.6.35
+Version: 0.6.36
Release: 0
Group: Multimedia/Libraries
License: Apache-2.0
BuildRequires: pkgconfig(capi-media-tool)
BuildRequires: pkgconfig(murphy-resource)
BuildRequires: pkgconfig(murphy-glib)
+BuildRequires: pkgconfig(storage)
+BuildRequires: pkgconfig(libtzplatform-config)
%description
Multimedia Framework Player Library files.
$(MEDIAPACKET_CFLAGS) \
$(DLOG_CFLAGS) \
$(ECORE_CFLAGS) \
+ $(STORAGE_CFLAGS) \
+ $(TZPLATFORM_CONFIG_CFLAGS) \
-Werror -Wno-deprecated -Wno-deprecated-declarations -Wno-cpp
noinst_HEADERS = include/mm_player_utils.h \
$(MEDIAPACKET_LIBS) \
$(DLOG_LIBS) \
$(UTILX_LIBS) \
- $(ECORE_LIBS)
+ $(ECORE_LIBS) \
+ $(STORAGE_LIBS) \
+ $(TZPLATFORM_CONFIG_LIBS)
if IS_SDK
int mm_player_set_sound_stream_info(MMHandleType player, char *stream_type, int stream_index);
/**
+ * This function is to manage the playback according to the external storage state
+ */
+int mm_player_manage_external_storage_state(MMHandleType player, int state);
+
+/**
@}
*/
#include <stdlib.h>
#include <stdio.h>
#include <tbm_bufmgr.h>
+#include <storage.h>
#include "mm_player.h"
#include "mm_player_internal.h"
#include "mm_player_audioeffect.h"
MMPLAYER_STREAMING_ERROR_OPTION_NOT_SUPPORTED,
};
+typedef enum {
+ MMPLAYER_PATH_VOD = 0,
+ MMPLAYER_PATH_TEXT,
+ MMPLAYER_PATH_MAX
+} MMPlayerPathType;
+
/*---------------------------------------------------------------------------
| GLOBAL DATA TYPE DEFINITIONS: |
---------------------------------------------------------------------------*/
} MMPlayerParseProfile;
typedef struct {
+ storage_type_e type;
+ storage_state_e state;
+ int id;
+} MMPlayerStorageInfo;
+
+typedef struct {
bool is_pending;
MMPlayerPosFormatType format;
unsigned long pos;
/* content profile */
MMPlayerParseProfile profile;
+ MMPlayerStorageInfo storage_info[MMPLAYER_PATH_MAX];
/* streaming service type */
MMStreamingType streaming_type;
int _mmplayer_set_pcm_spec(MMHandleType hplayer, int samplerate, int channel);
int _mmplayer_get_timeout(MMHandleType hplayer, int *timeout);
int _mmplayer_get_num_of_video_out_buffers(MMHandleType hplayer, int *num, int *extra_num);
+int _mmplayer_manage_external_storage_state(MMHandleType hplayer, int state);
int __mmplayer_gst_set_state(mm_player_t* player, GstElement * pipeline, GstState state, gboolean async, gint timeout);
int __mmplayer_set_state(mm_player_t* player, int state);
int __mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command);
gboolean __mmplayer_handle_gst_error(mm_player_t* player, GstMessage * message, GError* error);
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_resource_error(mm_player_t* player, int code, GstMessage * message);
gint __gst_handle_stream_error(mm_player_t* player, GError* error, GstMessage * message);
int _mmplayer_sound_register_with_pid(MMHandleType hplayer, int pid);
int _mmplayer_get_client_pid(MMHandleType hplayer, int* pid);
#include <mm_types.h>
#include <mm_error.h>
#include <mm_message.h>
+#include "mm_player_priv.h"
#ifdef __cplusplus
extern "C" {
bool util_check_valid_url(const char *proxy);
const char* util_get_charset(const char *file_path);
int util_get_pixtype(unsigned int fourcc);
+bool util_get_storage_info(const char *path, MMPlayerStorageInfo *storage_info);
#ifdef __cplusplus
}
return result;
}
+
+int mm_player_manage_external_storage_state(MMHandleType player, int state)
+{
+ int result = MM_ERROR_NONE;
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+ MMPLAYER_CMD_LOCK( player );
+
+ result = _mmplayer_manage_external_storage_state(player, state);
+
+ MMPLAYER_CMD_UNLOCK( player );
+
+ return result;
+}
} 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);
+ msg_param.code = __gst_handle_resource_error(player, error->code, message);
} else if (error->domain == GST_STREAM_ERROR) {
msg_param.code = __gst_handle_stream_error(player, error, message);
} else {
if (msg_param.code == MM_ERROR_NONE)
return TRUE;
+ /* skip error to avoid duplicated posting */
+ if ((player->storage_info[MMPLAYER_PATH_VOD].state <= STORAGE_STATE_REMOVED) ||
+ (player->storage_info[MMPLAYER_PATH_TEXT].state <= STORAGE_STATE_REMOVED)) {
+
+ /* The error will be handled by mused.
+ * @ref _mmplayer_manage_external_storage_state() */
+
+ LOGW("storage is removed, skip error post");
+ return TRUE;
+ }
+
/* post error to application */
if (!player->msg_posted) {
MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
}
gint
-__gst_handle_resource_error(mm_player_t* player, int code)
+__gst_handle_resource_error(mm_player_t* player, int code, GstMessage * message)
{
gint trans_err = MM_ERROR_NONE;
|| MMPLAYER_IS_RTSP_STREAMING(player)) {
trans_err = MM_ERROR_PLAYER_STREAMING_FAIL;
break;
- }
+ } else if (message != NULL && message->src != NULL) {
+ storage_state_e storage_state = STORAGE_STATE_UNMOUNTABLE;
+ MMPlayerPathType path_type = MMPLAYER_PATH_MAX;
+
+ if (message->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_SRC].gst)
+ path_type = MMPLAYER_PATH_VOD;
+ else if (message->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_SUBSRC].gst)
+ path_type = MMPLAYER_PATH_TEXT;
+
+ if (path_type != MMPLAYER_PATH_MAX && player->storage_info[path_type].type == STORAGE_TYPE_EXTERNAL) {
+ /* check storage state */
+ storage_get_state(player->storage_info[path_type].id, &storage_state);
+ player->storage_info[path_type].state = storage_state;
+ LOGW("path %d, storage state %d", path_type, storage_state);
+ }
+ } /* fall through */
case GST_RESOURCE_ERROR_WRITE:
case GST_RESOURCE_ERROR_FAILED:
case GST_RESOURCE_ERROR_SEEK:
static void __mmplayer_gst_caps_notify_cb(GstPad * pad, GParamSpec * unused, gpointer data);
static void __mmplayer_audio_stream_clear_buffer(mm_player_t* player, gboolean send_all);
static void __mmplayer_audio_stream_send_data(mm_player_t* player, mm_player_audio_stream_buff_t *a_buffer);
+static void __mmplayer_initialize_storage_info(mm_player_t* player, MMPlayerPathType path_type);
/*===========================================================================================
| |
gst_object_unref(pad);
pad = NULL;
+ if (!util_get_storage_info(subtitle_uri, &player->storage_info[MMPLAYER_PATH_TEXT]))
+ LOGE("failed to get storage info of subtitle path");
+
/* create dot. for debugging */
MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-with-subtitle");
MMPLAYER_FLEAVE();
player->last_multiwin_status = FALSE;
_mmplayer_track_initialize(player);
+ __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
/* create source element */
switch (player->profile.uri_type) {
g_object_get(element, "location", &location, NULL);
LOGD("PD_LOCATION [%s].\n", location);
+ if (!util_get_storage_info(location, &player->storage_info[MMPLAYER_PATH_VOD]))
+ LOGE("failed to get storage info");
if (location)
g_free(location);
}
}
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);
+ if (!util_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD]))
+ LOGE("failed to get storage info");
}
break;
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);
+ ret = __gst_handle_resource_error(player, error->code, NULL);
else if (error->domain == GST_LIBRARY_ERROR)
ret = __gst_handle_library_error(player, error->code);
else if (error->domain == GST_CORE_ERROR)
player->total_maximum_bitrate = 0;
_mmplayer_track_initialize(player);
+ __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) {
player->bitrate[i] = 0;
}
g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL); /* uri+7 -> remove "file:// */
+ if (!util_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD]))
+ LOGE("failed to get storage info");
break;
}
case MM_PLAYER_URI_TYPE_URL_HTTP:
/* clear the video stream bo list */
__mmplayer_video_stream_destroy_bo_list(player);
+ __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
player->uri_info.uri_idx = 0;
MMPLAYER_FLEAVE();
goto EXIT;
}
+ __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_TEXT);
+
g_object_set(G_OBJECT(mainbin[MMPLAYER_M_SUBSRC].gst), "location", filepath, NULL);
+ if (!util_get_storage_info(filepath, &player->storage_info[MMPLAYER_PATH_TEXT]))
+ LOGE("failed to get storage info of subtitle path");
+
charset = util_get_charset(filepath);
if (charset) {
LOGD("detected charset is %s\n", charset);
return MM_ERROR_NONE;
}
+static void
+__mmplayer_initialize_storage_info(mm_player_t* player, MMPlayerPathType path_type)
+{
+ int i = 0;
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_IF_FAIL(player);
+
+ for (i=0; i<MMPLAYER_PATH_MAX; i++) {
+
+ if (path_type == MMPLAYER_PATH_MAX || path_type == i) {
+ player->storage_info[i].type = STORAGE_TYPE_INTERNAL;
+ player->storage_info[i].state = STORAGE_STATE_MOUNTED;
+ player->storage_info[i].id = -1;
+
+ if (path_type != MMPLAYER_PATH_MAX)
+ break;
+ }
+ }
+
+ MMPLAYER_FLEAVE();
+}
+
+int _mmplayer_manage_external_storage_state(MMHandleType hplayer, int state)
+{
+ int ret = MM_ERROR_NONE;
+ mm_player_t* player = (mm_player_t*) hplayer;
+ MMMessageParamType msg_param = {0, };
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+ LOGD("storage state : %d", state);
+
+ if (state != STORAGE_STATE_UNMOUNTABLE && state != STORAGE_STATE_REMOVED)
+ return MM_ERROR_NONE;
+
+ if ((player->storage_info[MMPLAYER_PATH_VOD].type == STORAGE_TYPE_EXTERNAL) ||
+ (player->storage_info[MMPLAYER_PATH_TEXT].type == STORAGE_TYPE_EXTERNAL)) {
+ LOGW("external storage is removed.");
+
+ if (player->msg_posted == FALSE) {
+ memset(&msg_param, 0, sizeof(MMMessageParamType));
+ msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
+ MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
+ player->msg_posted = TRUE;
+ }
+
+ /* unrealize the player */
+ ret = _mmplayer_unrealize(hplayer);
+ if (ret != MM_ERROR_NONE)
+ LOGE("failed to unrealize");
+ }
+
+ MMPLAYER_FLEAVE();
+ return ret;
+}
+
#include <arpa/inet.h>
#include <unicode/ucsdet.h>
#include <dlog.h>
-
+#include <storage.h>
+#include <tzplatform_config.h>
#include "mm_player_utils.h"
+#define MEDIA_PATH_EXTERNAL tzplatform_getenv(TZ_SYS_STORAGE) /* external storage */
+
int util_exist_file_path(const char *file_path)
{
int fd = 0;
return pixtype;
}
+
+static int _util_storage_supported_cb(int storage_id, storage_type_e type,
+ storage_state_e state, const char *path, void *user_data)
+{
+ MMPlayerStorageInfo *storage_info = (MMPlayerStorageInfo *)user_data;
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(storage_info, FALSE);
+
+ if (type == storage_info->type && state >= STORAGE_STATE_MOUNTED) {
+ storage_info->id = storage_id;
+ storage_info->state = state;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bool util_get_storage_info(const char *path, MMPlayerStorageInfo *storage_info)
+{
+ int ret = 0;
+ const char *file_path = path;
+
+ MMPLAYER_RETURN_VAL_IF_FAIL(file_path && storage_info, false);
+
+ if (strncmp(file_path, "file://", strlen("file://")) == 0)
+ file_path = path+7; /* remove file prefix */
+
+ if (strncmp(file_path, MEDIA_PATH_EXTERNAL, strlen(MEDIA_PATH_EXTERNAL)) == 0)
+ storage_info->type = STORAGE_TYPE_EXTERNAL;
+ else
+ storage_info->type = STORAGE_TYPE_INTERNAL;
+
+ ret = storage_foreach_device_supported((storage_device_supported_cb)_util_storage_supported_cb, storage_info);
+ if (ret != STORAGE_ERROR_NONE) {
+ LOGE("storage_foreach_device_supported failed 0x%x", ret);
+ return false;
+ }
+
+ LOGD("storage info: type %d, id %d", storage_info->type, storage_info->id);
+
+ return true;
+}