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