Supported S420 for capturing video 19/163219/1 accepted/tizen/unified/20171212.171926 submit/tizen/20171212.053432
authorSejun Park <sejun79.park@samsung.com>
Tue, 5 Dec 2017 05:56:11 +0000 (14:56 +0900)
committereunhae choi <eunhae1.choi@samsung.com>
Fri, 8 Dec 2017 04:47:49 +0000 (04:47 +0000)
Change-Id: I1fc58314fc4b14b852f996961df8b8a515d02b65
(cherry picked from commit ba0b49163edd0f8c0faba6c52dccbe5a308ecfdb)

src/include/mm_player_capture.h [changed mode: 0644->0755]
src/include/mm_player_internal.h [changed mode: 0644->0755]
src/mm_player_capture.c [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 44dcbb4..1dd5b92
@@ -33,6 +33,8 @@
        extern "C" {
 #endif
 
+#define MAX_BUFFER_PLANE       3
+
 /*=======================================================================================
 | GLOBAL FUNCTION PROTOTYPES                                                           |
 ========================================================================================*/
old mode 100644 (file)
new mode 100755 (executable)
index 7a7e966..8504d97
@@ -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 {
old mode 100644 (file)
new mode 100755 (executable)
index 46f8cca..4ed21ae
@@ -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;
 }