summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSejun Park <sejun79.park@samsung.com>2017-12-05 14:56:11 +0900
committerSejun Park <sejun79.park@samsung.com>2017-12-06 16:49:07 +0900
commitba0b49163edd0f8c0faba6c52dccbe5a308ecfdb (patch)
treecd22f0b609e04c3f1f82c5410997544ebe280ef2
parent53dee29e410a83198be5502b1e39ff8cea4d58bd (diff)
downloadlibmm-player-ba0b49163edd0f8c0faba6c52dccbe5a308ecfdb.tar.gz
libmm-player-ba0b49163edd0f8c0faba6c52dccbe5a308ecfdb.tar.bz2
libmm-player-ba0b49163edd0f8c0faba6c52dccbe5a308ecfdb.zip
Supported S420 for capturing video
Change-Id: I1fc58314fc4b14b852f996961df8b8a515d02b65
-rwxr-xr-x[-rw-r--r--]src/include/mm_player_capture.h2
-rwxr-xr-x[-rw-r--r--]src/include/mm_player_internal.h1
-rwxr-xr-x[-rw-r--r--]src/mm_player_capture.c180
3 files changed, 130 insertions, 53 deletions
diff --git a/src/include/mm_player_capture.h b/src/include/mm_player_capture.h
index 44dcbb4..1dd5b92 100644..100755
--- 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
index 7a7e966..8504d97 100644..100755
--- 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
index 46f8cca..4ed21ae 100644..100755
--- 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;
}