Name: libmm-camcorder
Summary: Camera and recorder library
-Version: 0.10.66
+Version: 0.10.67
Release: 0
Group: Multimedia/Libraries
License: Apache-2.0
dpm_restriction_policy_h dpm_policy; /**< DPM restriction policy handle */
int dpm_camera_cb_id; /**< DPM camera policy changed callback id */
+ /* Storage */
+ _MMCamcorderStorageInfo storage_info; /**< Storage information */
+
#ifdef _MMCAMCORDER_RM_SUPPORT
rm_category_request_s request_resources;
rm_device_return_s returned_devices;
========================================================================================*/
#include <gio/gio.h>
#include <linux/magic.h>
+#include <storage.h>
#ifdef __cplusplus
GMutex lock; /**< mutex for item */
} _MMCamcorderMsgItem;
+/**
+ * Structure of storage information
+ */
+typedef struct {
+ storage_type_e type;
+ int id;
+} _MMCamcorderStorageInfo;
+
/*=======================================================================================
| CONSTANT DEFINITIONS |
gboolean _mmcamcorder_update_composition_matrix(FILE *f, int orientation);
/* File system */
-int _mmcamcorder_get_freespace(const gchar *path, const gchar *root_directory, guint64 *free_space);
+int _mmcamcorder_get_storage_info(const gchar *path, const gchar *root_directory, _MMCamcorderStorageInfo *storage_info);
+int _mmcamcorder_get_freespace(storage_type_e type, guint64 *free_space);
int _mmcamcorder_get_file_size(const char *filename, guint64 *size);
int _mmcamcorder_get_file_system_type(const gchar *path, int *file_system_type);
/* TODO : check free space before recording start */
dir_name = g_path_get_dirname(info->filename);
if (dir_name) {
- err = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
+ err = _mmcamcorder_get_storage_info(dir_name, hcamcorder->root_directory, &hcamcorder->storage_info);
+ if (err != 0) {
+ _mmcam_dbg_err("get storage info failed");
+ return MM_ERROR_OUT_OF_STORAGE;
+ }
+
+ err = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
_mmcam_dbg_warn("current space - %s [%" G_GUINT64_FORMAT "]", dir_name, free_space);
guint64 free_space = 0;
guint64 buffer_size = 0;
guint64 trailer_size = 0;
- char *filename = NULL;
unsigned long long remained_time = 0;
int get_trailer_size = 0;
trailer_size = 0; /* no trailer */
}
- filename = audioinfo->filename;
-
/* to minimizing free space check overhead */
count = count % _MMCAMCORDER_FREE_SPACE_CHECK_INTERVAL;
if (count++ == 0) {
- char *dir_name = g_path_get_dirname(filename);
gint free_space_ret = 0;
+ storage_state_e storage_state = STORAGE_STATE_UNMOUNTABLE;
- if (dir_name) {
- free_space_ret = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
- g_free(dir_name);
- dir_name = NULL;
- } else {
- _mmcam_dbg_err("failed to get dir name from [%s]", filename);
- free_space_ret = -1;
- }
-
- /*_mmcam_dbg_log("check free space for recording");*/
-
- switch (free_space_ret) {
- case -2: /* file not exist */
- case -1: /* failed to get free space */
+ /* check free space */
+ free_space_ret = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
+ if (free_space_ret != 0) {
_mmcam_dbg_err("Error occured. [%d]", free_space_ret);
if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
sc->ferror_send = TRUE;
+
msg.id = MM_MESSAGE_CAMCORDER_ERROR;
- if (free_space_ret == -2)
- msg.param.code = MM_ERROR_FILE_NOT_FOUND;
- else
- msg.param.code = MM_ERROR_FILE_READ;
+ msg.param.code = MM_ERROR_FILE_READ;
_mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
} else {
}
return GST_PAD_PROBE_DROP; /* skip this buffer */
+ }
+
+ if (free_space == 0) {
+ /* check storage state */
+ storage_get_state(hcamcorder->storage_info.id, &storage_state);
+
+ _mmcam_dbg_warn("storage state %d", storage_state);
+
+ if (storage_state == STORAGE_STATE_REMOVED ||
+ storage_state == STORAGE_STATE_UNMOUNTABLE) {
+ _mmcam_dbg_err("storage was removed!");
- default: /* succeeded to get free space */
- /* check free space for recording */
- if (free_space < (guint64)(_MMCAMCORDER_AUDIO_MINIMUM_SPACE + buffer_size + trailer_size)) {
- _mmcam_dbg_warn("No more space for recording!!!");
- _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], file size : [%" G_GUINT64_FORMAT "]",
- free_space, audioinfo->filesize);
+ _MMCAMCORDER_LOCK(hcamcorder);
- if (audioinfo->bMuxing) {
- MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+ if (sc->ferror_send == FALSE) {
+ _mmcam_dbg_err("OUT_OF_STORAGE error");
+
+ sc->ferror_send = TRUE;
+
+ _MMCAMCORDER_UNLOCK(hcamcorder);
+
+ msg.id = MM_MESSAGE_CAMCORDER_ERROR;
+ msg.param.code = MM_ERROR_OUT_OF_STORAGE;
+
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
} else {
- MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
+ _MMCAMCORDER_UNLOCK(hcamcorder);
+ _mmcam_dbg_warn("error was already sent");
}
- sc->isMaxsizePausing = TRUE;
- msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
- _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+ return GST_PAD_PROBE_DROP;
+ }
+ }
+
+ if (free_space < (guint64)(_MMCAMCORDER_AUDIO_MINIMUM_SPACE + buffer_size + trailer_size)) {
+ _mmcam_dbg_warn("No more space for recording!!!");
+ _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], file size : [%" G_GUINT64_FORMAT "]",
+ free_space, audioinfo->filesize);
- return GST_PAD_PROBE_DROP; /* skip this buffer */
+ if (audioinfo->bMuxing) {
+ MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+ } else {
+ MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_AQUE].gst, "empty-buffers", TRUE);
}
- break;
+
+ sc->isMaxsizePausing = TRUE;
+ msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+
+ return GST_PAD_PROBE_DROP; /* skip this buffer */
}
}
}
} else {
gboolean b_commiting = FALSE;
+ storage_state_e storage_state = STORAGE_STATE_UNMOUNTABLE;
if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
mmf_return_val_if_fail(sc->info_video, GST_BUS_PASS);
switch (err->code) {
case GST_RESOURCE_ERROR_WRITE:
- _mmcam_dbg_err("File write error");
- hcamcorder->error_code = MM_ERROR_FILE_WRITE;
+ storage_get_state(hcamcorder->storage_info.id, &storage_state);
+ if (storage_state == STORAGE_STATE_REMOVED ||
+ storage_state == STORAGE_STATE_UNMOUNTABLE) {
+ _mmcam_dbg_err("storage was removed! [storage state %d]", storage_state);
+ hcamcorder->error_code = MM_ERROR_OUT_OF_STORAGE;
+ } else {
+ _mmcam_dbg_err("File write error, storage state %d", storage_state);
+ hcamcorder->error_code = MM_ERROR_FILE_WRITE;
+ }
+
+ if (sc->ferror_send == FALSE) {
+ sc->ferror_send = TRUE;
+ } else {
+ _mmcam_dbg_err("error was already sent");
+ _MMCAMCORDER_UNLOCK(hcamcorder);
+ goto DROP_MESSAGE;
+ }
break;
case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
_mmcam_dbg_err("No left space");
#include <mm_util_imgp.h>
#include <mm_util_jpeg.h>
-#include <storage.h>
-
/*-----------------------------------------------------------------------
| GLOBAL VARIABLE DEFINITIONS for internal |
-----------------------------------------------------------------------*/
}
-int _mmcamcorder_get_freespace(const gchar *path, const gchar *root_directory, guint64 *free_space)
+static int __mmcamcorder_storage_supported_cb(int storage_id, storage_type_e type,
+ storage_state_e state, const char *path, void *user_data)
{
- int ret = 0;
- struct statvfs vfs;
+ _MMCamcorderStorageInfo *info = (_MMCamcorderStorageInfo *)user_data;
+
+ if (!info) {
+ _mmcam_dbg_err("NULL info");
+ return FALSE;
+ }
+
+ if (type == info->type) {
+ info->id = storage_id;
+ return FALSE;
+ }
- int is_internal = TRUE;
+ return TRUE;
+}
+
+
+int _mmcamcorder_get_storage_info(const gchar *path, const gchar *root_directory, _MMCamcorderStorageInfo *info)
+{
+ int ret = 0;
struct stat stat_path;
struct stat stat_root;
- if (path == NULL || free_space == NULL) {
- _mmcam_dbg_err("invalid parameter %p, %p", path, free_space);
+ if (!path || !root_directory || !info) {
+ _mmcam_dbg_err("invalid parameter %p %p %p", path, root_directory, info);
return -1;
}
- if (root_directory && strlen(root_directory) > 0) {
+ if (strlen(root_directory) > 0) {
if (stat(path, &stat_path) != 0) {
- *free_space = 0;
_mmcam_dbg_err("failed to stat for [%s][errno %d]", path, errno);
return -1;
}
if (stat(root_directory, &stat_root) != 0) {
- *free_space = 0;
_mmcam_dbg_err("failed to stat for [%s][errno %d]", root_directory, errno);
return -1;
}
- if (stat_path.st_dev != stat_root.st_dev)
- is_internal = FALSE;
+ if (stat_path.st_dev == stat_root.st_dev)
+ info->type = STORAGE_TYPE_INTERNAL;
+ else
+ info->type = STORAGE_TYPE_EXTERNAL;
} else {
- _mmcam_dbg_warn("root_directory is NULL, assume that it's internal storage.");
+ info->type = STORAGE_TYPE_INTERNAL;
+ _mmcam_dbg_warn("invalid length of root directory, assume that it's internal storage.");
}
- if (is_internal)
+ ret = storage_foreach_device_supported((storage_device_supported_cb)__mmcamcorder_storage_supported_cb, info);
+ if (ret != STORAGE_ERROR_NONE) {
+ _mmcam_dbg_err("storage_foreach_device_supported failed 0x%x", ret);
+ return -1;
+ }
+
+ _mmcam_dbg_log("storage info - type %d, id %d", info->type, info->id);
+
+ return 0;
+}
+
+
+int _mmcamcorder_get_freespace(storage_type_e type, guint64 *free_space)
+{
+ int ret = 0;
+ struct statvfs vfs;
+
+ if (type == STORAGE_TYPE_INTERNAL)
ret = storage_get_internal_memory_size(&vfs);
else
ret = storage_get_external_memory_size(&vfs);
- if (ret < 0) {
+ if (ret != STORAGE_ERROR_NONE) {
*free_space = 0;
- _mmcam_dbg_err("failed to get memory size [%s]", path);
+ _mmcam_dbg_err("get memory size failed [type %d] 0x%x", type, ret);
return -1;
- } else {
- *free_space = vfs.f_bsize * vfs.f_bavail;
- /*
- _mmcam_dbg_log("vfs.f_bsize [%lu], vfs.f_bavail [%lu]", vfs.f_bsize, vfs.f_bavail);
- _mmcam_dbg_log("memory size %llu [%s]", *free_space, path);
- */
- return 1;
}
+
+ *free_space = vfs.f_bsize * vfs.f_bavail;
+ /*
+ _mmcam_dbg_log("vfs.f_bsize [%lu], vfs.f_bavail [%lu]", vfs.f_bsize, vfs.f_bavail);
+ _mmcam_dbg_log("memory size %llu [%s]", *free_space, path);
+ */
+ return 0;
}
/*_mmcam_dbg_log("msg id:%x, msg_cb:%p, msg_data:%p, item:%p", item->id, hcamcorder->msg_cb, hcamcorder->msg_data, item);*/
- _MMCAMCORDER_LOCK((MMHandleType)hcamcorder);
+ _MMCAMCORDER_LOCK(hcamcorder);
/* remove item from msg data */
if (hcamcorder->msg_data) {
_mmcam_dbg_warn("msg_data is NULL but item[%p] will be removed", item);
}
- _MMCAMCORDER_UNLOCK((MMHandleType)hcamcorder);
+ _MMCAMCORDER_UNLOCK(hcamcorder);
_MMCAMCORDER_LOCK_MESSAGE_CALLBACK(hcamcorder);
dir_name = g_path_get_dirname(temp_filename);
if (dir_name) {
- ret_free_space = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
+ ret = _mmcamcorder_get_storage_info(dir_name, hcamcorder->root_directory, &hcamcorder->storage_info);
+ if (ret != 0) {
+ _mmcam_dbg_err("get storage info failed");
+ return MM_ERROR_OUT_OF_STORAGE;
+ }
+
+ ret_free_space = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
_mmcam_dbg_warn("current space - %s [%" G_GUINT64_FORMAT "]", dir_name, free_space);
guint64 trailer_size = 0;
guint64 queued_buffer = 0;
guint64 max_size = 0;
- char *dir_name = NULL;
GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
GstMapInfo mapinfo;
+ storage_state_e storage_state = STORAGE_STATE_UNMOUNTABLE;
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
_MMCamcorderMsgItem msg;
trailer_size = 0;
}
- dir_name = g_path_get_dirname(videoinfo->filename);
- if (dir_name) {
- ret = _mmcamcorder_get_freespace(dir_name, hcamcorder->root_directory, &free_space);
- g_free(dir_name);
- dir_name = NULL;
- } else {
- _mmcam_dbg_err("failed to get dir name from [%s]", videoinfo->filename);
- ret = -1;
- }
-
- /*_mmcam_dbg_log("check free space for recording");*/
-
- switch (ret) {
- case -2: /* file not exist */
- case -1: /* failed to get free space */
+ /* check free space */
+ ret = _mmcamcorder_get_freespace(hcamcorder->storage_info.type, &free_space);
+ if (ret != 0) {
_mmcam_dbg_err("Error occured. [%d]", ret);
if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
sc->ferror_send = TRUE;
+
msg.id = MM_MESSAGE_CAMCORDER_ERROR;
- if (ret == -2)
- msg.param.code = MM_ERROR_FILE_NOT_FOUND;
- else
- msg.param.code = MM_ERROR_FILE_READ;
+ msg.param.code = MM_ERROR_FILE_READ;
_mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
} else {
}
return GST_PAD_PROBE_DROP; /* skip this buffer */
- break;
- default: /* succeeded to get free space */
- /* check free space for recording */
- /* get queued buffer size */
- if (sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst) {
- MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst, "current-level-bytes", &aq_size);
- }
+ }
- if (sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst) {
- MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst, "current-level-bytes", &vq_size);
- }
+ if (free_space == 0) {
+ /* check storage state */
+ storage_get_state(hcamcorder->storage_info.id, &storage_state);
- queued_buffer = aq_size + vq_size;
+ _mmcam_dbg_warn("storage state %d", storage_state);
- /* check free space */
- if (free_space < (_MMCAMCORDER_MINIMUM_SPACE + buffer_size + trailer_size + queued_buffer)) {
- _mmcam_dbg_warn("No more space for recording!!! Recording is paused.");
- _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], trailer size : [%" G_GUINT64_FORMAT "]," \
- " buffer size : [%" G_GUINT64_FORMAT "], queued buffer size : [%" G_GUINT64_FORMAT "]", \
- free_space, trailer_size, buffer_size, queued_buffer);
+ if (storage_state == STORAGE_STATE_REMOVED ||
+ storage_state == STORAGE_STATE_UNMOUNTABLE) {
+ _mmcam_dbg_err("storage was removed!");
- if (!sc->isMaxsizePausing) {
- MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
- sc->isMaxsizePausing = TRUE;
+ _MMCAMCORDER_LOCK(hcamcorder);
+
+ if (sc->ferror_send == FALSE) {
+ _mmcam_dbg_err("OUT_OF_STORAGE error");
+
+ sc->ferror_send = TRUE;
+
+ _MMCAMCORDER_UNLOCK(hcamcorder);
+
+ msg.id = MM_MESSAGE_CAMCORDER_ERROR;
+ msg.param.code = MM_ERROR_OUT_OF_STORAGE;
- msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
_mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+ } else {
+ _MMCAMCORDER_UNLOCK(hcamcorder);
+ _mmcam_dbg_warn("error was already sent");
}
return GST_PAD_PROBE_DROP;
}
- break;
+ }
+
+ /* get queued buffer size */
+ if (sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst) {
+ MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_AENC_QUE].gst, "current-level-bytes", &aq_size);
+ }
+
+ if (sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst) {
+ MMCAMCORDER_G_OBJECT_GET(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC_QUE].gst, "current-level-bytes", &vq_size);
+ }
+
+ queued_buffer = aq_size + vq_size;
+
+ if (free_space < (_MMCAMCORDER_MINIMUM_SPACE + buffer_size + trailer_size + queued_buffer)) {
+ _mmcam_dbg_warn("No more space for recording!!! Recording is paused.");
+ _mmcam_dbg_warn("Free Space : [%" G_GUINT64_FORMAT "], trailer size : [%" G_GUINT64_FORMAT "]," \
+ " buffer size : [%" G_GUINT64_FORMAT "], queued buffer size : [%" G_GUINT64_FORMAT "]", \
+ free_space, trailer_size, buffer_size, queued_buffer);
+
+ if (!sc->isMaxsizePausing) {
+ MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_ENCBIN].gst, "block", TRUE);
+ sc->isMaxsizePausing = TRUE;
+
+ msg.id = MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
+ }
+
+ return GST_PAD_PROBE_DROP;
}
g_mutex_lock(&videoinfo->size_check_lock);
$(GLIB_CFLAGS)\
$(GST_CFLAGS)\
$(DPM_CFLAGS)\
+ $(STORAGE_CFLAGS)\
$(MM_COMMON_CFLAGS)\
$(MM_SOUND_CFLAGS)
if PRODUCT_TV
mm_camcorder_testsuite_CFLAGS += -D_MMCAMCORDER_PRODUCT_TV
-endif
\ No newline at end of file
+endif
+