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