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