4 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include "ctsvc_internal.h"
21 #include "ctsvc_image_util.h"
23 struct image_transform {
31 int ctsvc_image_util_get_mimetype(image_util_colorspace_e colorspace,
34 RETV_IF(NULL == p_mimetype, CONTACTS_ERROR_INVALID_PARAMETER);
36 media_format_mimetype_e mimetype;
38 case IMAGE_UTIL_COLORSPACE_YUV422:
39 mimetype = MEDIA_FORMAT_422P;
41 case IMAGE_UTIL_COLORSPACE_NV12:
42 mimetype = MEDIA_FORMAT_NV12;
44 case IMAGE_UTIL_COLORSPACE_UYVY:
45 mimetype = MEDIA_FORMAT_UYVY;
47 case IMAGE_UTIL_COLORSPACE_YUYV:
48 mimetype = MEDIA_FORMAT_YUYV;
50 case IMAGE_UTIL_COLORSPACE_RGB565:
51 mimetype = MEDIA_FORMAT_RGB565;
53 case IMAGE_UTIL_COLORSPACE_RGB888:
54 mimetype = MEDIA_FORMAT_RGB888;
56 case IMAGE_UTIL_COLORSPACE_ARGB8888:
57 mimetype = MEDIA_FORMAT_ARGB;
59 case IMAGE_UTIL_COLORSPACE_RGBA8888:
60 mimetype = MEDIA_FORMAT_RGBA;
62 case IMAGE_UTIL_COLORSPACE_NV21:
63 mimetype = MEDIA_FORMAT_NV21;
65 case IMAGE_UTIL_COLORSPACE_NV16:
66 mimetype = MEDIA_FORMAT_NV16;
68 case IMAGE_UTIL_COLORSPACE_BGRA8888: /* not supported */
69 case IMAGE_UTIL_COLORSPACE_BGRX8888: /* not supported */
70 case IMAGE_UTIL_COLORSPACE_NV61: /* not supported */
71 case IMAGE_UTIL_COLORSPACE_YV12: /* not supported */
72 case IMAGE_UTIL_COLORSPACE_I420: /* not supported */
75 ERR("Not supported %d", colorspace);
76 return CONTACTS_ERROR_INVALID_PARAMETER;
79 *p_mimetype = mimetype;
80 return CONTACTS_ERROR_NONE;
83 media_format_h ctsvc_image_util_create_media_format(int mimetype, int width,
87 media_format_h fmt = NULL;
89 ret = media_format_create(&fmt);
90 if (MEDIA_FORMAT_ERROR_NONE != ret) {
92 ERR("media_format_create() Fail(%d)", ret);
97 ret = media_format_set_video_mime(fmt, mimetype);
98 if (MEDIA_FORMAT_ERROR_NONE != ret) {
100 ERR("media_format_set_video_mime() Fail(%d)", ret);
101 media_format_unref(fmt);
106 ret = media_format_set_video_width(fmt, width);
107 if (MEDIA_FORMAT_ERROR_NONE != ret) {
108 /* LCOV_EXCL_START */
109 ERR("media_format_set_video_width() Fail(%d)", ret);
110 media_format_unref(fmt);
115 ret = media_format_set_video_height(fmt, height);
116 if (MEDIA_FORMAT_ERROR_NONE != ret) {
117 /* LCOV_EXCL_START */
118 ERR("media_format_set_video_height() Fail(%d)", ret);
119 media_format_unref(fmt);
124 ret = media_format_set_video_avg_bps(fmt, 2000000); /* image_util guide */
125 if (MEDIA_FORMAT_ERROR_NONE != ret) {
126 /* LCOV_EXCL_START */
127 ERR("media_format_set_video_avg_bps() Fail(%d)", ret);
128 media_format_unref(fmt);
133 ret = media_format_set_video_max_bps(fmt, 15000000); /* image_util guide */
134 if (MEDIA_FORMAT_ERROR_NONE != ret) {
135 /* LCOV_EXCL_START */
136 ERR("media_format_set_video_max_bps() Fail(%d)", ret);
137 media_format_unref(fmt);
145 int _ctsvc_image_packet_create_alloc_finalize_cb(media_packet_h packet,
146 int error_code, void *user_data)
148 return MEDIA_PACKET_FINALIZE;
151 media_packet_h ctsvc_image_util_create_media_packet(media_format_h fmt,
152 void *buffer, unsigned int buffer_size)
155 void *mp_buffer = NULL;
156 media_packet_h packet = NULL;
157 uint64_t mp_buffer_size = 0;
159 RETV_IF(NULL == fmt, NULL);
160 RETV_IF(NULL == buffer, NULL);
162 ret = media_packet_create_alloc(fmt, _ctsvc_image_packet_create_alloc_finalize_cb,
164 if (MEDIA_PACKET_ERROR_NONE != ret) {
165 /* LCOV_EXCL_START */
166 ERR("media_packet_create_alloc() Fail(%d)", ret);
171 ret = media_packet_get_buffer_size(packet, &mp_buffer_size);
172 if (MEDIA_PACKET_ERROR_NONE != ret) {
173 /* LCOV_EXCL_START */
174 ERR("media_packet_get_buffer_size() Fail(%d)", ret);
175 media_packet_destroy(packet);
180 ret = media_packet_get_buffer_data_ptr(packet, &mp_buffer);
181 if (MEDIA_PACKET_ERROR_NONE != ret) {
182 /* LCOV_EXCL_START */
183 ERR("media_packet_get_buffer_data_ptr() Fail(%d)", ret);
184 media_packet_destroy(packet);
190 memcpy(mp_buffer, buffer, (int)((buffer_size < mp_buffer_size) ? buffer_size : mp_buffer_size));
196 static void _image_transform_completed_cb(media_packet_h *dst,
197 image_util_error_e error, void *user_data)
202 struct image_transform *info = user_data;
206 media_packet_destroy(*dst);
210 if (IMAGE_UTIL_ERROR_NONE == error) {
211 ret = media_packet_get_buffer_size(*dst, &size);
212 if (MEDIA_PACKET_ERROR_NONE != ret) {
213 /* LCOV_EXCL_START */
214 ERR("media_packet_get_buffer_size() Fail(%d)", ret);
215 info->ret = CONTACTS_ERROR_SYSTEM;
216 media_packet_destroy(*dst);
217 g_mutex_lock(&info->mutex);
218 g_cond_signal(&info->cond);
219 g_mutex_unlock(&info->mutex);
224 ret = media_packet_get_buffer_data_ptr(*dst, &buffer);
225 if (MEDIA_PACKET_ERROR_NONE != ret) {
226 /* LCOV_EXCL_START */
227 ERR("media_packet_get_buffer_data_ptr() Fail(%d)", ret);
228 info->ret = CONTACTS_ERROR_SYSTEM;
229 media_packet_destroy(*dst);
230 g_mutex_lock(&info->mutex);
231 g_cond_signal(&info->cond);
232 g_mutex_unlock(&info->mutex);
237 info->buffer = calloc(1, (size_t)size);
238 if (NULL == info->buffer) {
239 /* LCOV_EXCL_START */
240 ERR("calloc() Fail");
241 info->ret = CONTACTS_ERROR_SYSTEM;
242 media_packet_destroy(*dst);
243 g_mutex_lock(&info->mutex);
244 g_cond_signal(&info->cond);
245 g_mutex_unlock(&info->mutex);
249 memcpy(info->buffer, buffer, (size_t)size);
251 info->ret = CONTACTS_ERROR_NONE;
253 ERR("transform_run() Fail(%d)", error);
254 info->ret = CONTACTS_ERROR_SYSTEM;
256 media_packet_destroy(*dst);
257 g_mutex_lock(&info->mutex);
258 g_cond_signal(&info->cond);
259 g_mutex_unlock(&info->mutex);
262 static int _ctsvc_image_util_transform_run(transformation_h transform,
263 media_packet_h packet, void **p_buffer, uint64_t *p_size)
267 struct image_transform *info = NULL;
269 RETV_IF(NULL == transform, CONTACTS_ERROR_INVALID_PARAMETER);
270 RETV_IF(NULL == packet, CONTACTS_ERROR_INVALID_PARAMETER);
272 info = calloc(1, sizeof(struct image_transform));
274 /* LCOV_EXCL_START */
275 ERR("calloc() Fail");
276 return CONTACTS_ERROR_OUT_OF_MEMORY;
280 g_cond_init(&info->cond);
281 g_mutex_init(&info->mutex);
283 g_mutex_lock(&info->mutex);
284 ret = image_util_transform_run(transform, packet, _image_transform_completed_cb, info);
285 if (IMAGE_UTIL_ERROR_NONE != ret) {
286 /* LCOV_EXCL_START */
287 ERR("image_util_transform_run() Fail(%d)", ret);
288 g_mutex_unlock(&info->mutex);
289 g_mutex_clear(&info->mutex);
290 g_cond_clear(&info->cond);
291 return CONTACTS_ERROR_SYSTEM;
295 end_time = g_get_monotonic_time() + 4000 * G_TIME_SPAN_MILLISECOND;
296 if (!g_cond_wait_until(&info->cond, &info->mutex, end_time)) {
297 /* timeout has passed */
298 ERR("g_cond_wait_until() return FALSE");
299 info->ret = CONTACTS_ERROR_SYSTEM;
301 g_mutex_unlock(&info->mutex);
302 g_mutex_clear(&info->mutex);
303 g_cond_clear(&info->cond);
305 if (CONTACTS_ERROR_NONE != info->ret) {
306 /* LCOV_EXCL_START */
307 ERR("image_util_transform_run() Fail(%d)", info->ret);
310 return CONTACTS_ERROR_SYSTEM;
314 *p_size = info->size;
315 *p_buffer = info->buffer;
317 return CONTACTS_ERROR_NONE;
321 int ctsvc_image_util_rotate(media_packet_h packet, image_util_rotation_e rotation,
322 void **p_buffer, uint64_t *p_size)
325 transformation_h transform = NULL;
327 ret = image_util_transform_create(&transform);
328 if (IMAGE_UTIL_ERROR_NONE != ret) {
329 /* LCOV_EXCL_START */
330 ERR("image_util_transform_create() Fail(%d)", ret);
331 return CONTACTS_ERROR_SYSTEM;
335 ret = image_util_transform_set_rotation(transform, rotation);
336 if (IMAGE_UTIL_ERROR_NONE != ret) {
337 /* LCOV_EXCL_START */
338 ERR("image_util_transform_set_rotation() Fail(%d)", ret);
339 image_util_transform_destroy(transform);
340 return CONTACTS_ERROR_SYSTEM;
344 ret = _ctsvc_image_util_transform_run(transform, packet, p_buffer, p_size);
346 image_util_transform_destroy(transform);
350 int ctsvc_image_util_resize(media_packet_h packet, int width, int height,
351 void **p_buffer, uint64_t *p_size)
354 transformation_h transform = NULL;
356 ret = image_util_transform_create(&transform);
357 if (IMAGE_UTIL_ERROR_NONE != ret) {
358 /* LCOV_EXCL_START */
359 ERR("image_util_transform_create() Fail(%d)", ret);
360 return CONTACTS_ERROR_SYSTEM;
364 ret = image_util_transform_set_resolution(transform, width, height);
365 if (IMAGE_UTIL_ERROR_NONE != ret) {
366 /* LCOV_EXCL_START */
367 ERR("image_util_transform_set_resolution() Fail(%d)", ret);
368 image_util_transform_destroy(transform);
369 return CONTACTS_ERROR_SYSTEM;
373 ret = _ctsvc_image_util_transform_run(transform, packet, p_buffer, p_size);
375 image_util_transform_destroy(transform);