Fix build error
[platform/core/api/video-util.git] / src / video_util.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdbool.h>
20 #include <dlog.h>
21 #include <mm_transcode.h>
22 #include <mm_error.h>
23 #include <video_util.h>
24 #include <video_util_private.h>
25 #include <system_info.h>
26
27 #ifdef LOG_TAG
28 #undef LOG_TAG
29 #endif
30
31 #define LOG_TAG "CAPI_MEDIA_VIDEO_UTIL"
32
33 #define UTIL_SAFE_FREE(src)     \
34         do {                                    \
35                 if (src) {                      \
36                         free(src);              \
37                         src = NULL;             \
38                 }                                       \
39         } while (0)
40
41 #define UTIL_STRING_VALID(str) \
42         ((str != NULL && strlen(str) > 0) ? true : false)
43
44 #define VIDEO_UTIL_MINIMUM_WIDTH                        128
45 #define VIDEO_UTIL_MINIMUM_HEIGHT               96
46 #define VIDEO_UTIL_MINIMUM_DURATION             1000    /* 1 sec */
47 #define VIDEO_UTIL_MINIMUM_FPS                  5
48 #define VIDEO_UTIL_MAXIMUM_FPS                  30
49 #define VIDEO_UTIL_MAXIMUM_BPS                  4294967295UL
50
51 static int __video_util_create_transcode_handle(video_util_s *handle);
52 static int __video_util_destroy_transcode_handle(video_util_s *handle);
53 static int __video_util_check_transcode_is_busy(video_util_s * handle, bool *is_busy);
54 static bool __video_util_check_video_codec(video_util_video_codec_e video_codec);
55 static bool __video_util_check_audio_codec(video_util_audio_codec_e audio_codec);
56 static bool __video_util_check_file_format(video_util_file_format_e file_format);
57 static bool __video_util_check_resolution(int width, int height);
58 static bool __video_util_check_duration(int duration);
59 static bool __video_util_check_fps(int fps);
60 static video_util_error_e __video_util_error_convert(int error);
61 static void __video_util_transcode_progress_cb(unsigned long current_position, unsigned long duration, void *user_data);
62 static void __video_util_transcode_completed_cb(int error, void *user_data);
63 static bool __video_util_type_callback(int codec_type, void *user_data);
64 static int __video_util_foreach_supported_type(video_util_type_e type, video_util_supported_type_cb callback, void *user_data);
65
66 static int __video_util_create_transcode_handle(video_util_s *handle)
67 {
68         int ret = VIDEO_UTIL_ERROR_NONE;
69         MMHandleType transcode_h = 0;
70
71         ret = mm_transcode_create(&transcode_h);
72         if (ret != MM_ERROR_NONE) {
73                 if (ret == MM_ERROR_TRANSCODE_INVALID_VALUE) {
74                         video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
75                         return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
76                 } else if (ret == MM_ERROR_TRANSCODE_NOT_SUPPORT_FORMAT) {
77                         video_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
78                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
79                 } else {
80                         video_util_error("INVALID_OPERATION(0x%08x)", ret);
81                         return VIDEO_UTIL_ERROR_INVALID_OPERATION;
82                 }
83         }
84
85         ret = mm_transcode_prepare(transcode_h, handle->input_path, handle->file_format, handle->video_codec, handle->audio_codec);
86         if (ret != MM_ERROR_NONE) {
87                 if (ret == MM_ERROR_TRANSCODE_INVALID_VALUE) {
88                         video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
89                         ret = VIDEO_UTIL_ERROR_INVALID_PARAMETER;
90                 } else if (ret == MM_ERROR_TRANSCODE_NOT_SUPPORT_FORMAT) {
91                         video_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
92                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
93                 } else {
94                         video_util_error("INVALID_OPERATION(0x%08x)", ret);
95                         ret = VIDEO_UTIL_ERROR_INVALID_OPERATION;
96                 }
97         }
98
99         if (ret == MM_ERROR_NONE)
100                 handle->transcode_h = transcode_h;
101         else
102                 __video_util_destroy_transcode_handle(handle);
103
104         return ret;
105 }
106
107 /* when should make new trandcode handle? input_filepath or file_format or video_codec or audio_codec is modified */
108 static int __video_util_destroy_transcode_handle(video_util_s *handle)
109 {
110         int ret = VIDEO_UTIL_ERROR_NONE;
111
112         if (handle->transcode_h) {
113                 ret = mm_transcode_destroy(handle->transcode_h);
114                 if (ret != MM_ERROR_NONE) {
115                         video_util_error("INVALID_OPERATION (0x%08x)", ret);
116                         return VIDEO_UTIL_ERROR_INVALID_OPERATION;
117                 }
118         }
119
120         handle->transcode_h = 0;
121
122         return ret;
123 }
124
125 int __video_util_check_transcode_is_busy(video_util_s *handle, bool *is_busy)
126 {
127         int ret = VIDEO_UTIL_ERROR_NONE;
128
129         if (handle->transcode_h) {
130                 ret = mm_transcode_is_busy(handle->transcode_h, is_busy);
131                 if (ret != MM_ERROR_NONE) {
132                         video_util_error("INVALID_OPERATION(0x%08x)", ret);
133                         return VIDEO_UTIL_ERROR_INVALID_OPERATION;
134                 }
135         } else {
136                 *is_busy = false;
137         }
138
139         return ret;
140 }
141
142 static bool __video_util_check_video_codec(video_util_video_codec_e video_codec)
143 {
144         if ((video_codec < 0) || (video_codec > VIDEO_UTIL_VIDEO_CODEC_NONE)) {
145                 video_util_error("invalid video_codec [%d]", video_codec);
146                 return false;
147         }
148
149         return true;
150 }
151
152 static bool __video_util_check_audio_codec(video_util_audio_codec_e audio_codec)
153 {
154         if ((audio_codec < 0) || (audio_codec > VIDEO_UTIL_AUDIO_CODEC_NONE)) {
155                 video_util_error("invalid audio_codec [%d]", audio_codec);
156                 return false;
157         }
158
159         return true;
160 }
161
162 static bool __video_util_check_file_format(video_util_file_format_e file_format)
163 {
164         if ((file_format < 0) || (file_format >= VIDEO_UTIL_FILE_FORMAT_MAX)) {
165                 video_util_error("invalid file_format [%d]", file_format);
166                 return false;
167         }
168
169         return true;
170 }
171
172 static bool __video_util_check_resolution(int width, int height)
173 {
174         if (((width > 0) && (width < VIDEO_UTIL_MINIMUM_WIDTH)) || (width < 0)) {
175                 video_util_error("invalid width [%d]", width);
176                 return false;
177         }
178
179         if (((height > 0) && (height < VIDEO_UTIL_MINIMUM_HEIGHT)) || (height < 0)) {
180                 video_util_error("invalid height [%d]", height);
181                 return false;
182         }
183
184         return true;
185 }
186
187 static bool __video_util_check_duration(int duration)
188 {
189         if (((duration > 0) && (duration < VIDEO_UTIL_MINIMUM_DURATION)) || (duration < 0)) {
190                 video_util_error("invalid duration [%d]", duration);
191                 return false;
192         }
193
194         return true;
195 }
196
197 static bool __video_util_check_fps(int fps)
198 {
199         if ((fps < 0) || ((fps > 0) && (fps < VIDEO_UTIL_MINIMUM_FPS)) || (fps > VIDEO_UTIL_MAXIMUM_FPS)) {
200                 video_util_error("invalid fps [%d]", fps);
201                 return false;
202         }
203
204         return true;
205 }
206
207 static video_util_error_e __video_util_error_convert(int error)
208 {
209         if (error == MM_ERROR_NONE) {
210                 video_util_debug("Error None");
211                 return VIDEO_UTIL_ERROR_NONE;
212         } else if (error == MM_ERROR_TRANSCODE_INVALID_VALUE) {
213                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
214                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
215         } else if (error == MM_ERROR_TRANSCODE_NOT_SUPPORT_FORMAT) {
216                 video_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
217                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
218         } else {
219                 video_util_error("INVALID_OPERATION(0x%08x)", error);
220                 return VIDEO_UTIL_ERROR_INVALID_OPERATION;
221         }
222 }
223
224 static void __video_util_transcode_progress_cb(unsigned long current_position, unsigned long duration, void *user_data)
225 {
226         video_util_s *_handle = (video_util_s *)user_data;
227
228         if ((_handle != NULL) && (_handle->_util_cb != NULL)
229                 && (_handle->_util_cb->transcode_progress_cb != NULL))
230                 _handle->_util_cb->transcode_progress_cb(current_position, duration, _handle->_util_cb->user_data);
231
232         return;
233 }
234
235 static void __video_util_transcode_completed_cb(int error, void *user_data)
236 {
237         int error_value = VIDEO_UTIL_ERROR_NONE;
238         video_util_s *_handle = (video_util_s *)user_data;
239
240         if (_handle == NULL) {
241                 video_util_error("INVALID_PARAMETER");
242                 return;
243         }
244
245         if ((_handle->_util_cb != NULL) && (_handle->_util_cb->transcode_completed_cb != NULL)) {
246                 error_value = __video_util_error_convert(error);
247                 _handle->_util_cb->transcode_completed_cb(error_value, _handle->_util_cb->user_data);
248         }
249
250         UTIL_SAFE_FREE(_handle->_util_cb);
251
252         return;
253 }
254
255 static bool __video_util_type_callback(int codec_type, void *user_data)
256 {
257         video_util_type_cb_s *codec_cb = (video_util_type_cb_s *)user_data;
258
259         if (codec_cb != NULL) {
260                 if (codec_cb->supported_type_cb)
261                         codec_cb->supported_type_cb(codec_type, codec_cb->user_data);
262         }
263
264         return true;
265 }
266
267 static int __video_util_foreach_supported_type(video_util_type_e type, video_util_supported_type_cb callback, void *user_data)
268 {
269         int ret = VIDEO_UTIL_ERROR_NONE;
270
271         video_util_type_cb_s *codec_cb = (video_util_type_cb_s *)calloc(1, sizeof(video_util_type_cb_s));
272         codec_cb->user_data = user_data;
273         codec_cb->supported_type_cb = (video_util_supported_type_cb)callback;
274
275         if (type == VIDEO_UTIL_TYPE_FORMAT)
276                 ret = mm_transcode_get_supported_container_format((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb);
277         else if (type == VIDEO_UTIL_TYPE_VIDEO_ENC)
278                 ret = mm_transcode_get_supported_video_encoder((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb);
279         else if (type == VIDEO_UTIL_TYPE_AUDIO_ENC)
280                 ret = mm_transcode_get_supported_audio_encoder((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb);
281         else {
282                 video_util_error("Invalid type (%d)", type);
283                 ret = VIDEO_UTIL_ERROR_INVALID_PARAMETER;
284         }
285
286         UTIL_SAFE_FREE(codec_cb);
287
288         return ret;
289 }
290
291 int video_util_create(video_util_h *handle)
292 {
293         int ret = VIDEO_UTIL_ERROR_NONE;
294
295         bool transcoder_supported = false;
296         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
297                 if (false == transcoder_supported) {
298                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
299                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
300                 }
301         } else {
302                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
303                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
304         }
305
306         if (handle == NULL) {
307                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
308                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
309         }
310
311         video_util_s *_handle = (video_util_s *)calloc(1, sizeof(video_util_s));
312         if (_handle == NULL) {
313                 video_util_error("OUT_OF_MEMORY(0x%08x)", VIDEO_UTIL_ERROR_OUT_OF_MEMORY);
314                 return VIDEO_UTIL_ERROR_OUT_OF_MEMORY;
315         }
316
317         _handle->input_path = NULL;
318         _handle->accurate_mode = false;
319         _handle->video_codec = 0;
320         _handle->audio_codec = 0;
321         _handle->file_format = 0;
322         _handle->width = 0;
323         _handle->height = 0;
324         _handle->fps = 0;
325         _handle->transcode_h = 0;
326         _handle->_util_cb = NULL;
327
328         *handle = (video_util_h)_handle;
329
330         return ret;
331 }
332
333 int video_util_destroy(video_util_h handle)
334 {
335         int ret = VIDEO_UTIL_ERROR_NONE;
336         video_util_s *_handle = NULL;
337         bool transcoder_supported = false;
338         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
339                 if (false == transcoder_supported) {
340                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
341                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
342                 }
343         } else {
344                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
345                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
346         }
347
348         _handle = (video_util_s *)handle;
349         if (_handle == NULL) {
350                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
351                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
352         }
353
354         ret = __video_util_destroy_transcode_handle(_handle);
355
356         UTIL_SAFE_FREE(_handle->_util_cb);
357         video_util_debug("FREE(_handle->_util_cb)");
358         UTIL_SAFE_FREE(_handle->input_path);
359         UTIL_SAFE_FREE(_handle);
360
361         return ret;
362 }
363
364 int video_util_set_file_path(video_util_h handle, const char *file_path)
365 {
366         int ret = VIDEO_UTIL_ERROR_NONE;
367         video_util_s *_handle = NULL;
368         bool is_busy = false;
369         bool transcoder_supported = false;
370         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
371                 if (false == transcoder_supported) {
372                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
373                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
374                 }
375         } else {
376                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
377                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
378         }
379
380         _handle = (video_util_s *)handle;
381         if ((_handle != NULL) && (UTIL_STRING_VALID(file_path))) {
382                 video_util_secure_info("file_path [%s]\n", file_path);
383
384                 if (_handle->input_path != NULL) {
385                         ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
386                         if (ret != VIDEO_UTIL_ERROR_NONE)
387                                 return ret;
388
389                         if (is_busy) {
390                                 video_util_error("BUSY!! Transcoding is already running.\n");
391                                 return VIDEO_UTIL_ERROR_BUSY;
392                         } else {
393                                 ret = __video_util_destroy_transcode_handle(_handle);
394                                 if (ret != VIDEO_UTIL_ERROR_NONE)
395                                         return ret;
396
397                                 UTIL_SAFE_FREE(_handle->input_path);
398                         }
399                 }
400
401                 _handle->input_path = strdup(file_path);
402                 if (_handle->input_path == NULL) {
403                         video_util_error("OUT_OF_MEMORY(0x%08x)", VIDEO_UTIL_ERROR_OUT_OF_MEMORY);
404                         return VIDEO_UTIL_ERROR_OUT_OF_MEMORY;
405                 }
406         } else {
407                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
408                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
409         }
410
411         return ret;
412 }
413
414 int video_util_set_accurate_mode(video_util_h handle, bool accurate_mode)
415 {
416         int ret = VIDEO_UTIL_ERROR_NONE;
417         video_util_s *_handle = NULL;
418         bool transcoder_supported = false;
419         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
420                 if (false == transcoder_supported) {
421                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
422                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
423                 }
424         } else {
425                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
426                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
427         }
428
429         _handle = (video_util_s *)handle;
430         if (_handle != NULL) {
431                 _handle->accurate_mode = accurate_mode;
432         } else {
433                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
434                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
435         }
436
437         return ret;
438 }
439
440 int video_util_set_video_codec(video_util_h handle, video_util_video_codec_e codec)
441 {
442         int ret = VIDEO_UTIL_ERROR_NONE;
443         video_util_s *_handle = NULL;
444         bool is_busy = false;
445         bool transcoder_supported = false;
446         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
447                 if (false == transcoder_supported) {
448                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
449                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
450                 }
451         } else {
452                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
453                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
454         }
455
456         _handle = (video_util_s *)handle;
457         if ((_handle != NULL) && (__video_util_check_video_codec(codec))) {
458                 ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
459                 if (ret != VIDEO_UTIL_ERROR_NONE)
460                         return ret;
461
462                 if (is_busy) {
463                         video_util_error("BUSY!! Transcoding is already running.\n");
464                         return VIDEO_UTIL_ERROR_BUSY;
465                 } else {
466                         ret = __video_util_destroy_transcode_handle(_handle);
467                         if (ret != VIDEO_UTIL_ERROR_NONE)
468                                 return ret;
469                 }
470
471                 _handle->video_codec = codec;
472         } else {
473                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
474                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
475         }
476
477         return ret;
478 }
479
480 int video_util_set_audio_codec(video_util_h handle, video_util_audio_codec_e codec)
481 {
482         int ret = VIDEO_UTIL_ERROR_NONE;
483         video_util_s *_handle = NULL;
484         bool is_busy = false;
485         bool transcoder_supported = false;
486         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
487                 if (false == transcoder_supported) {
488                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
489                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
490                 }
491         } else {
492                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
493                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
494         }
495
496         _handle = (video_util_s *)handle;
497         if ((_handle != NULL) && (__video_util_check_audio_codec(codec))) {
498                 ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
499                 if (ret != VIDEO_UTIL_ERROR_NONE)
500                         return ret;
501
502                 if (is_busy) {
503                         video_util_error("BUSY!! Transcoding is already running.\n");
504                         return VIDEO_UTIL_ERROR_BUSY;
505                 } else {
506                         ret = __video_util_destroy_transcode_handle(_handle);
507                         if (ret != VIDEO_UTIL_ERROR_NONE)
508                                 return ret;
509                 }
510
511                 _handle->audio_codec = codec;
512         } else {
513                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
514                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
515         }
516
517         return ret;
518 }
519
520 int video_util_set_file_format(video_util_h handle, video_util_file_format_e format)
521 {
522         int ret = VIDEO_UTIL_ERROR_NONE;
523         video_util_s *_handle = NULL;
524         bool is_busy = false;
525         bool transcoder_supported = false;
526         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
527                 if (false == transcoder_supported) {
528                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
529                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
530                 }
531         } else {
532                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
533                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
534         }
535
536         _handle = (video_util_s *)handle;
537         if ((_handle != NULL) && (__video_util_check_file_format(format))) {
538                 ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
539                 if (ret != VIDEO_UTIL_ERROR_NONE)
540                         return ret;
541
542                 if (is_busy) {
543                         video_util_error("BUSY!! Transcoding is already running.\n");
544                         return VIDEO_UTIL_ERROR_BUSY;
545                 } else {
546                         ret = __video_util_destroy_transcode_handle(_handle);
547                         if (ret != VIDEO_UTIL_ERROR_NONE)
548                                 return ret;
549                 }
550
551                 _handle->file_format = format;
552         } else {
553                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
554                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
555         }
556
557         return ret;
558 }
559
560 int video_util_set_resolution(video_util_h handle, int width, int height)
561 {
562         int ret = VIDEO_UTIL_ERROR_NONE;
563         video_util_s *_handle = NULL;
564         bool transcoder_supported = false;
565         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
566                 if (false == transcoder_supported) {
567                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
568                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
569                 }
570         } else {
571                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
572                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
573         }
574
575         _handle = (video_util_s *)handle;
576         if ((_handle != NULL) && (__video_util_check_resolution(width, height))) {
577                 _handle->width = width;
578                 _handle->height = height;
579         } else {
580                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
581                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
582         }
583
584         return ret;
585 }
586
587 int video_util_set_fps(video_util_h handle, int fps)
588 {
589         int ret = VIDEO_UTIL_ERROR_NONE;
590         video_util_s *_handle = NULL;
591         bool transcoder_supported = false;
592         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
593                 if (false == transcoder_supported) {
594                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
595                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
596                 }
597         } else {
598                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
599                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
600         }
601
602         _handle = (video_util_s *)handle;
603         if (_handle && __video_util_check_fps(fps)) {
604                 _handle->fps = fps;
605         } else {
606                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
607                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
608         }
609
610         return ret;
611 }
612
613 int video_util_start_transcoding(video_util_h handle, unsigned long start, unsigned long duration, const char *out_path, video_util_transcoding_progress_cb progress_cb, video_util_transcoding_completed_cb completed_cb, void *user_data)
614 {
615         int ret = VIDEO_UTIL_ERROR_NONE;
616         video_util_s *_handle = NULL;
617         mm_seek_mode_e accurate_mode = MM_SEEK_NUM;
618         bool is_busy = false;
619         bool transcoder_supported = false;
620         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
621                 if (false == transcoder_supported) {
622                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
623                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
624                 }
625         } else {
626                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
627                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
628         }
629
630         _handle = (video_util_s *)handle;
631         video_util_debug("start [%lu] duration [%lu]\n", start, duration);
632
633         if (_handle && (__video_util_check_duration(duration)) && (UTIL_STRING_VALID(_handle->input_path)) && (UTIL_STRING_VALID(out_path)) && completed_cb) {
634                 if (!_handle->transcode_h) {
635                         ret = __video_util_create_transcode_handle(_handle);
636                         if (ret != MM_ERROR_NONE)
637                                 return ret;
638
639                         if (!_handle->transcode_h) {
640                                 video_util_error("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION);
641                                 return VIDEO_UTIL_ERROR_INVALID_OPERATION;
642                         }
643                 } else {
644                         ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
645                         if (ret != VIDEO_UTIL_ERROR_NONE)
646                                 return ret;
647
648                         if (is_busy) {
649                                 video_util_error("BUSY!! Transcoding is already running.\n");
650                                 return VIDEO_UTIL_ERROR_BUSY;
651                         }
652                 }
653
654                 video_util_debug("width [%d] height [%d] fps [%d]v_codec [%d] a_codec [%d] file_format [%d] accurate [%d]\n", _handle->width, _handle->height, _handle->fps, _handle->video_codec, _handle->audio_codec, _handle->file_format, _handle->accurate_mode);
655
656                 _handle->_util_cb = (video_util_cb_s *)calloc(1, sizeof(video_util_cb_s));
657                 if (!_handle->_util_cb) {
658                         video_util_error("Error _util_cb");
659                         return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
660                 }
661                 _handle->_util_cb->user_data = user_data;
662                 _handle->_util_cb->transcode_completed_cb = completed_cb;
663                 _handle->_util_cb->transcode_progress_cb = progress_cb;
664
665                 if (_handle->accurate_mode)
666                         accurate_mode = MM_SEEK_ACCURATE;
667                 else
668                         accurate_mode = MM_SEEK_INACCURATE;
669
670                 ret = mm_transcode(_handle->transcode_h, _handle->width, _handle->height, _handle->fps, start, duration, accurate_mode, out_path, (mm_transcode_progress_callback)__video_util_transcode_progress_cb, (mm_transcode_completed_callback)__video_util_transcode_completed_cb, (void *)_handle);
671
672                 if (ret != MM_ERROR_NONE) {
673                         UTIL_SAFE_FREE(_handle->_util_cb);
674
675                         if (ret == MM_ERROR_TRANSCODE_INVALID_VALUE) {
676                                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
677                                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
678                         } else if (ret == MM_ERROR_TRANSCODE_NOT_SUPPORT_FORMAT) {
679                                 video_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
680                                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
681                         } else {
682                                 video_util_error("INVALID_OPERATION(0x%08x)", ret);
683                                 return VIDEO_UTIL_ERROR_INVALID_OPERATION;
684                         }
685                 }
686         } else {
687                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
688                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
689         }
690
691         return ret;
692 }
693
694 int video_util_cancel_transcoding(video_util_h handle)
695 {
696         int ret = VIDEO_UTIL_ERROR_NONE;
697         video_util_s *_handle = NULL;
698         bool transcoder_supported = false;
699         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
700                 if (false == transcoder_supported) {
701                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
702                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
703                 }
704         } else {
705                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
706                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
707         }
708
709         _handle = (video_util_s *)handle;
710         if (_handle && (_handle->transcode_h)) {
711                 ret = mm_transcode_cancel(_handle->transcode_h);
712                 if (ret != MM_ERROR_NONE) {
713                         video_util_error("INVALID_OPERATION(0x%08x)", ret);
714                         return VIDEO_UTIL_ERROR_INVALID_OPERATION;
715                 }
716         } else {
717                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
718                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
719         }
720
721         UTIL_SAFE_FREE(_handle->_util_cb);
722         video_util_debug("FREE(_handle->_util_cb)");
723
724         return ret;
725 }
726
727 int video_util_get_progress_transcoding(video_util_h handle, unsigned long *current_position, unsigned long *duration)
728 {
729         int ret = VIDEO_UTIL_ERROR_NONE;
730         video_util_s *_handle = NULL;
731         int value = 0;
732         bool transcoder_supported = false;
733         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
734                 if (false == transcoder_supported) {
735                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
736                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
737                 }
738         } else {
739                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
740                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
741         }
742
743         _handle = (video_util_s *)handle;
744         if (_handle && current_position && duration) {
745                 if (_handle->transcode_h) {
746                         ret = mm_transcode_get_attrs(_handle->transcode_h, (mm_containerformat_e *)&value, (mm_videoencoder_e *)&value, (mm_audioencoder_e *)&value, current_position, duration, (unsigned int *)&value, (unsigned int *)&value);
747                         if (ret != MM_ERROR_NONE) {
748                                 video_util_error("INVALID_OPERATION(0x%08x)", ret);
749                                 return VIDEO_UTIL_ERROR_INVALID_OPERATION;
750                         }
751                 } else {
752                         video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
753                         return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
754                 }
755         } else {
756                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
757                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
758         }
759
760         return ret;
761 }
762
763 int video_util_foreach_supported_file_format(video_util_h handle, video_util_supported_file_format_cb callback, void *user_data)
764 {
765         int ret = VIDEO_UTIL_ERROR_NONE;
766         video_util_s *_handle = NULL;
767         bool transcoder_supported = false;
768         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
769                 if (false == transcoder_supported) {
770                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
771                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
772                 }
773         } else {
774                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
775                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
776         }
777
778         _handle = (video_util_s *)handle;
779         if (_handle && callback) {
780                 ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_FORMAT, (video_util_supported_type_cb)callback, user_data);
781         } else {
782                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
783                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
784         }
785
786         return ret;
787 }
788
789 int video_util_foreach_supported_video_codec(video_util_h handle, video_util_supported_video_encoder_cb callback, void *user_data)
790 {
791         int ret = VIDEO_UTIL_ERROR_NONE;
792         video_util_s *_handle = NULL;
793         bool transcoder_supported = false;
794         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
795                 if (false == transcoder_supported) {
796                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
797                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
798                 }
799         }
800         _handle = (video_util_s *)handle;
801         if (_handle && callback) {
802                 ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_VIDEO_ENC, (video_util_supported_type_cb)callback, user_data);
803         } else {
804                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
805                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
806         }
807
808         return ret;
809 }
810
811 int video_util_foreach_supported_audio_codec(video_util_h handle, video_util_supported_audio_encoder_cb callback, void *user_data)
812 {
813         int ret = VIDEO_UTIL_ERROR_NONE;
814         video_util_s *_handle = NULL;
815         bool transcoder_supported = false;
816         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
817                 if (false == transcoder_supported) {
818                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
819                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
820                 }
821         } else {
822                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
823                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
824         }
825
826         _handle = (video_util_s *)handle;
827         if (_handle && callback) {
828                 ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_AUDIO_ENC, (video_util_supported_type_cb)callback, user_data);
829         } else {
830                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
831                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
832         }
833
834         return ret;
835 }