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