X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmm_player_capture.c;h=0297b6ecfb265820e5098d94e314bfb75acb8bab;hb=f7ed1c5dd426e97d2be91f5b53be8c6884a8bfeb;hp=37cdd0ff28dd67725ac44143dcab8e7c7779ca60;hpb=b8e649a1ab3a5453ceaae4d243cb16978d784974;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git diff --git a/src/mm_player_capture.c b/src/mm_player_capture.c old mode 100755 new mode 100644 index 37cdd0f..0297b6e --- a/src/mm_player_capture.c +++ b/src/mm_player_capture.c @@ -30,6 +30,7 @@ #include "mm_player_capture.h" #include "mm_player_priv.h" +#include #include #include @@ -42,16 +43,17 @@ | 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_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(mm_player_t *player); -static int __mm_player_convert_NV12(mm_player_t *player); -static int __mm_player_convert_I420(mm_player_t *player); +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(mm_player_t* player); +static void capture_output_dump(mmplayer_t *player); #endif /*=========================================================================================== @@ -60,7 +62,7 @@ static void capture_output_dump(mm_player_t* player); | | ========================================================================================== */ 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); @@ -70,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 */ @@ -87,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 */ @@ -103,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); @@ -115,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; @@ -134,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; @@ -192,36 +174,25 @@ _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; + mm_util_image_h src_image = NULL; + mm_util_image_h dst_image = NULL; size_t dst_size = 0; - mm_util_img_rotate_type rot_enum = MM_UTIL_ROTATE_NUM; + 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 */ - LOGD("before rotation : dst_width = %d and dst_height = %d", dst_width, dst_height); - src_buffer = (unsigned char*)player->capture.data; + src_buffer = (unsigned char *)player->capture.data; /* convert orientation degree into enum here */ switch (orientation) { @@ -241,36 +212,43 @@ __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, rot_enum, - &dst_frame, &dst_width, &dst_height, &dst_size); - if (ret != MM_ERROR_NONE || !dst_frame) { - LOGE("failed to do rotate image"); - free(dst_frame); + 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 create image"); return ret; } - LOGD("after rotation same stride: dst_width = %d and dst_height = %d, dst_size = %zu", dst_width, dst_height, dst_size); + 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; + } + + mm_image_debug_image(dst_image, NULL); + + 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; + } - g_free(src_buffer); + free(src_buffer); - player->capture.data = dst_frame; 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, }; int orientation = 0; int display_angle = 0; @@ -297,24 +275,38 @@ __mmplayer_capture_thread(gpointer data) /* Colorspace conversion : NV12T-> NV12-> RGB888 */ ret = __mm_player_convert_NV12_tiled(player); if (ret != MM_ERROR_NONE) { + LOGE("failed to covert NV12T"); msg.code = ret; goto ERROR; } } 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; } } 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; + } + } else if (player->video_cs == MM_PLAYER_COLORSPACE_BGRx) { + ret = __mm_player_convert_BGRx(player); + if (ret != MM_ERROR_NONE) { + LOGE("failed to covert BGRx"); msg.code = ret; goto ERROR; } + } else { + LOGE("invalid format"); + msg.code = MM_ERROR_PLAYER_INTERNAL; + goto ERROR; } - ret = __mmplayer_get_video_angle((MMHandleType)player, &display_angle, &orientation); + ret = _mmplayer_get_video_angle((MMHandleType)player, &display_angle, &orientation); if (ret != MM_ERROR_NONE) { LOGE("failed to get rotation angle"); goto ERROR; @@ -339,7 +331,7 @@ __mmplayer_capture_thread(gpointer data) continue; ERROR: - for (i = 0; i < player->captured.handle_num; i++) + for (i = 0; i < player->captured.plane_num; i++) MMPLAYER_FREEIF(player->captured.data[i]); msg.union_type = MM_MSG_UNION_CODE; @@ -356,18 +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 size = 0; gint i = 0; - gint src_width = 0; - gint src_height = 0; + guint plane_size = 0; GstCaps *caps = NULL; - GstStructure *structure = NULL; - GstMapInfo mapinfo = GST_MAP_INFO_INIT; - mm_util_color_format_e src_fmt = MM_UTIL_COLOR_YUV420; - mm_util_color_format_e dst_fmt = MM_UTIL_COLOR_RGB24; // fixed + GstVideoFrame vframe; + GstVideoInfo vinfo; + guint8 *pixels = NULL; + int ret = MM_ERROR_NONE; MMPLAYER_FENTER(); @@ -380,139 +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); - - GstVideoInfo video_info; - gst_video_info_from_caps(&video_info, caps); - - /* 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")) - player->video_cs = MM_PLAYER_COLORSPACE_NV12_TILED; - else if (!g_strcmp0(gst_format, "S420")) - player->video_cs = MM_PLAYER_COLORSPACE_I420; - else if (!g_strcmp0(gst_format, "SN12")) - player->video_cs = MM_PLAYER_COLORSPACE_NV12; - else if (!g_strcmp0(gst_format, "BGRx")) - player->video_cs = MM_PLAYER_COLORSPACE_BGRx; - else - player->video_cs = MM_PLAYER_COLORSPACE_MAX; - - LOGI("captured format is %s\n", gst_format); - - if (!g_strcmp0(gst_format, "ST12") || !g_strcmp0(gst_format, "SN12") - || !g_strcmp0(gst_format, "S420")) { - GstVideoFrame vframe; - GstVideoFormat format; - const GstVideoFormatInfo *finfo; - - /* get video frame info from proved buffer */ - format = gst_video_format_from_string(gst_format); - finfo = gst_video_format_get_info(format); - - if (gst_video_frame_map(&vframe, &video_info, buffer, GST_MAP_READ)) { - for (i = 0; i < GST_VIDEO_FORMAT_INFO_N_PLANES(finfo); i++) { - player->captured.width[i] = GST_VIDEO_FRAME_PLANE_STRIDE(&vframe, i); - player->captured.height[i] = GST_VIDEO_FRAME_COMP_HEIGHT(&vframe, i); - player->captured.stride_width[i] = GST_VIDEO_FRAME_PLANE_STRIDE(&vframe, i); - player->captured.stride_height[i] = GST_VIDEO_FRAME_COMP_HEIGHT(&vframe, i); - size = player->captured.stride_width[i] * player->captured.stride_height[i]; - guint8 *pixels = GST_VIDEO_FRAME_PLANE_DATA(&vframe, i); - - player->captured.data[i] = g_try_malloc(size); - if (!player->captured.data[i]) { - gst_video_frame_unmap(&vframe); - LOGE("no free space\n"); - ret = MM_ERROR_PLAYER_NO_FREE_SPACE; - goto ERROR; - } - memcpy(player->captured.data[i], pixels, size); - } - player->captured.handle_num = GST_VIDEO_FRAME_N_PLANES(&vframe); - gst_video_frame_unmap(&vframe); - } - goto DONE; - } else { - player->captured.width[0] = src_width; - player->captured.height[0] = src_height; - player->captured.stride_width[0] = MM_ALIGN(src_width, 4); - player->captured.stride_height[0] = src_height; - switch (GST_VIDEO_INFO_FORMAT(&video_info)) { - case GST_VIDEO_FORMAT_I420: - src_fmt = MM_UTIL_COLOR_I420; - player->captured.width[1] = player->captured.width[2] = src_width>>1; - player->captured.height[1] = player->captured.width[2] = src_height>>1; - player->captured.stride_width[1] = player->captured.stride_width[2] = MM_ALIGN(player->captured.width[1], 4); - player->captured.stride_height[1] = player->captured.stride_height[2] = src_height>>1; - break; - case GST_VIDEO_FORMAT_BGRA: - src_fmt = MM_UTIL_COLOR_BGRA; - break; - case GST_VIDEO_FORMAT_BGRx: - src_fmt = MM_UTIL_COLOR_BGRX; - break; - default: - LOGE("unknown format to capture\n"); - ret = MM_ERROR_PLAYER_INTERNAL; - goto ERROR; - break; - } - player->captured.handle_num = 1; - } - } else { - LOGE("unknown format to capture\n"); - ret = MM_ERROR_PLAYER_INTERNAL; - goto ERROR; - } + memset(&player->capture, 0x00, sizeof(mmplayer_video_capture_t)); - 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); + gst_video_info_from_caps(&vinfo, caps); -DONE: - /* do convert colorspace */ - MMPLAYER_CAPTURE_THREAD_SIGNAL(player); + gst_caps_unref(caps); - if (caps) { - gst_caps_unref(caps); - caps = NULL; - } + LOGI("captured format is %s", gst_video_format_to_string(GST_VIDEO_INFO_FORMAT(&vinfo))); - return ret; + player->captured.width[0] = GST_VIDEO_INFO_WIDTH(&vinfo); + player->captured.height[0] = GST_VIDEO_INFO_HEIGHT(&vinfo); -ERROR: + 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; + } - if (caps) { - gst_caps_unref(caps); - caps = NULL; + if (ret != MM_ERROR_NONE) { + LOGE("unknown format to capture"); + return ret; } - for (i = 0; i < player->captured.handle_num; i++) { - MMPLAYER_FREEIF(player->captured.data[i]); + 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); + } + player->captured.plane_num = GST_VIDEO_FRAME_N_PLANES(&vframe); + gst_video_frame_unmap(&vframe); } + /* do convert colorspace */ + MMPLAYER_CAPTURE_THREAD_SIGNAL(player); - 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; @@ -521,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; @@ -539,27 +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_color_format_e src_fmt, unsigned int src_w, unsigned int src_h, mm_util_color_format_e 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_width = 0; - unsigned int dst_height = 0; - size_t dst_size = 0; 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); - SECURE_LOGD("src size info. width: %d, height: %d \n", src_w, src_h); + SECURE_LOGD("src size info. width: %d, height: %d", src_w, src_h); - ret = mm_util_convert_colorspace(src_data, src_w, src_h, src_fmt, dst_fmt, &dst_data, &dst_width, &dst_height, &dst_size); - if (ret != MM_ERROR_NONE || !dst_data) { - LOGE("failed to convert for capture, %d\n", ret); - g_free(dst_data); + 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 create image for capture, %d", ret); return MM_ERROR_PLAYER_INTERNAL; } - SECURE_LOGD("dst size info. width: %d, height: %d, size: %zu\n", dst_width, dst_height, dst_size); - player->capture.size = (int)dst_size; - player->capture.data = dst_data; + 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_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 get image for capture, %d", ret); + return MM_ERROR_PLAYER_INTERNAL; + } + + player->capture.size = (int)size; return MM_ERROR_NONE; } @@ -574,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 @@ -601,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); @@ -609,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); @@ -625,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 @@ -651,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; @@ -667,151 +604,153 @@ __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); - 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(mm_player_t* player) +static void +capture_output_dump(mmplayer_t *player) { unsigned char *temp = NULL; char file[100] = { 0, }; @@ -828,7 +767,7 @@ static void capture_output_dump(mm_player_t* player) for (j = 0; j < player->captured.height[i]; j++) { ret = fwrite(temp, player->captured.width[i], 1, fp); - temp += player->captured.width[i]; + temp += player->captured.stride_width[i]; } } LOGE("capture yuv dumped!! ret = %d", ret); @@ -844,69 +783,56 @@ static void capture_output_dump(mm_player_t* player) #endif static int -__mm_player_convert_NV12_tiled(mm_player_t *player) +__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; - int linear_y_plane_size; - int linear_uv_plane_size; - int width = player->captured.width[0]; - int height = player->captured.height[0]; - int i; + 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_y_plane_size = width * height; linear_uv_plane_size = linear_y_plane_size / 2; - linear_y_plane = (unsigned char *)g_try_malloc(linear_y_plane_size); - if (!linear_y_plane) - return MM_ERROR_PLAYER_NO_FREE_SPACE; - - linear_uv_plane = (unsigned char *)g_try_malloc(linear_uv_plane_size); - if (!linear_uv_plane) { - ret = MM_ERROR_PLAYER_NO_FREE_SPACE; - goto EXIT; + 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_try_malloc(linear_y_plane_size + linear_uv_plane_size); + src_buffer = (unsigned char *)g_malloc(linear_y_plane_size + linear_uv_plane_size); - if (!src_buffer) { - ret = MM_ERROR_PLAYER_NO_FREE_SPACE; - goto EXIT; - } - 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_COLOR_NV12, - width, height, MM_UTIL_COLOR_RGB24); - if (ret != MM_ERROR_NONE) { - LOGE("failed to convert nv12 linear"); - goto EXIT; - } + 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); -EXIT: - /* clean */ MMPLAYER_FREEIF(src_buffer); MMPLAYER_FREEIF(linear_y_plane); MMPLAYER_FREEIF(linear_uv_plane); - for (i = 0; i < player->captured.handle_num; i++) + for (i = 0; i < player->captured.plane_num; i++) MMPLAYER_FREEIF(player->captured.data[i]); return ret; } static int -__mm_player_convert_NV12(mm_player_t *player) +__mm_player_convert_NV12(mmplayer_t *player) { unsigned char *src_buffer = NULL; unsigned char *p_buf = NULL; @@ -915,20 +841,17 @@ __mm_player_convert_NV12(mm_player_t *player) int ret = MM_ERROR_NONE; int i, j; - /* using original width otherwises, app can't know aligned to resize */ + /* 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]; - int src_buffer_size = planes[0] + planes[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_try_malloc(src_buffer_size); - if (!src_buffer) - return MM_ERROR_PLAYER_NO_FREE_SPACE; + src_buffer = (unsigned char *)g_malloc(src_buffer_size); - memset(src_buffer, 0x00, src_buffer_size); p_buf = src_buffer; temp = player->captured.data[0]; @@ -950,29 +873,23 @@ __mm_player_convert_NV12(mm_player_t *player) } /* NV12 -> RGB888 */ - ret = __mm_player_convert_colorspace(player, (unsigned char *)src_buffer, + 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); - if (ret != MM_ERROR_NONE) { - LOGE("failed to convert nv12 linear"); - goto EXIT; - } + #ifdef CAPTURE_OUTPUT_DUMP capture_output_dump(player); #endif - -EXIT: - /* clean */ MMPLAYER_FREEIF(src_buffer); - /* free captured buf */ - for (i = 0; i < player->captured.handle_num; i++) + + for (i = 0; i < player->captured.plane_num; i++) MMPLAYER_FREEIF(player->captured.data[i]); return ret; } static int -__mm_player_convert_I420(mm_player_t *player) +__mm_player_convert_I420(mmplayer_t *player) { unsigned char *src_buffer = NULL; unsigned char *p_buf = NULL; @@ -981,19 +898,18 @@ __mm_player_convert_I420(mm_player_t *player) int ret = MM_ERROR_NONE; int i; - /* using original width otherwises, app can't know aligned to resize */ + /* 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); - src_buffer = (unsigned char *)g_try_malloc(player->captured.stride_width[0] - * player->captured.stride_height[0] * 3 / 2); - - if (!src_buffer) - return MM_ERROR_PLAYER_NO_FREE_SPACE; + 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 */ - memset(src_buffer, 0x00, planes[0]); p_buf = src_buffer; temp = player->captured.data[0]; @@ -1005,7 +921,6 @@ __mm_player_convert_I420(mm_player_t *player) } /* set U plane */ - memset(p_buf, 0x00, planes[1]); temp = player->captured.data[1]; for (i = 0; i < player->captured.height[1]; i++) { @@ -1015,7 +930,6 @@ __mm_player_convert_I420(mm_player_t *player) } /* set V plane */ - memset(p_buf, 0x00, planes[2]); temp = player->captured.data[2]; for (i = 0; i < player->captured.height[2]; i++) { @@ -1025,21 +939,47 @@ __mm_player_convert_I420(mm_player_t *player) } /* I420 -> RGB888 */ - ret = __mm_player_convert_colorspace(player, (unsigned char *)src_buffer, MM_UTIL_COLOR_I420, - player->captured.width[0], player->captured.height[0], MM_UTIL_COLOR_RGB24); - if (ret != MM_ERROR_NONE) { - LOGE("failed to convert I420 linear"); - goto EXIT; - } + 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); -EXIT: - /* clean */ + 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); - /* free captured buf */ - for (i = 0; i < player->captured.handle_num; i++) + + for (i = 0; i < player->captured.plane_num; i++) MMPLAYER_FREEIF(player->captured.data[i]); return ret;