From 07740e292454668b87efc2d9655db6b35a3dff12 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 5 Dec 2017 14:56:11 +0900 Subject: [PATCH] Supported S420 for capturing video Change-Id: I1fc58314fc4b14b852f996961df8b8a515d02b65 (cherry picked from commit ba0b49163edd0f8c0faba6c52dccbe5a308ecfdb) --- src/include/mm_player_capture.h | 2 + src/include/mm_player_internal.h | 1 + src/mm_player_capture.c | 180 +++++++++++++++++++++++++++------------ 3 files changed, 130 insertions(+), 53 deletions(-) mode change 100644 => 100755 src/include/mm_player_capture.h mode change 100644 => 100755 src/include/mm_player_internal.h mode change 100644 => 100755 src/mm_player_capture.c diff --git a/src/include/mm_player_capture.h b/src/include/mm_player_capture.h old mode 100644 new mode 100755 index 44dcbb4..1dd5b92 --- a/src/include/mm_player_capture.h +++ b/src/include/mm_player_capture.h @@ -33,6 +33,8 @@ extern "C" { #endif +#define MAX_BUFFER_PLANE 3 + /*======================================================================================= | GLOBAL FUNCTION PROTOTYPES | ========================================================================================*/ diff --git a/src/include/mm_player_internal.h b/src/include/mm_player_internal.h old mode 100644 new mode 100755 index 7a7e966..8504d97 --- a/src/include/mm_player_internal.h +++ b/src/include/mm_player_internal.h @@ -100,6 +100,7 @@ typedef enum { MM_PLAYER_COLORSPACE_RGB888, /**< RGB888 pixel format */ MM_PLAYER_COLORSPACE_NV12_TILED, /**< Customized color format */ MM_PLAYER_COLORSPACE_NV12, + MM_PLAYER_COLORSPACE_MAX = 0x7FFFFFFF } MMPlayerVideoColorspace; typedef struct { diff --git a/src/mm_player_capture.c b/src/mm_player_capture.c old mode 100644 new mode 100755 index 46f8cca..4ed21ae --- a/src/mm_player_capture.c +++ b/src/mm_player_capture.c @@ -283,6 +283,10 @@ __mmplayer_capture_thread(gpointer data) unsigned char * linear_uv_plane = NULL; int orientation = 0; int ret = 0; + int planes[MAX_BUFFER_PLANE] = {0, }; + unsigned char * p_buf = NULL; + unsigned char * temp = NULL; + int i, j; MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL); @@ -328,8 +332,9 @@ __mmplayer_capture_thread(gpointer data) __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]); + for (i = 0; i < player->captured.handle_num; i++) { + MMPLAYER_FREEIF(player->captured.data[i]); + } src_buffer = (unsigned char*) g_try_malloc(linear_y_plane_size+linear_uv_plane_size); @@ -357,35 +362,30 @@ __mmplayer_capture_thread(gpointer data) #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; + planes[0] = player->captured.width[0] * player->captured.height[0]; + planes[1] = player->captured.width[0] * player->captured.height[1]; + int src_buffer_size = planes[0] + planes[1]; + src_buffer = (unsigned char*) g_try_malloc(src_buffer_size); + p_buf = src_buffer; if (!src_buffer_size) { LOGE("invalid data size"); goto ERROR; } - src_buffer = (unsigned char*) g_try_malloc(src_buffer_size); - if (!src_buffer) { msg.code = MM_ERROR_PLAYER_NO_FREE_SPACE; goto ERROR; } - memset(src_buffer, 0x00, src_buffer_size); + memset(p_buf, 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; + memcpy(p_buf, temp, player->captured.width[0]); + p_buf += player->captured.width[0]; temp += player->captured.stride_width[0]; } @@ -393,18 +393,19 @@ __mmplayer_capture_thread(gpointer data) /* set UV plane*/ for (j = 0; j < player->captured.height[1]; j++) { - memcpy(dst_buf, temp, width_align); - dst_buf += width_align; + memcpy(p_buf, temp, player->captured.width[0]); + p_buf += player->captured.width[0]; temp += player->captured.stride_width[1]; } /* free captured buf */ - MMPLAYER_FREEIF(player->captured.data[0]); - MMPLAYER_FREEIF(player->captured.data[1]); + for (i = 0; i < player->captured.handle_num; i++) { + MMPLAYER_FREEIF(player->captured.data[i]); + } /* 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); + player->captured.width[0], player->captured.height[0], MM_UTIL_IMG_FMT_RGB888); if (ret != MM_ERROR_NONE) { LOGE("failed to convert nv12 linear"); goto ERROR; @@ -412,6 +413,55 @@ __mmplayer_capture_thread(gpointer data) /* clean */ MMPLAYER_FREEIF(src_buffer); + } else if (MM_PLAYER_COLORSPACE_I420 == player->video_cs) { + planes[0] = player->captured.width[0] * player->captured.height[0]; + planes[1] = planes[2] = (player->captured.width[0]>>1) * (player->captured.height[0]>>1); + + src_buffer = (unsigned char*) g_try_malloc(player->captured.width[0] * player->captured.height[0]*3/2); + p_buf = src_buffer; + /* set Y plane */ + memset(p_buf, 0x00, planes[0]); + 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 */ + memset(p_buf, 0x00, planes[1]); + 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 */ + memset(p_buf, 0x00, planes[2]); + 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, MM_UTIL_IMG_FMT_I420, + player->captured.width[0], player->captured.height[0], MM_UTIL_IMG_FMT_RGB888); + if (ret != MM_ERROR_NONE) { + LOGE("failed to convert I420 linear"); + goto ERROR; + } + + /* free captured buf */ + MMPLAYER_FREEIF(src_buffer); + for (i = 0; i < player->captured.handle_num; i++) { + MMPLAYER_FREEIF(player->captured.data[i]); + } } ret = _mmplayer_get_video_rotate_angle((MMHandleType)player, &orientation); @@ -444,8 +494,11 @@ __mmplayer_capture_thread(gpointer data) continue; ERROR: MMPLAYER_FREEIF(src_buffer); - MMPLAYER_FREEIF(player->captured.data[0]); - MMPLAYER_FREEIF(player->captured.data[1]); + + for (i = 0; i < player->captured.handle_num; i++) { + MMPLAYER_FREEIF(player->captured.data[i]); + } + if (player->video_cs == MM_PLAYER_COLORSPACE_NV12_TILED) { /* clean */ MMPLAYER_FREEIF(linear_y_plane); @@ -469,8 +522,8 @@ static int __mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstPad *pad, GstBuffer *buffer) { int ret = MM_ERROR_NONE; - gint yplane_size = 0; - gint uvplane_size = 0; + gint planes[MAX_BUFFER_PLANE] = {0, }; + gint i = 0; gint src_width = 0; gint src_height = 0; GstCaps *caps = NULL; @@ -508,15 +561,19 @@ __mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstPad *pad, GstBuff 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")) { + if (!g_strcmp0(gst_format, "ST12") || !g_strcmp0(gst_format, "SN12") || !g_strcmp0(gst_format, "S420")) { 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 + 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 + player->video_cs = MM_PLAYER_COLORSPACE_MAX; /* get video frame info from proved buffer */ n = gst_buffer_n_memory(buffer); @@ -532,11 +589,12 @@ __mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstPad *pad, GstBuff memcpy(&player->captured, proved, sizeof(MMVideoBuffer)); - yplane_size = proved->size[0]; - uvplane_size = proved->size[1]; - LOGI("yplane_size=%d, uvplane_size=%d", yplane_size, uvplane_size); + planes[0] = proved->size[0]; + planes[1] = proved->size[1]; + planes[2] = proved->size[2]; - player->captured.data[0] = g_try_malloc(yplane_size); + /* Y */ + player->captured.data[0] = g_try_malloc(planes[0]); if (!player->captured.data[0]) { gst_memory_unmap(memory, &mapinfo); LOGE("no free space\n"); @@ -544,44 +602,56 @@ __mmplayer_get_video_frame_from_buffer(mm_player_t* player, GstPad *pad, GstBuff goto ERROR; } -/* 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); + /* U */ + if (proved->size[1]) { + player->captured.data[1] = g_try_malloc(planes[1]); + + if (!player->captured.data[1]) { + LOGE("no free space\n"); + gst_memory_unmap(memory, &mapinfo); + ret = MM_ERROR_PLAYER_NO_FREE_SPACE; + goto ERROR; + } } -#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; + + /* V */ + if (proved->size[2]) { + player->captured.data[2] = g_try_malloc(planes[2]); + + if (!player->captured.data[2]) { + LOGE("no free space\n"); + gst_memory_unmap(memory, &mapinfo); + ret = MM_ERROR_PLAYER_NO_FREE_SPACE; + goto ERROR; + } } 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); + LOGD("plane[0] : %p, size %d", proved->data[0], planes[0]); if (proved->data[0]) - memcpy(player->captured.data[0], proved->data[0], yplane_size); + memcpy(player->captured.data[0], proved->data[0], planes[0]); - LOGD("source uv : %p, size %d", proved->data[1], uvplane_size); + LOGD("plane[1] : %p, size %d", proved->data[1], planes[1]); if (proved->data[1]) - memcpy(player->captured.data[1], proved->data[1], uvplane_size); + memcpy(player->captured.data[1], proved->data[1], planes[1]); tbm_bo_unref(proved->handle.bo[0]); tbm_bo_unref(proved->handle.bo[1]); + + if (player->video_cs == MM_PLAYER_COLORSPACE_I420) { + tbm_bo_ref(proved->handle.bo[2]); + LOGD("plane[2] : %p, size %d", proved->data[2], planes[2]); + + if (proved->data[2]) + memcpy(player->captured.data[2], proved->data[2], planes[2]); + + tbm_bo_unref(proved->handle.bo[2]); + } } 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; @@ -630,6 +700,10 @@ ERROR: caps = NULL; } + for (i = 0; i < player->captured.handle_num; i++) { + MMPLAYER_FREEIF(player->captured.data[i]); + } + MMPLAYER_FLEAVE(); return ret; } -- 2.7.4