Fix crash during destroy(due to double free)
[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) && (_handle->_util_cb != NULL)
241                 && (_handle->_util_cb->transcode_completed_cb != NULL)) {
242                 error_value = __video_util_error_convert(error);
243                 _handle->_util_cb->transcode_completed_cb(error_value, _handle->_util_cb->user_data);
244         }
245
246         UTIL_SAFE_FREE(_handle->_util_cb);
247
248         return;
249 }
250
251 static bool __video_util_type_callback(int codec_type, void *user_data)
252 {
253         video_util_type_cb_s *codec_cb = (video_util_type_cb_s *)user_data;
254
255         if (codec_cb != NULL) {
256                 if (codec_cb->supported_type_cb)
257                         codec_cb->supported_type_cb(codec_type, codec_cb->user_data);
258         }
259
260         return true;
261 }
262
263 static int __video_util_foreach_supported_type(video_util_type_e type, video_util_supported_type_cb callback, void *user_data)
264 {
265         int ret = VIDEO_UTIL_ERROR_NONE;
266
267         video_util_type_cb_s *codec_cb = (video_util_type_cb_s *)calloc(1, sizeof(video_util_type_cb_s));
268         codec_cb->user_data = user_data;
269         codec_cb->supported_type_cb = (video_util_supported_type_cb)callback;
270
271         if (type == VIDEO_UTIL_TYPE_FORMAT)
272                 ret = mm_transcode_get_supported_container_format((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb);
273         else if (type == VIDEO_UTIL_TYPE_VIDEO_ENC)
274                 ret = mm_transcode_get_supported_video_encoder((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb);
275         else if (type == VIDEO_UTIL_TYPE_AUDIO_ENC)
276                 ret = mm_transcode_get_supported_audio_encoder((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb);
277         else {
278                 video_util_error("Invalid type (%d)", type);
279                 ret = VIDEO_UTIL_ERROR_INVALID_PARAMETER;
280         }
281
282         UTIL_SAFE_FREE(codec_cb);
283
284         return ret;
285 }
286
287 int video_util_create(video_util_h *handle)
288 {
289         int ret = VIDEO_UTIL_ERROR_NONE;
290
291         bool transcoder_supported = false;
292         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
293                 if (false == transcoder_supported) {
294                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
295                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
296                 }
297         } else {
298                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
299                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
300         }
301
302         if (handle == NULL) {
303                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
304                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
305         }
306
307         video_util_s *_handle = (video_util_s *)calloc(1, sizeof(video_util_s));
308         if (_handle == NULL) {
309                 video_util_error("OUT_OF_MEMORY(0x%08x)", VIDEO_UTIL_ERROR_OUT_OF_MEMORY);
310                 return VIDEO_UTIL_ERROR_OUT_OF_MEMORY;
311         }
312
313         _handle->input_path = NULL;
314         _handle->accurate_mode = false;
315         _handle->video_codec = 0;
316         _handle->audio_codec = 0;
317         _handle->file_format = 0;
318         _handle->width = 0;
319         _handle->height = 0;
320         _handle->fps = 0;
321         _handle->transcode_h = 0;
322         _handle->_util_cb = NULL;
323
324         *handle = (video_util_h)_handle;
325
326         return ret;
327 }
328
329 int video_util_destroy(video_util_h handle)
330 {
331         int ret = VIDEO_UTIL_ERROR_NONE;
332         video_util_s *_handle = NULL;
333         bool transcoder_supported = false;
334         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
335                 if (false == transcoder_supported) {
336                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
337                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
338                 }
339         } else {
340                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
341                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
342         }
343
344         _handle = (video_util_s *)handle;
345         if (_handle == NULL) {
346                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
347                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
348         }
349
350         ret = __video_util_destroy_transcode_handle(_handle);
351
352         UTIL_SAFE_FREE(_handle->_util_cb);
353         video_util_debug("FREE(_handle->_util_cb)");
354         UTIL_SAFE_FREE(_handle->input_path);
355         UTIL_SAFE_FREE(_handle);
356
357         return ret;
358 }
359
360 int video_util_set_file_path(video_util_h handle, const char *file_path)
361 {
362         int ret = VIDEO_UTIL_ERROR_NONE;
363         video_util_s *_handle = NULL;
364         bool is_busy = false;
365         bool transcoder_supported = false;
366         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
367                 if (false == transcoder_supported) {
368                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
369                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
370                 }
371         } else {
372                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
373                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
374         }
375
376         _handle = (video_util_s *)handle;
377         if ((_handle != NULL) && (UTIL_STRING_VALID(file_path))) {
378                 video_util_secure_info("file_path [%s]\n", file_path);
379
380                 if (_handle->input_path != NULL) {
381                         ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
382                         if (ret != VIDEO_UTIL_ERROR_NONE)
383                                 return ret;
384
385                         if (is_busy) {
386                                 video_util_error("BUSY!! Transcoding is already running.\n");
387                                 return VIDEO_UTIL_ERROR_BUSY;
388                         } else {
389                                 ret = __video_util_destroy_transcode_handle(_handle);
390                                 if (ret != VIDEO_UTIL_ERROR_NONE)
391                                         return ret;
392
393                                 UTIL_SAFE_FREE(_handle->input_path);
394                         }
395                 }
396
397                 _handle->input_path = strdup(file_path);
398                 if (_handle->input_path == NULL) {
399                         video_util_error("OUT_OF_MEMORY(0x%08x)", VIDEO_UTIL_ERROR_OUT_OF_MEMORY);
400                         return VIDEO_UTIL_ERROR_OUT_OF_MEMORY;
401                 }
402         } else {
403                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
404                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
405         }
406
407         return ret;
408 }
409
410 int video_util_set_accurate_mode(video_util_h handle, bool accurate_mode)
411 {
412         int ret = VIDEO_UTIL_ERROR_NONE;
413         video_util_s *_handle = NULL;
414         bool transcoder_supported = false;
415         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
416                 if (false == transcoder_supported) {
417                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
418                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
419                 }
420         } else {
421                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
422                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
423         }
424
425         _handle = (video_util_s *)handle;
426         if (_handle != NULL) {
427                 _handle->accurate_mode = accurate_mode;
428         } else {
429                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
430                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
431         }
432
433         return ret;
434 }
435
436 int video_util_set_video_codec(video_util_h handle, video_util_video_codec_e codec)
437 {
438         int ret = VIDEO_UTIL_ERROR_NONE;
439         video_util_s *_handle = NULL;
440         bool is_busy = false;
441         bool transcoder_supported = false;
442         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
443                 if (false == transcoder_supported) {
444                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
445                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
446                 }
447         } else {
448                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
449                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
450         }
451
452         _handle = (video_util_s *)handle;
453         if ((_handle != NULL) && (__video_util_check_video_codec(codec))) {
454                 ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
455                 if (ret != VIDEO_UTIL_ERROR_NONE)
456                         return ret;
457
458                 if (is_busy) {
459                         video_util_error("BUSY!! Transcoding is already running.\n");
460                         return VIDEO_UTIL_ERROR_BUSY;
461                 } else {
462                         ret = __video_util_destroy_transcode_handle(_handle);
463                         if (ret != VIDEO_UTIL_ERROR_NONE)
464                                 return ret;
465                 }
466
467                 _handle->video_codec = codec;
468         } else {
469                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
470                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
471         }
472
473         return ret;
474 }
475
476 int video_util_set_audio_codec(video_util_h handle, video_util_audio_codec_e codec)
477 {
478         int ret = VIDEO_UTIL_ERROR_NONE;
479         video_util_s *_handle = NULL;
480         bool is_busy = false;
481         bool transcoder_supported = false;
482         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
483                 if (false == transcoder_supported) {
484                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
485                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
486                 }
487         } else {
488                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
489                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
490         }
491
492         _handle = (video_util_s *)handle;
493         if ((_handle != NULL) && (__video_util_check_audio_codec(codec))) {
494                 ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
495                 if (ret != VIDEO_UTIL_ERROR_NONE)
496                         return ret;
497
498                 if (is_busy) {
499                         video_util_error("BUSY!! Transcoding is already running.\n");
500                         return VIDEO_UTIL_ERROR_BUSY;
501                 } else {
502                         ret = __video_util_destroy_transcode_handle(_handle);
503                         if (ret != VIDEO_UTIL_ERROR_NONE)
504                                 return ret;
505                 }
506
507                 _handle->audio_codec = codec;
508         } else {
509                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
510                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
511         }
512
513         return ret;
514 }
515
516 int video_util_set_file_format(video_util_h handle, video_util_file_format_e format)
517 {
518         int ret = VIDEO_UTIL_ERROR_NONE;
519         video_util_s *_handle = NULL;
520         bool is_busy = false;
521         bool transcoder_supported = false;
522         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
523                 if (false == transcoder_supported) {
524                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
525                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
526                 }
527         } else {
528                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
529                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
530         }
531
532         _handle = (video_util_s *)handle;
533         if ((_handle != NULL) && (__video_util_check_file_format(format))) {
534                 ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
535                 if (ret != VIDEO_UTIL_ERROR_NONE)
536                         return ret;
537
538                 if (is_busy) {
539                         video_util_error("BUSY!! Transcoding is already running.\n");
540                         return VIDEO_UTIL_ERROR_BUSY;
541                 } else {
542                         ret = __video_util_destroy_transcode_handle(_handle);
543                         if (ret != VIDEO_UTIL_ERROR_NONE)
544                                 return ret;
545                 }
546
547                 _handle->file_format = format;
548         } else {
549                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
550                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
551         }
552
553         return ret;
554 }
555
556 int video_util_set_resolution(video_util_h handle, int width, int height)
557 {
558         int ret = VIDEO_UTIL_ERROR_NONE;
559         video_util_s *_handle = NULL;
560         bool transcoder_supported = false;
561         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
562                 if (false == transcoder_supported) {
563                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
564                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
565                 }
566         } else {
567                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
568                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
569         }
570
571         _handle = (video_util_s *)handle;
572         if ((_handle != NULL) && (__video_util_check_resolution(width, height))) {
573                 _handle->width = width;
574                 _handle->height = height;
575         } else {
576                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
577                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
578         }
579
580         return ret;
581 }
582
583 int video_util_set_fps(video_util_h handle, int fps)
584 {
585         int ret = VIDEO_UTIL_ERROR_NONE;
586         video_util_s *_handle = NULL;
587         bool transcoder_supported = false;
588         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
589                 if (false == transcoder_supported) {
590                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
591                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
592                 }
593         } else {
594                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
595                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
596         }
597
598         _handle = (video_util_s *)handle;
599         if (_handle && __video_util_check_fps(fps)) {
600                 _handle->fps = fps;
601         } else {
602                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
603                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
604         }
605
606         return ret;
607 }
608
609 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)
610 {
611         int ret = VIDEO_UTIL_ERROR_NONE;
612         video_util_s *_handle = NULL;
613         mm_seek_mode_e accurate_mode = MM_SEEK_NUM;
614         bool is_busy = false;
615         bool transcoder_supported = false;
616         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
617                 if (false == transcoder_supported) {
618                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
619                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
620                 }
621         } else {
622                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
623                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
624         }
625
626         _handle = (video_util_s *)handle;
627         video_util_debug("start [%d] duration [%d]\n", start, duration);
628
629         if (_handle && (__video_util_check_duration(duration)) && (UTIL_STRING_VALID(_handle->input_path)) && (UTIL_STRING_VALID(out_path)) && completed_cb) {
630                 if (!_handle->transcode_h) {
631                         ret = __video_util_create_transcode_handle(_handle);
632                         if (ret != MM_ERROR_NONE)
633                                 return ret;
634
635                         if (!_handle->transcode_h) {
636                                 video_util_error("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION);
637                                 return VIDEO_UTIL_ERROR_INVALID_OPERATION;
638                         }
639                 } else {
640                         ret = __video_util_check_transcode_is_busy(_handle, &is_busy);
641                         if (ret != VIDEO_UTIL_ERROR_NONE)
642                                 return ret;
643
644                         if (is_busy) {
645                                 video_util_error("BUSY!! Transcoding is already running.\n");
646                                 return VIDEO_UTIL_ERROR_BUSY;
647                         }
648                 }
649
650                 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);
651
652                 _handle->_util_cb = (video_util_cb_s *)calloc(1, sizeof(video_util_cb_s));
653                 if (!_handle->_util_cb) {
654                         video_util_error("Error _util_cb");
655                         return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
656                 }
657                 _handle->_util_cb->user_data = user_data;
658                 _handle->_util_cb->transcode_completed_cb = completed_cb;
659                 _handle->_util_cb->transcode_progress_cb = progress_cb;
660
661                 if (_handle->accurate_mode)
662                         accurate_mode = MM_SEEK_ACCURATE;
663                 else
664                         accurate_mode = MM_SEEK_INACCURATE;
665
666                 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);
667
668                 if (ret != MM_ERROR_NONE) {
669                         UTIL_SAFE_FREE(_handle->_util_cb);
670
671                         if (ret == MM_ERROR_TRANSCODE_INVALID_VALUE) {
672                                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
673                                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
674                         } else if (ret == MM_ERROR_TRANSCODE_NOT_SUPPORT_FORMAT) {
675                                 video_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
676                                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
677                         } else {
678                                 video_util_error("INVALID_OPERATION(0x%08x)", ret);
679                                 return VIDEO_UTIL_ERROR_INVALID_OPERATION;
680                         }
681                 }
682         } else {
683                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
684                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
685         }
686
687         return ret;
688 }
689
690 int video_util_cancel_transcoding(video_util_h handle)
691 {
692         int ret = VIDEO_UTIL_ERROR_NONE;
693         video_util_s *_handle = NULL;
694         bool transcoder_supported = false;
695         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
696                 if (false == transcoder_supported) {
697                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
698                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
699                 }
700         } else {
701                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
702                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
703         }
704
705         _handle = (video_util_s *)handle;
706         if (_handle && (_handle->transcode_h)) {
707                 ret = mm_transcode_cancel(_handle->transcode_h);
708                 if (ret != MM_ERROR_NONE) {
709                         video_util_error("INVALID_OPERATION(0x%08x)", ret);
710                         return VIDEO_UTIL_ERROR_INVALID_OPERATION;
711                 }
712         } else {
713                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
714                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
715         }
716
717         UTIL_SAFE_FREE(_handle->_util_cb);
718         video_util_debug("FREE(_handle->_util_cb)");
719
720         return ret;
721 }
722
723 int video_util_get_progress_transcoding(video_util_h handle, unsigned long *current_position, unsigned long *duration)
724 {
725         int ret = VIDEO_UTIL_ERROR_NONE;
726         video_util_s *_handle = NULL;
727         int value = 0;
728         bool transcoder_supported = false;
729         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
730                 if (false == transcoder_supported) {
731                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
732                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
733                 }
734         } else {
735                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
736                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
737         }
738
739         _handle = (video_util_s *)handle;
740         if (_handle && current_position && duration) {
741                 if (_handle->transcode_h) {
742                         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);
743                         if (ret != MM_ERROR_NONE) {
744                                 video_util_error("INVALID_OPERATION(0x%08x)", ret);
745                                 return VIDEO_UTIL_ERROR_INVALID_OPERATION;
746                         }
747                 } else {
748                         video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
749                         return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
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
756         return ret;
757 }
758
759 int video_util_foreach_supported_file_format(video_util_h handle, video_util_supported_file_format_cb callback, void *user_data)
760 {
761         int ret = VIDEO_UTIL_ERROR_NONE;
762         video_util_s *_handle = NULL;
763         bool transcoder_supported = false;
764         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
765                 if (false == transcoder_supported) {
766                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
767                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
768                 }
769         } else {
770                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
771                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
772         }
773
774         _handle = (video_util_s *)handle;
775         if (_handle && callback) {
776                 ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_FORMAT, (video_util_supported_type_cb)callback, user_data);
777         } else {
778                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
779                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
780         }
781
782         return ret;
783 }
784
785 int video_util_foreach_supported_video_codec(video_util_h handle, video_util_supported_video_encoder_cb callback, void *user_data)
786 {
787         int ret = VIDEO_UTIL_ERROR_NONE;
788         video_util_s *_handle = NULL;
789         bool transcoder_supported = false;
790         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
791                 if (false == transcoder_supported) {
792                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
793                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
794                 }
795         }
796         _handle = (video_util_s *)handle;
797         if (_handle && callback) {
798                 ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_VIDEO_ENC, (video_util_supported_type_cb)callback, user_data);
799         } else {
800                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
801                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
802         }
803
804         return ret;
805 }
806
807 int video_util_foreach_supported_audio_codec(video_util_h handle, video_util_supported_audio_encoder_cb callback, void *user_data)
808 {
809         int ret = VIDEO_UTIL_ERROR_NONE;
810         video_util_s *_handle = NULL;
811         bool transcoder_supported = false;
812         if (0 == system_info_get_platform_bool(TRANSCODER_FEATURE_PATH, &transcoder_supported)) {
813                 if (false == transcoder_supported) {
814                         video_util_error("VIDEO_UTIL_ERROR_NOT_SUPPORTED(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
815                         return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
816                 }
817         } else {
818                 video_util_error("Error - System Info of Platform(0x%08x)", VIDEO_UTIL_ERROR_NOT_SUPPORTED);
819                 return VIDEO_UTIL_ERROR_NOT_SUPPORTED;
820         }
821
822         _handle = (video_util_s *)handle;
823         if (_handle && callback) {
824                 ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_AUDIO_ENC, (video_util_supported_type_cb)callback, user_data);
825         } else {
826                 video_util_error("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER);
827                 return VIDEO_UTIL_ERROR_INVALID_PARAMETER;
828         }
829
830         return ret;
831 }