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