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 /* LCOV_EXCL_START */
254 ERR("transform_run() Fail(%d)", error);
255 info->ret = CONTACTS_ERROR_SYSTEM;
258 media_packet_destroy(*dst);
259 g_mutex_lock(&info->mutex);
260 g_cond_signal(&info->cond);
261 g_mutex_unlock(&info->mutex);
264 static int _ctsvc_image_util_transform_run(transformation_h transform,
265 media_packet_h packet, void **p_buffer, uint64_t *p_size)
269 struct image_transform *info = NULL;
271 RETV_IF(NULL == transform, CONTACTS_ERROR_INVALID_PARAMETER);
272 RETV_IF(NULL == packet, CONTACTS_ERROR_INVALID_PARAMETER);
274 info = calloc(1, sizeof(struct image_transform));
276 /* LCOV_EXCL_START */
277 ERR("calloc() Fail");
278 return CONTACTS_ERROR_OUT_OF_MEMORY;
282 g_cond_init(&info->cond);
283 g_mutex_init(&info->mutex);
285 g_mutex_lock(&info->mutex);
286 ret = image_util_transform_run(transform, packet, _image_transform_completed_cb, info);
287 if (IMAGE_UTIL_ERROR_NONE != ret) {
288 /* LCOV_EXCL_START */
289 ERR("image_util_transform_run() Fail(%d)", ret);
290 g_mutex_unlock(&info->mutex);
291 g_mutex_clear(&info->mutex);
292 g_cond_clear(&info->cond);
294 return CONTACTS_ERROR_SYSTEM;
298 end_time = g_get_monotonic_time() + 2000 * G_TIME_SPAN_MILLISECOND;
299 if (!g_cond_wait_until(&info->cond, &info->mutex, end_time)) {
300 /* timeout has passed */
301 /* LCOV_EXCL_START */
302 ERR("g_cond_wait_until() return FALSE");
303 g_mutex_unlock(&info->mutex);
304 g_mutex_clear(&info->mutex);
305 g_cond_clear(&info->cond);
307 return CONTACTS_ERROR_SYSTEM;
310 g_mutex_unlock(&info->mutex);
311 g_mutex_clear(&info->mutex);
312 g_cond_clear(&info->cond);
314 if (!info && CONTACTS_ERROR_NONE != info->ret) {
315 /* LCOV_EXCL_START */
316 ERR("image_util_transform_run() Fail(%d)", info->ret);
319 return CONTACTS_ERROR_SYSTEM;
323 *p_size = info->size;
324 *p_buffer = info->buffer;
326 return CONTACTS_ERROR_NONE;
330 int ctsvc_image_util_rotate(media_packet_h packet, image_util_rotation_e rotation,
331 void **p_buffer, uint64_t *p_size)
334 transformation_h transform = NULL;
336 ret = image_util_transform_create(&transform);
337 if (IMAGE_UTIL_ERROR_NONE != ret) {
338 /* LCOV_EXCL_START */
339 ERR("image_util_transform_create() Fail(%d)", ret);
340 return CONTACTS_ERROR_SYSTEM;
344 ret = image_util_transform_set_rotation(transform, rotation);
345 if (IMAGE_UTIL_ERROR_NONE != ret) {
346 /* LCOV_EXCL_START */
347 ERR("image_util_transform_set_rotation() Fail(%d)", ret);
348 image_util_transform_destroy(transform);
349 return CONTACTS_ERROR_SYSTEM;
353 ret = _ctsvc_image_util_transform_run(transform, packet, p_buffer, p_size);
355 image_util_transform_destroy(transform);
359 int ctsvc_image_util_resize(media_packet_h packet, int width, int height,
360 void **p_buffer, uint64_t *p_size)
363 transformation_h transform = NULL;
365 ret = image_util_transform_create(&transform);
366 if (IMAGE_UTIL_ERROR_NONE != ret) {
367 /* LCOV_EXCL_START */
368 ERR("image_util_transform_create() Fail(%d)", ret);
369 return CONTACTS_ERROR_SYSTEM;
373 ret = image_util_transform_set_resolution(transform, width, height);
374 if (IMAGE_UTIL_ERROR_NONE != ret) {
375 /* LCOV_EXCL_START */
376 ERR("image_util_transform_set_resolution() Fail(%d)", ret);
377 image_util_transform_destroy(transform);
378 return CONTACTS_ERROR_SYSTEM;
382 ret = _ctsvc_image_util_transform_run(transform, packet, p_buffer, p_size);
384 image_util_transform_destroy(transform);