X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmm_player_capture.c;h=0297b6ecfb265820e5098d94e314bfb75acb8bab;hb=f7ed1c5dd426e97d2be91f5b53be8c6884a8bfeb;hp=7f8c134044cbe9417514c968382518823a720d61;hpb=e0becfd988ff16f20e0f9c039659d02945b2d279;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git diff --git a/src/mm_player_capture.c b/src/mm_player_capture.c index 7f8c134..0297b6e 100644 --- a/src/mm_player_capture.c +++ b/src/mm_player_capture.c @@ -30,9 +30,11 @@ #include "mm_player_capture.h" #include "mm_player_priv.h" +#include #include #include +//#define CAPTURE_OUTPUT_DUMP 1 /*--------------------------------------------------------------------------- | LOCAL VARIABLE DEFINITIONS for internal | ---------------------------------------------------------------------------*/ @@ -41,11 +43,18 @@ | LOCAL FUNCTION PROTOTYPES: | ---------------------------------------------------------------------------*/ static GstPadProbeReturn __mmplayer_video_capture_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data); -static int __mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstPad *pad, GstBuffer *buffer); +static int __mmplayer_get_video_frame_from_buffer(mmplayer_t *player, GstPad *pad, GstBuffer *buffer); static gpointer __mmplayer_capture_thread(gpointer data); -static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src, int yuv420_width, int yuv420_height, int left, int top, int right, int buttom); +static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src, int yuv420_width, int yuv420_height, int left, int top, int right, int bottom); static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos); -static int __mm_player_convert_colorspace(mm_player_t* player, unsigned char* src_data, mm_util_img_format src_fmt, unsigned int src_w, unsigned int src_h, mm_util_img_format dst_fmt); +static int __mm_player_convert_colorspace(mmplayer_t *player, unsigned char *src_data, size_t src_size, mm_util_color_format_e src_fmt, unsigned int src_w, unsigned int src_h, mm_util_color_format_e dst_fmt); +static int __mm_player_convert_NV12_tiled(mmplayer_t *player); +static int __mm_player_convert_NV12(mmplayer_t *player); +static int __mm_player_convert_I420(mmplayer_t *player); +static int __mm_player_convert_BGRx(mmplayer_t *player); +#ifdef CAPTURE_OUTPUT_DUMP +static void capture_output_dump(mmplayer_t *player); +#endif /*=========================================================================================== | | @@ -53,7 +62,7 @@ static int __mm_player_convert_colorspace(mm_player_t* player, unsigned char* sr | | ========================================================================================== */ int -_mmplayer_initialize_video_capture(mm_player_t* player) +_mmplayer_initialize_video_capture(mmplayer_t *player) { int ret = MM_ERROR_NONE; MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED); @@ -63,7 +72,6 @@ _mmplayer_initialize_video_capture(mm_player_t* player) /* create capture cond */ g_cond_init(&player->capture_thread_cond); - player->capture_thread_exit = FALSE; /* create video capture thread */ @@ -80,14 +88,12 @@ _mmplayer_initialize_video_capture(mm_player_t* player) ERROR: /* capture thread */ g_mutex_clear(&player->capture_thread_mutex); - g_cond_clear(&player->capture_thread_cond); - return ret; } int -_mmplayer_release_video_capture(mm_player_t* player) +_mmplayer_release_video_capture(mmplayer_t *player) { MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED); /* release capture thread */ @@ -96,7 +102,7 @@ _mmplayer_release_video_capture(mm_player_t* player) MMPLAYER_CAPTURE_THREAD_SIGNAL(player); MMPLAYER_CAPTURE_THREAD_UNLOCK(player); - LOGD("waitting for capture thread exit"); + LOGD("waiting for capture thread exit"); g_thread_join(player->capture_thread); g_mutex_clear(&player->capture_thread_mutex); g_cond_clear(&player->capture_thread_cond); @@ -108,7 +114,7 @@ _mmplayer_release_video_capture(mm_player_t* player) int _mmplayer_do_video_capture(MMHandleType hplayer) { - mm_player_t* player = (mm_player_t*) hplayer; + mmplayer_t *player = (mmplayer_t *)hplayer; int ret = MM_ERROR_NONE; GstPad *pad = NULL; @@ -127,55 +133,38 @@ _mmplayer_do_video_capture(MMHandleType hplayer) /* check if video pipeline is linked or not */ if (!player->pipeline->videobin) { - if (surface_type == MM_DISPLAY_SURFACE_REMOTE && player->video_fakesink) { - LOGD("it is evas surface type."); - } else { - LOGW("not ready to capture"); - return MM_ERROR_PLAYER_INVALID_STATE; - } + LOGW("not ready to capture"); + return MM_ERROR_PLAYER_INVALID_STATE; } - if (player->pipeline->videobin) - pad = gst_element_get_static_pad(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "sink"); - else // evas surface - pad = gst_element_get_static_pad(player->video_fakesink, "sink"); - - if (player->state != MM_PLAYER_STATE_PLAYING) { - if (player->state == MM_PLAYER_STATE_PAUSED) { - // get last buffer from video sink - GstSample *sample = NULL; - - gst_element_get_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, NULL, NULL, 5 * GST_SECOND); //5 seconds - - if (player->pipeline->videobin) - g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "last-sample", &sample, NULL); - else // evas surface - g_object_get(player->video_fakesink, "last-sample", &sample, NULL); - - if (sample) { - GstBuffer *buf = NULL; - buf = gst_sample_get_buffer(sample); - if (buf) { - if (__mmplayer_get_video_frame_from_buffer(player, pad, buf) != MM_ERROR_NONE) - ret = MM_ERROR_PLAYER_INTERNAL; - } else { - LOGW("failed to get video frame"); - } - gst_sample_unref(sample); + pad = gst_element_get_static_pad(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "sink"); + + if (player->state == MM_PLAYER_STATE_PLAYING) { + /* register probe */ + player->video_capture_cb_probe_id = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, + __mmplayer_video_capture_probe, player, NULL); + } else if (player->state == MM_PLAYER_STATE_PAUSED) { + // get last buffer from video sink + GstSample *sample = NULL; + + gst_element_get_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, NULL, NULL, 5 * GST_SECOND); + g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "last-sample", &sample, NULL); + + if (sample) { + GstBuffer *buf = gst_sample_get_buffer(sample); + if (buf) { + if (__mmplayer_get_video_frame_from_buffer(player, pad, buf) != MM_ERROR_NONE) + ret = MM_ERROR_PLAYER_INTERNAL; + } else { + LOGW("failed to get video frame"); } - return ret; - } else { - LOGW("invalid state(%d) to capture", player->state); - gst_object_unref(GST_OBJECT(pad)); - pad = NULL; - return MM_ERROR_PLAYER_INVALID_STATE; + gst_sample_unref(sample); } + } else { + LOGW("invalid state(%d) to capture", player->state); + ret = MM_ERROR_PLAYER_INVALID_STATE; } - /* register probe */ - player->video_capture_cb_probe_id = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, - __mmplayer_video_capture_probe, player, NULL); - gst_object_unref(GST_OBJECT(pad)); pad = NULL; @@ -185,55 +174,28 @@ _mmplayer_do_video_capture(MMHandleType hplayer) } int -__mmplayer_handle_orientation(mm_player_t* player, int orientation, int format) +__mmplayer_handle_orientation(mmplayer_t *player, int orientation, int format) { unsigned char *src_buffer = NULL; int ret = MM_ERROR_NONE; - unsigned char *dst_frame = NULL; - unsigned int dst_width = 0; - unsigned int dst_height = 0; - unsigned int dst_size = 0; - mm_util_img_rotate_type rot_enum = MM_UTIL_ROTATE_NUM; + mm_util_image_h src_image = NULL; + mm_util_image_h dst_image = NULL; + size_t dst_size = 0; + mm_util_rotate_type_e rot_enum = MM_UTIL_ROTATE_NUM; player->capture.orientation = orientation; - if (orientation == 90 || orientation == 270) { - dst_width = player->captured.height[0]; - dst_height = player->captured.width[0]; - LOGD("interchange width & height"); - } else if (orientation == 180) { - dst_width = player->captured.width[0]; - dst_height = player->captured.height[0]; - } else if (orientation == 0) { + if (orientation == 0) { LOGE("no need handle orientation : %d", orientation); player->capture.width = player->captured.width[0]; player->capture.height = player->captured.height[0]; return MM_ERROR_NONE; - } else - LOGE("wrong orientation value..."); - - /* height & width will be interchanged for 90 and 270 orientation */ - ret = mm_util_get_image_size(format, dst_width, dst_height, &dst_size); - if (ret != MM_ERROR_NONE) { - LOGE("failed to get destination frame size"); - return ret; } - LOGD("before rotation : dst_width = %d and dst_height = %d", dst_width, dst_height); - - dst_frame = (unsigned char*) malloc(dst_size); - if (!dst_frame) { - LOGE("failed to allocate memory"); - return MM_ERROR_PLAYER_NO_FREE_SPACE; - } - - src_buffer = (unsigned char*)player->capture.data; + src_buffer = (unsigned char *)player->capture.data; /* convert orientation degree into enum here */ switch (orientation) { - case 0: - rot_enum = MM_UTIL_ROTATE_0; - break; case 90: rot_enum = MM_UTIL_ROTATE_90; break; @@ -250,42 +212,48 @@ __mmplayer_handle_orientation(mm_player_t* player, int orientation, int format) LOGD("source buffer for rotation = %p and rotation = %d", src_buffer, rot_enum); - ret = mm_util_rotate_image(src_buffer, - player->captured.width[0], player->captured.height[0], format, - dst_frame, &dst_width, &dst_height, rot_enum); + ret = mm_image_create_image(player->captured.width[0], player->captured.height[0], format, src_buffer, (size_t)player->capture.size, &src_image); if (ret != MM_ERROR_NONE) { - LOGE("failed to do rotate image"); - free(dst_frame); + LOGE("failed to create image"); return ret; } - LOGD("after rotation same stride: dst_width = %d and dst_height = %d", dst_width, dst_height); + ret = mm_util_rotate_image(src_image, rot_enum, &dst_image); + mm_image_destroy_image(src_image); + if (ret != MM_ERROR_NONE) { + LOGE("failed to rotate image"); + return ret; + } - g_free(src_buffer); + mm_image_debug_image(dst_image, NULL); - player->capture.data = dst_frame; - player->capture.size = dst_size; + ret = mm_image_get_image(dst_image, &player->capture.width, &player->capture.height, NULL, &player->capture.data, &dst_size); + mm_image_destroy_image(dst_image); + if (ret != MM_ERROR_NONE) { + LOGE("failed to get image"); + return ret; + } + + free(src_buffer); + + player->capture.size = (int)dst_size; player->capture.orientation = orientation; - player->capture.width = dst_width; - player->capture.height = dst_height; - player->captured.width[0] = player->captured.stride_width[0] = dst_width; - player->captured.height[0] = player->captured.stride_height[0] = dst_height; + player->captured.width[0] = player->captured.stride_width[0] = player->capture.width; + player->captured.height[0] = player->captured.stride_height[0] = player->capture.height; return ret; } - static gpointer __mmplayer_capture_thread(gpointer data) { - mm_player_t* player = (mm_player_t*) data; + mmplayer_t *player = (mmplayer_t *)data; MMMessageParamType msg = {0, }; - unsigned char * src_buffer = NULL; - unsigned char * linear_y_plane = NULL; - unsigned char * linear_uv_plane = NULL; int orientation = 0; + int display_angle = 0; int ret = 0; + int i; MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL); @@ -305,127 +273,48 @@ __mmplayer_capture_thread(gpointer data) */ if (player->video_cs == MM_PLAYER_COLORSPACE_NV12_TILED) { /* Colorspace conversion : NV12T-> NV12-> RGB888 */ - int ret = 0; - int linear_y_plane_size; - int linear_uv_plane_size; - int width = player->captured.width[0]; - int height = player->captured.height[0]; - - linear_y_plane_size = (width * height); - linear_uv_plane_size = (width * height / 2); - - linear_y_plane = (unsigned char*) g_try_malloc(linear_y_plane_size); - if (linear_y_plane == NULL) { - msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE; - goto ERROR; - } - - linear_uv_plane = (unsigned char*) g_try_malloc(linear_uv_plane_size); - if (linear_uv_plane == NULL) { - msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE; - goto ERROR; - } - /* NV12 tiled to linear */ - __csc_tiled_to_linear_crop(linear_y_plane, - player->captured.data[0], width, height, 0, 0, 0, 0); - __csc_tiled_to_linear_crop(linear_uv_plane, - player->captured.data[1], width, height / 2, 0, 0, 0, 0); - - MMPLAYER_FREEIF(player->captured.data[0]); - MMPLAYER_FREEIF(player->captured.data[1]); - - src_buffer = (unsigned char*) g_try_malloc(linear_y_plane_size+linear_uv_plane_size); - - if (src_buffer == NULL) { - msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE; - goto ERROR; - } - memset(src_buffer, 0x00, linear_y_plane_size+linear_uv_plane_size); - memcpy(src_buffer, linear_y_plane, linear_y_plane_size); - memcpy(src_buffer+linear_y_plane_size, linear_uv_plane, linear_uv_plane_size); - - /* NV12 linear to RGB888 */ - ret = __mm_player_convert_colorspace(player, src_buffer, MM_UTIL_IMG_FMT_NV12, - width, height, MM_UTIL_IMG_FMT_RGB888); - + ret = __mm_player_convert_NV12_tiled(player); if (ret != MM_ERROR_NONE) { - LOGE("failed to convert nv12 linear"); + LOGE("failed to covert NV12T"); + msg.code = ret; goto ERROR; } - /* clean */ - MMPLAYER_FREEIF(src_buffer); - MMPLAYER_FREEIF(linear_y_plane); - MMPLAYER_FREEIF(linear_uv_plane); - } else if (MM_PLAYER_COLORSPACE_NV12 == player->video_cs) { - #define MM_ALIGN(x, a) (((x) +(a) - 1) & ~((a) - 1)) - int ret = 0; - /* using original width otherwises, app can't know aligned to resize */ - int width_align = player->captured.width[0]; - int y_size = width_align * player->captured.height[0]; - int uv_size = width_align * player->captured.height[1]; - int src_buffer_size = y_size + uv_size; - int i, j; - unsigned char * temp = NULL; - unsigned char * dst_buf = NULL; - - if (!src_buffer_size) { - LOGE("invalid data size"); + } else if (player->video_cs == MM_PLAYER_COLORSPACE_NV12) { + ret = __mm_player_convert_NV12(player); + if (ret != MM_ERROR_NONE) { + LOGE("failed to covert NV12"); + msg.code = ret; goto ERROR; } - - src_buffer = (unsigned char*) g_try_malloc(src_buffer_size); - - if (!src_buffer) { - msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE; + } else if (player->video_cs == MM_PLAYER_COLORSPACE_I420) { + ret = __mm_player_convert_I420(player); + if (ret != MM_ERROR_NONE) { + LOGE("failed to covert I420"); + msg.code = ret; goto ERROR; } - - memset(src_buffer, 0x00, src_buffer_size); - - temp = player->captured.data[0]; - dst_buf = src_buffer; - - /* set Y plane */ - for (i = 0; i < player->captured.height[0]; i++) { - memcpy(dst_buf, temp, width_align); - dst_buf += width_align; - temp += player->captured.stride_width[0]; - } - - temp = player->captured.data[1]; - - /* set UV plane*/ - for (j = 0; j < player->captured.height[1]; j++) { - memcpy(dst_buf, temp, width_align); - dst_buf += width_align; - temp += player->captured.stride_width[1]; - } - - /* free captured buf */ - MMPLAYER_FREEIF(player->captured.data[0]); - MMPLAYER_FREEIF(player->captured.data[1]); - - /* NV12 -> RGB888 */ - ret = __mm_player_convert_colorspace(player, (unsigned char*)src_buffer, MM_UTIL_IMG_FMT_NV12, - width_align, player->captured.height[0], MM_UTIL_IMG_FMT_RGB888); + } else if (player->video_cs == MM_PLAYER_COLORSPACE_BGRx) { + ret = __mm_player_convert_BGRx(player); if (ret != MM_ERROR_NONE) { - LOGE("failed to convert nv12 linear"); + LOGE("failed to covert BGRx"); + msg.code = ret; goto ERROR; } - - /* clean */ - MMPLAYER_FREEIF(src_buffer); + } else { + LOGE("invalid format"); + msg.code = MM_ERROR_PLAYER_INTERNAL; + goto ERROR; } - ret = _mmplayer_get_video_rotate_angle((MMHandleType)player, &orientation); + ret = _mmplayer_get_video_angle((MMHandleType)player, &display_angle, &orientation); if (ret != MM_ERROR_NONE) { LOGE("failed to get rotation angle"); goto ERROR; } - LOGD("orientation value = %d", orientation); + LOGD("orientation value = %d user_angle = %d", orientation, display_angle); - ret = __mmplayer_handle_orientation(player, orientation, MM_UTIL_IMG_FMT_RGB888); + ret = __mmplayer_handle_orientation(player, orientation, MM_UTIL_COLOR_RGB24); if (ret != MM_ERROR_NONE) { LOGE("failed to convert nv12 linear"); goto ERROR; @@ -434,26 +323,16 @@ __mmplayer_capture_thread(gpointer data) player->capture.fmt = MM_PLAYER_COLORSPACE_RGB888; msg.data = &player->capture; msg.size = player->capture.size; -// msg.captured_frame.width = player->capture.width; -// msg.captured_frame.height = player->capture.height; -// msg.captured_frame.orientation = player->capture.orientation; if (player->cmd >= MMPLAYER_COMMAND_START) { MMPLAYER_POST_MSG(player, MM_MESSAGE_VIDEO_CAPTURED, &msg); LOGD("returned from capture message callback"); } - //MMPLAYER_FREEIF(player->capture.data); continue; ERROR: - MMPLAYER_FREEIF(src_buffer); - MMPLAYER_FREEIF(player->captured.data[0]); - MMPLAYER_FREEIF(player->captured.data[1]); - if (player->video_cs == MM_PLAYER_COLORSPACE_NV12_TILED) { - /* clean */ - MMPLAYER_FREEIF(linear_y_plane); - MMPLAYER_FREEIF(linear_uv_plane); - } + for (i = 0; i < player->captured.plane_num; i++) + MMPLAYER_FREEIF(player->captured.data[i]); msg.union_type = MM_MSG_UNION_CODE; @@ -469,19 +348,15 @@ EXIT: * The output is fixed as RGB888 */ static int -__mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstPad *pad, GstBuffer *buffer) +__mmplayer_get_video_frame_from_buffer(mmplayer_t *player, GstPad *pad, GstBuffer *buffer) { - int ret = MM_ERROR_NONE; - gint yplane_size = 0; - gint uvplane_size = 0; - gint src_width = 0; - gint src_height = 0; + gint i = 0; + guint plane_size = 0; GstCaps *caps = NULL; - GstStructure *structure = NULL; - GstMapInfo mapinfo = GST_MAP_INFO_INIT; - GstMemory *memory = NULL; - mm_util_img_format src_fmt = MM_UTIL_IMG_FMT_YUV420; - mm_util_img_format dst_fmt = MM_UTIL_IMG_FMT_RGB888; // fixed + GstVideoFrame vframe; + GstVideoInfo vinfo; + guint8 *pixels = NULL; + int ret = MM_ERROR_NONE; MMPLAYER_FENTER(); @@ -494,153 +369,77 @@ __mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstPad *pad, GstBuff MMPLAYER_RETURN_VAL_IF_FAIL(caps, MM_ERROR_INVALID_ARGUMENT); MMPLAYER_LOG_GST_CAPS_TYPE(caps); - structure = gst_caps_get_structure(caps, 0); - if (!structure) { - LOGE("cannot get structure from caps.\n"); - ret = MM_ERROR_PLAYER_INTERNAL; - goto ERROR; - } - /* init capture image buffer */ - memset(&player->capture, 0x00, sizeof(MMPlayerVideoCapture)); - - gst_structure_get_int(structure, "width", &src_width); - gst_structure_get_int(structure, "height", &src_height); - - /* check rgb or yuv */ - if (gst_structure_has_name(structure, "video/x-raw")) { - /* NV12T */ - const gchar *gst_format = gst_structure_get_string(structure, "format"); - if (!g_strcmp0(gst_format, "ST12") || !g_strcmp0(gst_format, "SN12")) { - guint n; - LOGI("captured format is %s\n", gst_format); - - MMVideoBuffer *proved = NULL; - if (!g_strcmp0(gst_format, "ST12")) - player->video_cs = MM_PLAYER_COLORSPACE_NV12_TILED; - else - player->video_cs = MM_PLAYER_COLORSPACE_NV12; - - /* get video frame info from proved buffer */ - n = gst_buffer_n_memory(buffer); - memory = gst_buffer_peek_memory(buffer, n-1); - gst_memory_map(memory, &mapinfo, GST_MAP_READ); - proved = (MMVideoBuffer *)mapinfo.data; - - if (!proved || !proved->data[0] || !proved->data[1]) { - LOGE("fail to gst_memory_map"); - ret = MM_ERROR_PLAYER_INTERNAL; - goto ERROR; - } + memset(&player->capture, 0x00, sizeof(mmplayer_video_capture_t)); - memcpy(&player->captured, proved, sizeof(MMVideoBuffer)); + gst_video_info_from_caps(&vinfo, caps); - yplane_size = proved->size[0]; - uvplane_size = proved->size[1]; - LOGI("yplane_size=%d, uvplane_size=%d", yplane_size, uvplane_size); + gst_caps_unref(caps); - player->captured.data[0] = g_try_malloc(yplane_size); - if (!player->captured.data[0]) { - gst_memory_unmap(memory, &mapinfo); - LOGE("no free space\n"); - ret = MM_ERROR_PLAYER_NO_FREE_SPACE; - goto ERROR; - } + LOGI("captured format is %s", gst_video_format_to_string(GST_VIDEO_INFO_FORMAT(&vinfo))); -/* FIXME */ -#if 0 - player->captured.data[1] = g_try_malloc(uvplane_size); -#else - if (uvplane_size < proved->stride_width[1] * proved->stride_height[1]) { - player->captured.data[1] = - g_try_malloc(proved->stride_width[1] * proved->stride_height[1]); - uvplane_size = proved->stride_width[1] * proved->stride_height[1]; - } else { - player->captured.data[1] = g_try_malloc(uvplane_size); - } -#endif - if (!player->captured.data[1]) { - LOGE("no free space\n"); - MMPLAYER_FREEIF(player->captured.data[0]); - gst_memory_unmap(memory, &mapinfo); - ret = MM_ERROR_PLAYER_NO_FREE_SPACE; - goto ERROR; - } + player->captured.width[0] = GST_VIDEO_INFO_WIDTH(&vinfo); + player->captured.height[0] = GST_VIDEO_INFO_HEIGHT(&vinfo); - LOGD("Buffer type %d", proved->type); - if (proved->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) { - tbm_bo_ref(proved->handle.bo[0]); - tbm_bo_ref(proved->handle.bo[1]); - LOGD("source y : %p, size %d", proved->data[0], yplane_size); - if (proved->data[0]) - memcpy(player->captured.data[0], proved->data[0], yplane_size); - - LOGD("source uv : %p, size %d", proved->data[1], uvplane_size); - if (proved->data[1]) - memcpy(player->captured.data[1], proved->data[1], uvplane_size); + switch (GST_VIDEO_INFO_FORMAT(&vinfo)) { + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_SN12: + player->video_cs = MM_PLAYER_COLORSPACE_NV12; + player->captured.width[1] = player->captured.width[0]; + player->captured.height[1] = player->captured.height[0] >> 1; + break; + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_S420: + player->video_cs = MM_PLAYER_COLORSPACE_I420; + player->captured.width[1] = player->captured.width[2] = player->captured.width[0] >> 1; + player->captured.height[1] = player->captured.height[2] = player->captured.height[0] >> 1; + break; + case GST_VIDEO_FORMAT_ST12: + player->video_cs = MM_PLAYER_COLORSPACE_NV12_TILED; + player->captured.width[1] = player->captured.width[0]; + player->captured.height[1] = player->captured.height[0] >> 1; + break; + case GST_VIDEO_FORMAT_BGRx: + player->video_cs = MM_PLAYER_COLORSPACE_BGRx; + break; + default: + player->video_cs = MM_PLAYER_COLORSPACE_MAX; + ret = MM_ERROR_PLAYER_INTERNAL; + break; + } - tbm_bo_unref(proved->handle.bo[0]); - tbm_bo_unref(proved->handle.bo[1]); - } else { - LOGE("Not support video buffer type %d", proved->type); - MMPLAYER_FREEIF(player->captured.data[0]); - MMPLAYER_FREEIF(player->captured.data[1]); - gst_memory_unmap(memory, &mapinfo); - ret = MM_ERROR_PLAYER_INTERNAL; - goto ERROR; - } + if (ret != MM_ERROR_NONE) { + LOGE("unknown format to capture"); + return ret; + } - gst_memory_unmap(memory, &mapinfo); - goto DONE; - } else { - GstVideoInfo format_info; - gst_video_info_from_caps(&format_info, caps); - - switch (GST_VIDEO_INFO_FORMAT(&format_info)) { - case GST_VIDEO_FORMAT_I420: - src_fmt = MM_UTIL_IMG_FMT_I420; - break; - case GST_VIDEO_FORMAT_BGRA: - src_fmt = MM_UTIL_IMG_FMT_BGRA8888; - break; - case GST_VIDEO_FORMAT_BGRx: - src_fmt = MM_UTIL_IMG_FMT_BGRX8888; - break; - default: - LOGE("unknown format to capture\n"); - ret = MM_ERROR_PLAYER_INTERNAL; - goto ERROR; - break; + if (gst_video_frame_map(&vframe, &vinfo, buffer, GST_MAP_READ)) { + for (i = 0; i < GST_VIDEO_FRAME_N_PLANES(&vframe); i++) { + player->captured.stride_width[i] = GST_VIDEO_FRAME_PLANE_STRIDE(&vframe, i); + player->captured.stride_height[i] = player->captured.height[i]; + plane_size = player->captured.stride_width[i] * player->captured.stride_height[i]; + if (!plane_size) { + LOGE("invalid plane size"); + gst_video_frame_unmap(&vframe); + return MM_ERROR_PLAYER_INTERNAL; } + pixels = GST_VIDEO_FRAME_PLANE_DATA(&vframe, i); + player->captured.data[i] = g_malloc(plane_size); + memcpy(player->captured.data[i], pixels, plane_size); } - } else { - LOGE("unknown format to capture\n"); - ret = MM_ERROR_PLAYER_INTERNAL; - goto ERROR; + player->captured.plane_num = GST_VIDEO_FRAME_N_PLANES(&vframe); + gst_video_frame_unmap(&vframe); } - - gst_buffer_map(buffer, &mapinfo, GST_MAP_READ); - __mm_player_convert_colorspace(player, mapinfo.data, src_fmt, src_width, src_height, dst_fmt); - gst_buffer_unmap(buffer, &mapinfo); - -DONE: /* do convert colorspace */ MMPLAYER_CAPTURE_THREAD_SIGNAL(player); -ERROR: - if (caps) { - gst_caps_unref(caps); - caps = NULL; - } - - MMPLAYER_FLEAVE(); return ret; } static GstPadProbeReturn __mmplayer_video_capture_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) { - mm_player_t* player = (mm_player_t*) u_data; + mmplayer_t *player = (mmplayer_t *)u_data; GstBuffer *buffer = NULL; int ret = MM_ERROR_NONE; @@ -649,7 +448,6 @@ __mmplayer_video_capture_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_da buffer = gst_pad_probe_info_get_buffer(info); ret = __mmplayer_get_video_frame_from_buffer(player, pad, buffer); - if (ret != MM_ERROR_NONE) { LOGE("failed to get video frame"); return GST_PAD_PROBE_REMOVE; @@ -667,40 +465,38 @@ __mmplayer_video_capture_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_da } static int -__mm_player_convert_colorspace(mm_player_t* player, unsigned char* src_data, mm_util_img_format src_fmt, unsigned int src_w, unsigned int src_h, mm_util_img_format dst_fmt) +__mm_player_convert_colorspace(mmplayer_t *player, unsigned char *src_data, size_t src_size, mm_util_color_format_e src_fmt, unsigned int src_w, unsigned int src_h, mm_util_color_format_e dst_fmt) { - unsigned char *dst_data = NULL; - unsigned int dst_size; int ret = MM_ERROR_NONE; + mm_util_image_h src_image = NULL; + mm_util_image_h dst_image = NULL; + size_t size = 0; MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_INTERNAL); - ret = mm_util_get_image_size(dst_fmt, src_w, src_h, &dst_size); + SECURE_LOGD("src size info. width: %d, height: %d", src_w, src_h); + ret = mm_image_create_image(src_w, src_h, src_fmt, src_data, src_size, &src_image); if (ret != MM_ERROR_NONE) { - LOGE("failed to get image size for capture, %d\n", ret); + LOGE("failed to create image for capture, %d", ret); return MM_ERROR_PLAYER_INTERNAL; } - SECURE_LOGD("width: %d, height: %d to capture, dest size: %d\n", src_w, src_h, dst_size); - - dst_data = (unsigned char*)g_malloc0(dst_size); - - if (!dst_data) { - LOGE("no free space to capture\n"); - g_free(dst_data); - return MM_ERROR_PLAYER_NO_FREE_SPACE; + ret = mm_util_convert_colorspace(src_image, dst_fmt, &dst_image); + mm_image_destroy_image(src_image); + if (ret != MM_ERROR_NONE) { + LOGE("failed to convert for capture, %d", ret); + return MM_ERROR_PLAYER_INTERNAL; } + mm_image_debug_image(dst_image, NULL); - ret = mm_util_convert_colorspace(src_data, src_w, src_h, src_fmt, dst_data, dst_fmt); - + ret = mm_image_get_image(dst_image, NULL, NULL, NULL, &player->capture.data, &size); + mm_image_destroy_image(dst_image); if (ret != MM_ERROR_NONE) { - LOGE("failed to convert for capture, %d\n", ret); - g_free(dst_data); + LOGE("failed to get image for capture, %d", ret); return MM_ERROR_PLAYER_INTERNAL; } - player->capture.size = dst_size; - player->capture.data = dst_data; + player->capture.size = (int)size; return MM_ERROR_NONE; } @@ -715,10 +511,10 @@ __mm_player_convert_colorspace(mm_player_t* player, unsigned char* src_data, mm_ * height of tiled[in] * * @param x_pos - * x position of tield[in] + * x position of tiled[in] * * @param src_size - * y position of tield[in] + * y position of tiled[in] * * @return * address of tiled data @@ -742,7 +538,7 @@ __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) if ((y_size <= y_pos+32) && (y_pos < y_size) && (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) { linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf)); - linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x +((x_addr >> 6) & 0x3f)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f)); if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) bank_addr = ((x_addr >> 4) & 0x1); @@ -750,7 +546,7 @@ __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) bank_addr = 0x2 | ((x_addr >> 4) & 0x1); } else { linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf)); - linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x +((x_addr >> 5) & 0x7f)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f)); if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) bank_addr = ((x_addr >> 4) & 0x1); @@ -766,7 +562,7 @@ __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) /* * Converts tiled data to linear - * Crops left, top, right, buttom + * Crops left, top, right, bottom * 1. Y of NV12T to Y of YUV420P * 2. Y of NV12T to Y of YUV420S * 3. UV of NV12T to UV of YUV420S @@ -792,12 +588,12 @@ __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) * @param right * Crop size of right * - * @param buttom - * Crop size of buttom + * @param bottom + * Crop size of bottom */ static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src, int yuv420_width, int yuv420_height, - int left, int top, int right, int buttom) + int left, int top, int right, int bottom) { int i, j; int tiled_offset = 0, tiled_offset1 = 0; @@ -808,149 +604,383 @@ __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src, temp1 = temp3-left; /* real width is greater than or equal 256 */ if (temp1 >= 256) { - for (i = top; i < yuv420_height-buttom; i = i+1) { + for (i = top; i < yuv420_height-bottom; i = i+1) { j = left; - temp3 = (j>>8)<<8; - temp3 = temp3>>6; - temp4 = i>>5; + temp3 = (j >> 8) << 8; + temp3 = temp3 >> 6; + temp4 = i >> 5; if (temp4 & 0x1) { - /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ - tiled_offset = temp4-1; - temp1 = ((yuv420_width+127)>>7)<<7; - tiled_offset = tiled_offset*(temp1>>6); - tiled_offset = tiled_offset+temp3; - tiled_offset = tiled_offset+2; - temp1 = (temp3>>2)<<2; - tiled_offset = tiled_offset+temp1; - tiled_offset = tiled_offset<<11; - tiled_offset1 = tiled_offset+2048*2; + /* odd formula: 2 + x + (x >> 2) << 2 + x_block_num * (y - 1) */ + tiled_offset = temp4 - 1; + temp1 = ((yuv420_width + 127) >> 7) << 7; + tiled_offset = tiled_offset * (temp1 >> 6); + tiled_offset = tiled_offset + temp3; + tiled_offset = tiled_offset + 2; + temp1 = (temp3 >> 2) << 2; + tiled_offset = tiled_offset + temp1; + tiled_offset = tiled_offset << 11; + tiled_offset1 = tiled_offset + 2048 * 2; temp4 = 8; } else { - temp2 = ((yuv420_height+31)>>5)<<5; - if ((i+32) < temp2) { - /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ - temp1 = temp3+2; - temp1 = (temp1>>2)<<2; - tiled_offset = temp3+temp1; - temp1 = ((yuv420_width+127)>>7)<<7; - tiled_offset = tiled_offset+temp4*(temp1>>6); - tiled_offset = tiled_offset<<11; - tiled_offset1 = tiled_offset+2048*6; + temp2 = ((yuv420_height+31) >> 5) << 5; + if ((i + 32) < temp2) { + /* even1 formula: x + ((x + 2) >> 2) << 2 + x_block_num * y */ + temp1 = temp3 + 2; + temp1 = (temp1 >> 2) << 2; + tiled_offset = temp3 + temp1; + temp1 = ((yuv420_width + 127) >> 7) << 7; + tiled_offset = tiled_offset + temp4 * (temp1 >> 6); + tiled_offset = tiled_offset << 11; + tiled_offset1 = tiled_offset + 2048 * 6; temp4 = 8; } else { - /* even2 fomula: x+x_block_num*y */ - temp1 = ((yuv420_width+127)>>7)<<7; - tiled_offset = temp4*(temp1>>6); - tiled_offset = tiled_offset+temp3; - tiled_offset = tiled_offset<<11; - tiled_offset1 = tiled_offset+2048*2; + /* even2 formula: x + x_block_num * y */ + temp1 = ((yuv420_width + 127) >> 7) << 7; + tiled_offset = temp4 * (temp1 >> 6); + tiled_offset = tiled_offset + temp3; + tiled_offset = tiled_offset << 11; + tiled_offset1 = tiled_offset + 2048 * 2; temp4 = 4; } } - temp1 = i&0x1F; - tiled_offset = tiled_offset+64*(temp1); - tiled_offset1 = tiled_offset1+64*(temp1); - temp2 = yuv420_width-left-right; - linear_offset = temp2*(i-top); - temp3 = ((j+256)>>8)<<8; - temp3 = temp3-j; - temp1 = left&0x3F; + temp1 = i & 0x1F; + tiled_offset = tiled_offset + 64 * temp1; + tiled_offset1 = tiled_offset1 + 64 * temp1; + temp2 = yuv420_width - left - right; + linear_offset = temp2 * (i - top); + temp3 = ((j + 256) >> 8) << 8; + temp3 = temp3 - j; + temp1 = left & 0x3F; if (temp3 > 192) { - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1); - temp2 = ((left+63)>>6)<<6; - temp3 = ((yuv420_width-right)>>6)<<6; - if (temp2 == temp3) - temp2 = yuv420_width-right-(64-temp1); - memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64); - memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64); - memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64); - linear_offset = linear_offset+256-temp1; + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset + temp1, 64 - temp1); + memcpy(yuv420_dest + linear_offset + 64 - temp1, nv12t_src + tiled_offset + 2048, 64); + memcpy(yuv420_dest + linear_offset + 128 - temp1, nv12t_src + tiled_offset1, 64); + memcpy(yuv420_dest + linear_offset + 192 - temp1, nv12t_src + tiled_offset1 + 2048, 64); + linear_offset = linear_offset + 256 - temp1; } else if (temp3 > 128) { - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1); - memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64); - memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64); - linear_offset = linear_offset+192-temp1; + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset + 2048 + temp1, 64 - temp1); + memcpy(yuv420_dest + linear_offset + 64 - temp1, nv12t_src + tiled_offset1, 64); + memcpy(yuv420_dest + linear_offset + 128 - temp1, nv12t_src + tiled_offset1 + 2048, 64); + linear_offset = linear_offset + 192 - temp1; } else if (temp3 > 64) { - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1); - memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64); - linear_offset = linear_offset+128-temp1; + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset1 + temp1, 64 - temp1); + memcpy(yuv420_dest + linear_offset + 64 - temp1, nv12t_src + tiled_offset1 + 2048, 64); + linear_offset = linear_offset + 128 - temp1; } else if (temp3 > 0) { - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1); - linear_offset = linear_offset+64-temp1; + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset1 + 2048 + temp1, 64 - temp1); + linear_offset = linear_offset + 64 - temp1; } - tiled_offset = tiled_offset+temp4*2048; - j = (left>>8)<<8; + tiled_offset = tiled_offset + temp4 * 2048; + j = (left >> 8) << 8; j = j + 256; - temp2 = yuv420_width-right-256; - for (; j <= temp2; j = j+256) { - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); - tiled_offset1 = tiled_offset1+temp4*2048; - memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64); - memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64); - tiled_offset = tiled_offset+temp4*2048; - memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64); - linear_offset = linear_offset+256; + temp2 = yuv420_width - right - 256; + for (; j <= temp2; j = j + 256) { + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, 64); + tiled_offset1 = tiled_offset1 + temp4 * 2048; + memcpy(yuv420_dest + linear_offset + 64, nv12t_src + tiled_offset + 2048, 64); + memcpy(yuv420_dest + linear_offset + 128, nv12t_src + tiled_offset1, 64); + tiled_offset = tiled_offset + temp4 * 2048; + memcpy(yuv420_dest + linear_offset + 192, nv12t_src + tiled_offset1 + 2048, 64); + linear_offset = linear_offset + 256; } - tiled_offset1 = tiled_offset1+temp4*2048; - temp2 = yuv420_width-right-j; + tiled_offset1 = tiled_offset1 + temp4 * 2048; + temp2 = yuv420_width - right - j; if (temp2 > 192) { - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); - memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64); - memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64); - memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192); + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, 64); + memcpy(yuv420_dest + linear_offset + 64, nv12t_src + tiled_offset + 2048, 64); + memcpy(yuv420_dest + linear_offset + 128, nv12t_src + tiled_offset1, 64); + memcpy(yuv420_dest + linear_offset + 192, nv12t_src + tiled_offset1 + 2048, temp2 - 192); } else if (temp2 > 128) { - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); - memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64); - memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128); + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, 64); + memcpy(yuv420_dest + linear_offset + 64, nv12t_src + tiled_offset + 2048, 64); + memcpy(yuv420_dest + linear_offset + 128, nv12t_src + tiled_offset1, temp2 - 128); } else if (temp2 > 64) { - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); - memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64); - } else - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2); + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, 64); + memcpy(yuv420_dest + linear_offset + 64, nv12t_src + tiled_offset + 2048, temp2 - 64); + } else { + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, temp2); + } } } else if (temp1 >= 64) { - for (i = top; i < (yuv420_height-buttom); i = i+1) { + for (i = top; i < (yuv420_height - bottom); i++) { j = left; tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i); - temp2 = ((j+64)>>6)<<6; - temp2 = temp2-j; - linear_offset = temp1*(i-top); - temp4 = j&0x3; - tiled_offset = tiled_offset+temp4; - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2); - linear_offset = linear_offset+temp2; - j = j+temp2; - if ((j+64) <= temp3) { + temp2 = ((j + 64) >> 6) << 6; + temp2 = temp2 - j; + linear_offset = temp1 * (i - top); + temp4 = j & 0x3; + tiled_offset = tiled_offset + temp4; + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, temp2); + linear_offset = linear_offset + temp2; + j = j + temp2; + if ((j + 64) <= temp3) { tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i); - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); - linear_offset = linear_offset+64; - j = j+64; + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, 64); + linear_offset = linear_offset + 64; + j += 64; } - if ((j+64) <= temp3) { + if ((j + 64) <= temp3) { tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i); - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); - linear_offset = linear_offset+64; - j = j+64; + memcpy(yuv420_dest+linear_offset, nv12t_src + tiled_offset, 64); + linear_offset = linear_offset + 64; + j += 64; } if (j < temp3) { tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i); - temp2 = temp3-j; - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2); + temp2 = temp3 - j; + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, temp2); } } } else { - for (i = top; i < (yuv420_height-buttom); i = i+1) { - linear_offset = temp1*(i-top); - for (j = left; j < (yuv420_width-right); j = j+2) { + for (i = top; i < (yuv420_height - bottom); i++) { + linear_offset = temp1 * (i - top); + for (j = left; j < (yuv420_width - right); j += 2) { tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i); - temp4 = j&0x3; - tiled_offset = tiled_offset+temp4; - memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2); - linear_offset = linear_offset+2; + temp4 = j & 0x3; + tiled_offset = tiled_offset + temp4; + memcpy(yuv420_dest + linear_offset, nv12t_src + tiled_offset, 2); + linear_offset = linear_offset + 2; } } } } + +#ifdef CAPTURE_OUTPUT_DUMP /* for capture output dump */ +static void +capture_output_dump(mmplayer_t *player) +{ + unsigned char *temp = NULL; + char file[100] = { 0, }; + FILE *fp = NULL; + int ret = 0; + int i = 0, j = 0; + + LOGE("capture output dump start. size = %d", player->capture.size); + sprintf(file, "/tmp/dec_output_dump_%dx%d.yuv", player->captured.width[0], player->captured.height[0]); + fp = fopen(file, "ab"); + + for (i = 0; i < player->captured.plane_num; i++) { + temp = player->captured.data[i]; + + for (j = 0; j < player->captured.height[i]; j++) { + ret = fwrite(temp, player->captured.width[i], 1, fp); + temp += player->captured.stride_width[i]; + } + } + LOGE("capture yuv dumped!! ret = %d", ret); + fclose(fp); + + temp = (unsigned char *)player->capture.data; + sprintf(file, "/tmp/dec_output_dump_%dx%d.rgb", player->captured.width[0], player->captured.height[0]); + fp = fopen(file, "ab"); + ret = fwrite(temp, player->capture.size, 1, fp); + fclose(fp); + LOGE("capture rgb dumped!! ret = %d", ret); +} +#endif + +static int +__mm_player_convert_NV12_tiled(mmplayer_t *player) +{ + /* Colorspace conversion : NV12T-> NV12-> RGB888 */ + int i; + int ret = MM_ERROR_NONE; + unsigned char *src_buffer = NULL; + unsigned char *linear_y_plane = NULL; + unsigned char *linear_uv_plane = NULL; + guint linear_y_plane_size; + guint linear_uv_plane_size; + guint width = player->captured.width[0]; + guint height = player->captured.height[0]; + + linear_y_plane_size = width * height; + linear_uv_plane_size = linear_y_plane_size / 2; + + if (!linear_y_plane_size || !linear_uv_plane_size) { + LOGE("invalid plane size"); + return MM_ERROR_PLAYER_INTERNAL; + } + linear_y_plane = (unsigned char *)g_malloc(linear_y_plane_size); + linear_uv_plane = (unsigned char *)g_malloc(linear_uv_plane_size); + + /* NV12 tiled to linear */ + __csc_tiled_to_linear_crop(linear_y_plane, + player->captured.data[0], width, height, 0, 0, 0, 0); + __csc_tiled_to_linear_crop(linear_uv_plane, + player->captured.data[1], width, height / 2, 0, 0, 0, 0); + + src_buffer = (unsigned char *)g_malloc(linear_y_plane_size + linear_uv_plane_size); + + memcpy(src_buffer, linear_y_plane, linear_y_plane_size); + memcpy(src_buffer + linear_y_plane_size, linear_uv_plane, linear_uv_plane_size); + + /* NV12 linear to RGB888 */ + ret = __mm_player_convert_colorspace(player, src_buffer, (size_t)(linear_y_plane_size + linear_uv_plane_size), + MM_UTIL_COLOR_NV12, width, height, MM_UTIL_COLOR_RGB24); + + MMPLAYER_FREEIF(src_buffer); + MMPLAYER_FREEIF(linear_y_plane); + MMPLAYER_FREEIF(linear_uv_plane); + + for (i = 0; i < player->captured.plane_num; i++) + MMPLAYER_FREEIF(player->captured.data[i]); + + return ret; +} + +static int +__mm_player_convert_NV12(mmplayer_t *player) +{ + unsigned char *src_buffer = NULL; + unsigned char *p_buf = NULL; + unsigned char *temp = NULL; + int planes[MAX_BUFFER_PLANE] = {0, }; + int ret = MM_ERROR_NONE; + int i, j; + + /* using original width otherwise, app can't know aligned to resize */ + planes[0] = player->captured.stride_width[0] * player->captured.stride_height[0]; + planes[1] = player->captured.stride_width[1] * player->captured.stride_height[1]; + guint src_buffer_size = planes[0] + planes[1]; + + if (!src_buffer_size) { + LOGE("invalid data size"); + return MM_ERROR_PLAYER_INTERNAL; + } + src_buffer = (unsigned char *)g_malloc(src_buffer_size); + + p_buf = src_buffer; + + temp = player->captured.data[0]; + + /* set Y plane */ + for (i = 0; i < player->captured.height[0]; i++) { + memcpy(p_buf, temp, player->captured.width[0]); + p_buf += player->captured.width[0]; + temp += player->captured.stride_width[0]; + } + + temp = player->captured.data[1]; + + /* set UV plane*/ + for (j = 0; j < player->captured.height[1]; j++) { + memcpy(p_buf, temp, player->captured.width[1]); + p_buf += player->captured.width[1]; + temp += player->captured.stride_width[1]; + } + + /* NV12 -> RGB888 */ + ret = __mm_player_convert_colorspace(player, (unsigned char *)src_buffer, (size_t)src_buffer_size, + MM_UTIL_COLOR_NV12, player->captured.width[0], + player->captured.height[0], MM_UTIL_COLOR_RGB24); + +#ifdef CAPTURE_OUTPUT_DUMP + capture_output_dump(player); +#endif + MMPLAYER_FREEIF(src_buffer); + + for (i = 0; i < player->captured.plane_num; i++) + MMPLAYER_FREEIF(player->captured.data[i]); + + return ret; +} + +static int +__mm_player_convert_I420(mmplayer_t *player) +{ + unsigned char *src_buffer = NULL; + unsigned char *p_buf = NULL; + unsigned char *temp = NULL; + int planes[MAX_BUFFER_PLANE] = {0, }; + int ret = MM_ERROR_NONE; + int i; + + /* using original width otherwise, app can't know aligned to resize */ + planes[0] = player->captured.stride_width[0] * player->captured.stride_height[0]; + planes[1] = planes[2] = (player->captured.stride_width[0] >> 1) + * (player->captured.stride_height[0] >> 1); + + if (!planes[0] || !planes[1] || !planes[2]) { + LOGE("invalid plane size"); + return MM_ERROR_PLAYER_INTERNAL; + } + src_buffer = (unsigned char *)g_malloc(planes[0] + planes[1] + planes[2]); + + /* set Y plane */ + p_buf = src_buffer; + + temp = player->captured.data[0]; + + for (i = 0; i < player->captured.height[0]; i++) { + memcpy(p_buf, temp, player->captured.width[0]); + temp += player->captured.stride_width[0]; + p_buf += player->captured.width[0]; + } + + /* set U plane */ + temp = player->captured.data[1]; + + for (i = 0; i < player->captured.height[1]; i++) { + memcpy(p_buf, temp, player->captured.width[1]); + temp += player->captured.stride_width[1]; + p_buf += player->captured.width[1]; + } + + /* set V plane */ + temp = player->captured.data[2]; + + for (i = 0; i < player->captured.height[2]; i++) { + memcpy(p_buf, temp, player->captured.width[2]); + temp += player->captured.stride_width[2]; + p_buf += player->captured.width[2]; + } + + /* I420 -> RGB888 */ + ret = __mm_player_convert_colorspace(player, (unsigned char *)src_buffer, (size_t)(planes[0] + planes[1] + planes[2]), + MM_UTIL_COLOR_I420, player->captured.width[0], player->captured.height[0], MM_UTIL_COLOR_RGB24); + +#ifdef CAPTURE_OUTPUT_DUMP + capture_output_dump(player); +#endif + MMPLAYER_FREEIF(src_buffer); + + for (i = 0; i < player->captured.plane_num; i++) + MMPLAYER_FREEIF(player->captured.data[i]); + + return ret; +} + +static int +__mm_player_convert_BGRx(mmplayer_t *player) +{ + int i; + guint size; + int ret = MM_ERROR_NONE; + unsigned char *src_buffer = NULL; + + size = (player->captured.stride_width[0] * player->captured.stride_height[0]); + + if (!size) { + LOGE("invalid size"); + return MM_ERROR_PLAYER_INTERNAL; + } + src_buffer = (unsigned char *)g_malloc(size); + memcpy(src_buffer, player->captured.data[0], size); + + /* BGRx -> RGB888 */ + ret = __mm_player_convert_colorspace(player, (unsigned char *)src_buffer, (size_t)size, MM_UTIL_COLOR_BGRX, + player->captured.width[0], player->captured.height[0], MM_UTIL_COLOR_RGB24); + +#ifdef CAPTURE_OUTPUT_DUMP + capture_output_dump(player); +#endif + MMPLAYER_FREEIF(src_buffer); + + for (i = 0; i < player->captured.plane_num; i++) + MMPLAYER_FREEIF(player->captured.data[i]); + + return ret; +}