+ return TRUE;
+}
+
+void *_mmcamcorder_util_task_thread_func(void *data)
+{
+ int ret = MM_ERROR_NONE;
+ mmf_camcorder_t *hcamcorder = (mmf_camcorder_t *)data;
+
+ if (!hcamcorder) {
+ _mmcam_dbg_err("handle is NULL");
+ return NULL;
+ }
+
+ _mmcam_dbg_warn("start thread");
+
+ g_mutex_lock(&hcamcorder->task_thread_lock);
+
+ while (hcamcorder->task_thread_state != _MMCAMCORDER_TASK_THREAD_STATE_EXIT) {
+ switch (hcamcorder->task_thread_state) {
+ case _MMCAMCORDER_TASK_THREAD_STATE_NONE:
+ _mmcam_dbg_warn("wait for task signal");
+ g_cond_wait(&hcamcorder->task_thread_cond, &hcamcorder->task_thread_lock);
+ _mmcam_dbg_warn("task signal received : state %d", hcamcorder->task_thread_state);
+ break;
+ case _MMCAMCORDER_TASK_THREAD_STATE_SOUND_PLAY_START:
+ _mmcamcorder_sound_play((MMHandleType)hcamcorder, _MMCAMCORDER_SAMPLE_SOUND_NAME_CAPTURE02, FALSE);
+ hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_NONE;
+ break;
+ case _MMCAMCORDER_TASK_THREAD_STATE_SOUND_SOLO_PLAY_START:
+ _mmcamcorder_sound_solo_play((MMHandleType)hcamcorder, _MMCAMCORDER_SAMPLE_SOUND_NAME_CAPTURE01, FALSE);
+ hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_NONE;
+ break;
+ case _MMCAMCORDER_TASK_THREAD_STATE_ENCODE_PIPE_CREATE:
+ ret = _mmcamcorder_video_prepare_record((MMHandleType)hcamcorder);
+
+ /* Play record start sound */
+ _mmcamcorder_sound_solo_play((MMHandleType)hcamcorder, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_START, FALSE);
+
+ _mmcam_dbg_log("_mmcamcorder_video_prepare_record return 0x%x", ret);
+ hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_NONE;
+ break;
+ case _MMCAMCORDER_TASK_THREAD_STATE_CHECK_CAPTURE_IN_RECORDING:
+ {
+ gint64 end_time = 0;
+
+ _mmcam_dbg_warn("wait for capture data in recording. wait signal...");
+
+ end_time = g_get_monotonic_time() + (5 * G_TIME_SPAN_SECOND);
+
+ if (g_cond_wait_until(&hcamcorder->task_thread_cond, &hcamcorder->task_thread_lock, end_time)) {
+ _mmcam_dbg_warn("signal received");
+ } else {
+ _MMCamcorderMsgItem message;
+
+ memset(&message, 0x0, sizeof(_MMCamcorderMsgItem));
+
+ _mmcam_dbg_err("capture data wait time out, send error message");
+
+ message.id = MM_MESSAGE_CAMCORDER_ERROR;
+ message.param.code = MM_ERROR_CAMCORDER_RESPONSE_TIMEOUT;
+
+ _mmcamcorder_send_message((MMHandleType)hcamcorder, &message);
+
+ hcamcorder->capture_in_recording = FALSE;
+ }
+
+ hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_NONE;
+ }
+ break;
+ default:
+ _mmcam_dbg_warn("invalid task thread state %d", hcamcorder->task_thread_state);
+ hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_EXIT;
+ break;
+ }
+ }
+
+ g_mutex_unlock(&hcamcorder->task_thread_lock);
+
+ _mmcam_dbg_warn("exit thread");
+
+ return NULL;
+}
+
+#ifdef _USE_YUV_TO_RGB888_
+static gboolean
+_mmcamcorder_convert_YUV_to_RGB888(unsigned char *src, int src_fmt, guint width, guint height, unsigned char **dst, unsigned int *dst_len)
+{
+ int ret = 0;
+ int src_cs = MM_UTIL_IMG_FMT_UYVY;
+ int dst_cs = MM_UTIL_IMG_FMT_RGB888;
+ unsigned int dst_size = 0;
+
+ if (src_fmt == COLOR_FORMAT_YUYV) {
+ _mmcam_dbg_log("Convert YUYV to RGB888\n");
+ src_cs = MM_UTIL_IMG_FMT_YUYV;
+ } else if (src_fmt == COLOR_FORMAT_UYVY) {
+ _mmcam_dbg_log("Convert UYVY to RGB888\n");
+ src_cs = MM_UTIL_IMG_FMT_UYVY;
+ } else if (src_fmt == COLOR_FORMAT_NV12) {
+ _mmcam_dbg_log("Convert NV12 to RGB888\n");
+ src_cs = MM_UTIL_IMG_FMT_NV12;
+ } else {
+ _mmcam_dbg_err("NOT supported format [%d]\n", src_fmt);
+ return FALSE;
+ }
+
+ ret = mm_util_get_image_size(dst_cs, width, height, &dst_size);
+ if (ret != 0) {
+ _mmcam_dbg_err("mm_util_get_image_size failed [%x]\n", ret);
+ return FALSE;
+ }
+
+ *dst = malloc(dst_size);
+ if (*dst == NULL) {
+ _mmcam_dbg_err("malloc failed\n");
+ return FALSE;
+ }
+
+ *dst_len = dst_size;
+ ret = mm_util_convert_colorspace(src, width, height, src_cs, *dst, dst_cs);
+ if (ret == 0) {
+ _mmcam_dbg_log("Convert [dst_size:%d] OK.\n", dst_size);
+ return TRUE;
+ } else {
+ free(*dst);
+ *dst = NULL;
+
+ _mmcam_dbg_err("Convert [size:%d] FAILED.\n", dst_size);
+ return FALSE;
+ }
+}
+#endif /* _USE_YUV_TO_RGB888_ */
+
+
+static gboolean _mmcamcorder_convert_YUYV_to_I420(unsigned char *src, guint width, guint height, unsigned char **dst, unsigned int *dst_len)
+{
+ unsigned int i = 0;
+ int j = 0;
+ int src_offset = 0;
+ int dst_y_offset = 0;
+ int dst_u_offset = 0;
+ int dst_v_offset = 0;
+ int loop_length = 0;
+ unsigned int dst_size = 0;
+ unsigned char *dst_data = NULL;
+
+ if (!src || !dst || !dst_len) {
+ _mmcam_dbg_err("NULL pointer %p, %p, %p", src, dst, dst_len);
+ return FALSE;
+ }
+
+ dst_size = (width * height * 3) >> 1;
+
+ _mmcam_dbg_log("YUVY -> I420 : %dx%d, dst size %d", width, height, dst_size);
+
+ dst_data = (unsigned char *)malloc(dst_size);
+ if (!dst_data) {
+ _mmcam_dbg_err("failed to alloc dst_data. size %d", dst_size);
+ return FALSE;
+ }
+
+ loop_length = width << 1;
+ dst_u_offset = width * height;
+ dst_v_offset = dst_u_offset + (dst_u_offset >> 2);
+
+ _mmcam_dbg_log("offset y %d, u %d, v %d", dst_y_offset, dst_u_offset, dst_v_offset);
+
+ for (i = 0 ; i < height ; i++) {
+ for (j = 0 ; j < loop_length ; j += 2) {
+ dst_data[dst_y_offset++] = src[src_offset++]; /*Y*/
+
+ if (i % 2 == 0) {
+ if (j % 4 == 0)
+ dst_data[dst_u_offset++] = src[src_offset++]; /*U*/
+ else
+ dst_data[dst_v_offset++] = src[src_offset++]; /*V*/
+ } else {
+ src_offset++;
+ }
+ }
+ }
+
+ *dst = dst_data;
+ *dst_len = dst_size;
+
+ _mmcam_dbg_log("DONE: YUVY -> I420 : %dx%d, dst data %p, size %d", width, height, *dst, dst_size);
+
+ return TRUE;
+}
+
+
+static gboolean _mmcamcorder_convert_UYVY_to_I420(unsigned char *src, guint width, guint height, unsigned char **dst, unsigned int *dst_len)
+{
+ unsigned int i = 0;
+ int j = 0;
+ int src_offset = 0;
+ int dst_y_offset = 0;
+ int dst_u_offset = 0;
+ int dst_v_offset = 0;
+ int loop_length = 0;
+ unsigned int dst_size = 0;
+ unsigned char *dst_data = NULL;
+
+ if (!src || !dst || !dst_len) {
+ _mmcam_dbg_err("NULL pointer %p, %p, %p", src, dst, dst_len);
+ return FALSE;
+ }
+
+ dst_size = (width * height * 3) >> 1;
+
+ _mmcam_dbg_log("UYVY -> I420 : %dx%d, dst size %d", width, height, dst_size);
+
+ dst_data = (unsigned char *)malloc(dst_size);
+ if (!dst_data) {
+ _mmcam_dbg_err("failed to alloc dst_data. size %d", dst_size);
+ return FALSE;
+ }
+
+ loop_length = width << 1;
+ dst_u_offset = width * height;
+ dst_v_offset = dst_u_offset + (dst_u_offset >> 2);
+
+ _mmcam_dbg_log("offset y %d, u %d, v %d", dst_y_offset, dst_u_offset, dst_v_offset);
+
+ for (i = 0 ; i < height ; i++) {
+ for (j = 0 ; j < loop_length ; j += 2) {
+ if (i % 2 == 0) {
+ if (j % 4 == 0)
+ dst_data[dst_u_offset++] = src[src_offset++]; /*U*/
+ else
+ dst_data[dst_v_offset++] = src[src_offset++]; /*V*/
+ } else {
+ src_offset++;
+ }
+
+ dst_data[dst_y_offset++] = src[src_offset++]; /*Y*/
+ }
+ }
+
+ *dst = dst_data;
+ *dst_len = dst_size;
+
+ _mmcam_dbg_log("DONE: UYVY -> I420 : %dx%d, dst data %p, size %d", width, height, *dst, dst_size);
+
+ return TRUE;
+}
+
+
+static gboolean _mmcamcorder_convert_NV12_to_I420(unsigned char *src, guint width, guint height, unsigned char **dst, unsigned int *dst_len)
+{
+ int i = 0;
+ int src_offset = 0;
+ int dst_y_offset = 0;
+ int dst_u_offset = 0;
+ int dst_v_offset = 0;
+ int loop_length = 0;
+ unsigned int dst_size = 0;
+ unsigned char *dst_data = NULL;
+
+ if (!src || !dst || !dst_len) {
+ _mmcam_dbg_err("NULL pointer %p, %p, %p", src, dst, dst_len);
+ return FALSE;
+ }
+
+ /* buffer overflow prevention check */
+ if (width > __MMCAMCORDER_MAX_WIDTH || height > __MMCAMCORDER_MAX_HEIGHT) {
+ _mmcam_dbg_err("too large size %d x %d", width, height);
+ return FALSE;
+ }
+
+ dst_size = (width * height * 3) >> 1;
+
+ _mmcam_dbg_log("NV12 -> I420 : %dx%d, dst size %d", width, height, dst_size);
+
+ dst_data = (unsigned char *)malloc(dst_size);
+ if (!dst_data) {
+ _mmcam_dbg_err("failed to alloc dst_data. size %d", dst_size);
+ return FALSE;
+ }
+
+ loop_length = width << 1;
+ dst_u_offset = width * height;
+ dst_v_offset = dst_u_offset + (dst_u_offset >> 2);
+
+ _mmcam_dbg_log("offset y %d, u %d, v %d", dst_y_offset, dst_u_offset, dst_v_offset);
+
+ /* memcpy Y */
+ memcpy(dst_data, src, dst_u_offset);
+
+ loop_length = dst_u_offset >> 1;
+ src_offset = dst_u_offset;
+
+ /* set U and V */
+ for (i = 0 ; i < loop_length ; i++) {
+ if (i % 2 == 0)
+ dst_data[dst_u_offset++] = src[src_offset++];
+ else
+ dst_data[dst_v_offset++] = src[src_offset++];
+ }
+
+ *dst = dst_data;
+ *dst_len = dst_size;
+
+ _mmcam_dbg_log("DONE: NV12 -> I420 : %dx%d, dst data %p, size %d", width, height, *dst, dst_size);
+
+ return TRUE;
+}
+
+
+void _mmcamcorder_emit_dbus_signal(GDBusConnection *conn, const char *object_name,
+ const char *interface_name, const char *signal_name, int value)
+{
+ if (!conn || !object_name || !interface_name || !signal_name) {
+ _mmcam_dbg_err("NULL pointer %p %p %p %p",
+ conn, object_name, interface_name, signal_name);
+ return;
+ }
+
+ if (!g_dbus_connection_emit_signal(conn, NULL,
+ object_name, interface_name, signal_name,
+ g_variant_new("(i)", value), NULL)) {
+ _mmcam_dbg_warn("failed to emit signal");
+ } else {
+ _mmcam_dbg_log("emit signal done - value 0x%.8x", value);
+ g_dbus_connection_flush(conn, NULL, NULL, NULL);
+ _mmcam_dbg_log("signal flush done");
+ }
+
+ return;
+}
+
+
+int _mmcamcorder_get_audiosrc_blocksize(int samplerate, int format, int channel, int interval, int *blocksize)
+{
+ int depth = 8;
+
+ if (!blocksize) {
+ _mmcam_dbg_err("NULL ptr");
+ return FALSE;
+ }
+
+ if (samplerate == 0 || channel == 0 || interval == 0) {
+ _mmcam_dbg_err("invalid param %d %d %d", samplerate, channel, interval);
+ return FALSE;
+ }
+
+ if (format == MM_CAMCORDER_AUDIO_FORMAT_PCM_S16_LE)
+ depth = 16;
+
+ *blocksize = samplerate * depth * channel * interval / 8000;
+
+ return TRUE;