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