From: Jinkun Jang Date: Tue, 12 Mar 2013 16:46:21 +0000 (+0900) Subject: Tizen 2.1 base X-Git-Tag: 2.1b_release~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fapi%2Fvideo-util.git;a=commitdiff_plain;h=4a0bc18841fdc2d7bb985db22b79b9cfae2199fe Tizen 2.1 base --- diff --git a/AUTHORS b/AUTHORS new file mode 100755 index 0000000..80e2e9f --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +JongHyuk Choi +Haejeong Kim +YoungHun Kim diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..e55fe27 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,122 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(Services + "application" + "base" + "content" + "location" + "media" + "messaging" + "network" + "social" + "telephony" + "system" + ) + + +# project +SET(project_prefix "capi") +SET(prefix "/usr") +SET(version "0.0.1") +SET(maintainer "Younghun kim , Haejeong Kim") +SET(description "A Video Utility library in Tizen Native API") +SET(service "media") +SET(submodule "video-util") + +# for package file +SET(dependents "dlog mm-transcode capi-base-common") +SET(pc_dependents "capi-base-common") + +SET(fw_name "${project_prefix}-${service}-${submodule}") + +PROJECT(${fw_name}) + +SET(CMAKE_INSTALL_PREFIX ${prefix}) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(VERSION ${version}) + +SET(INC_DIR include) +INCLUDE_DIRECTORIES(${INC_DIR}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_name} REQUIRED ${dependents}) +FOREACH(flag ${${fw_name}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +IF("${ARCH}" MATCHES "^arm.*") + ADD_DEFINITIONS("-DTARGET") +ENDIF("${ARCH}" MATCHES "^arm.*") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DTIZEN_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +aux_source_directory(src SOURCES) +ADD_LIBRARY(${fw_name} SHARED ${SOURCES}) + +TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}) + +SET_TARGET_PROPERTIES(${fw_name} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + + +INSTALL(TARGETS ${fw_name} DESTINATION lib) +INSTALL( + DIRECTORY ${INC_DIR}/ DESTINATION include/${service} + FILES_MATCHING + PATTERN "*_private.h" EXCLUDE + PATTERN "${INC_DIR}/*.h" + ) + +SET(PC_NAME ${fw_name}) +SET(PC_REQUIRED ${pc_dependents}) +SET(PC_LDFLAGS -l${fw_name}) + +CONFIGURE_FILE( + ${fw_name}.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc + @ONLY +) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig) + +ADD_SUBDIRECTORY(test) + +IF(UNIX) + +ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution) +ADD_CUSTOM_COMMAND( + DEPENDS clean + COMMENT "distribution clean" + COMMAND find + ARGS . + -not -name config.cmake -and \( + -name tester.c -or + -name Testing -or + -name CMakeFiles -or + -name cmake.depends -or + -name cmake.check_depends -or + -name CMakeCache.txt -or + -name cmake.check_cache -or + -name *.cmake -or + -name Makefile -or + -name core -or + -name core.* -or + -name gmon.out -or + -name install_manifest.txt -or + -name *.pc -or + -name *~ \) + | grep -v TC | xargs rm -rf + TARGET distclean + VERBATIM +) + +ENDIF(UNIX) diff --git a/LICENSE.APLv2.0 b/LICENSE.APLv2.0 new file mode 100755 index 0000000..5554685 --- /dev/null +++ b/LICENSE.APLv2.0 @@ -0,0 +1,204 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..ffbca8e --- /dev/null +++ b/NOTICE @@ -0,0 +1,4 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE file for Apache License terms and conditions. + diff --git a/capi-media-video-util.manifest b/capi-media-video-util.manifest new file mode 100755 index 0000000..a76fdba --- /dev/null +++ b/capi-media-video-util.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/capi-media-video-util.pc.in b/capi-media-video-util.pc.in new file mode 100755 index 0000000..afda32e --- /dev/null +++ b/capi-media-video-util.pc.in @@ -0,0 +1,15 @@ + +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=/usr/lib +includedir=/usr/include/media + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} + diff --git a/include/video_util.h b/include/video_util.h new file mode 100755 index 0000000..7363e27 --- /dev/null +++ b/include/video_util.h @@ -0,0 +1,282 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __TIZEN_MEDIA_VIDEO_UTIL_H__ +#define __TIZEN_MEDIA_VIDEO_UTIL_H__ + + +#include + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @addtogroup CAPI_MEDIA_VIDEO_UTIL_MODULE + * @{ + */ + +/** + * @brief Creates a handle to video util. + * @details This function creates a handle to video util. + * @remarks The @a video util handle must be released with video_util_destroy() by you. + * @param[out] handle A handle to video util + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VIDEO_UTIL_ERROR_OUT_OF_MEMORY Out of memory + * @see video_util_destroy() + * + */ +int video_util_create(video_util_h *handle); + +/** + * @brief Destroys a handle to video util. + * @details The function frees all resources related to the video util handle. The video util + * handle no longer can be used to perform any operation. A new video util handle + * has to be created before the next usage. + * + * @param[in] handle The handle to video util + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @see video_util_create() + * + */ +int video_util_destroy(video_util_h handle); + +/** + * @brief Sets the video util's file path. + * @details This function sets the @a source path to transcode. + * @param[in] handle The handle to video util + * @param[in] path The source file path + * @return return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VIDEO_UTIL_ERROR_OUT_OF_MEMORY Out of memory + * @see video_util_create() + * @see video_util_destroy() + */ +int video_util_set_file_path(video_util_h handle, const char *path); + +/** + * @brief Sets the video util's accurate mode. + * @remarks If you do not set, the default value is @c false. + * @param[in] handle The handle to video util + * @param [in] mode @c true, user can get an accurated frame for given the duration in video_util_start_transcoding()\n + * @c false, user can only get the nearest i-frame + * @return return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @see video_util_create() + * @see video_util_destroy() + */ +int video_util_set_accurate_mode(video_util_h handle, bool mode); + + +/** + * @brief Sets the video codec for encoding video stream. + * @remarks You can get available list of video codec by using video_util_foreach_supported_video_codec().\n + * If you do not set, the default codec is #VIDEO_UTIL_VIDEO_CODEC_MPEG4. + * @param[in] handle The handle to video util + * @param[in] codec The video codec + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @see video_util_create() + * @see video_util_destroy() + * @see video_util_get_video_codec() + * @see video_util_foreach_supported_video_codec() + */ +int video_util_set_video_codec(video_util_h handle, video_util_video_codec_e codec); + +/** + * @brief Sets the audio codec for encoding audio stream. + * @remarks You can get available list of audio codec by using video_util_foreach_supported_audio_codec().\n + * If you do not set, the default codec is #VIDEO_UTIL_AUDIO_CODEC_AAC. + * @param[in] handle The handle to video util + * @param[in] codec The audio codec + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @see video_util_create() + * @see video_util_destroy() + * @see video_util_get_audio_codec() + * @see video_util_foreach_supported_audio_codec() + */ +int video_util_set_audio_codec(video_util_h handle, video_util_audio_codec_e codec); + +/** + * @brief Sets the file format for transcoding media stream. + * @remarks You can get available list of media format by using video_util_foreach_supported_file_format().\n + * If you do not set, the default file format is #VIDEO_UTIL_FILE_FORMAT_3GP. + * @param[in] handle The handle to video util + * @param[in] format The media file format + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @see video_util_create() + * @see video_util_destroy() + * @see video_util_get_file_format() + * @see video_util_foreach_supported_file_format() + */ +int video_util_set_file_format(video_util_h handle, video_util_file_format_e format); + +/** + * @brief Sets the resolution(width and height). + * @remarks If you do not set, the default resolution is original size. + * @param[in] handle The handle to video util + * @param[in] width The media's width, if the width is 0, it set original size.(minimum value is 128) + * @param[in] height The media's height, if the height is 0, it set original size.(minimum value is 96) + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @see video_util_create() + * @see video_util_destroy() + * @see video_util_get_resolution() + */ +int video_util_set_resolution(video_util_h handle, int width, int height); + +/** + * @brief Sets the frame rate. + * @remarks If fps is set 0, the default is original fps from source. + * @param[in] handle The handle to video util + * @param[in] fps The frame rate(minimum value is 5, maximum value is 30) + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_EROR_NONE Successful + * @retval #VIDEO_UTIL_EROR_INVALID_PARAMETER Invalid parameter + * @see video_util_create() + * @see video_util_destroy() + */ +int video_util_set_fps(video_util_h handle, int fps); + +/** + * @brief Transcodes the video for given video util handle. + * @details This function starts the transcoding from start time and for given duration.\n +#video_util_transcoding_progress_cb() function is called during the video transcoding regularly after some interval.\n +#video_util_transcoding_completed_cb() function is called and the transcoded video will be saved at the given output path when transcoding is finished corresponding callback. + * @remarks If there is already exists same file in file system, then old file will be overwritten. + * @param[in] handle The handle to video util + * @param[in] start The start position to transcode + * @param[in] duration The duration is in seconds.\n + If duration is 0, transcoding happens until end of the video. + * @param[out] out_path The file path to save + * @param[in] progress_cb The callback function to invoke + * @param[in] completed_cb The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VIDEO_UTIL_ERROR_INVALID_OPERATION Invalid operation + * @see video_util_create() + * @see video_util_destroy() + * @see video_util_transcoding_progress_cb() + * @see video_util_transcoding_completed_cb() + * @see video_util_get_progress_transcoding() + * @see video_util_cancel_transcoding() + */ +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); + +/** + * @brief Cancels to transcode the video for given video util handle. + * @details This function cancels the transcoding for given video util handle.\n + * @remarks If this function is invoked during transcoding, the data transcoded is discard. + * @param[in] handle The handle to video util + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VIDEO_UTIL_ERROR_INVALID_OPERATION Invalid operation + * @see video_util_create() + * @see video_util_destroy() + * @see video_util_start_transcoding() + */ +int video_util_cancel_transcoding(video_util_h handle); + +/** + * @brief Retreives the current position and duration of the video transcoding. + * @param[in] handle The handle to video util + * @param[out] current_position The transcoded current position + * @param[out] duration The duration is in seconds.\n + If duration is 0, transcoding happens until end of the video. + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @pre video_util_start_transcoding() + * @see video_util_create() + * @see video_util_destroy() + */ +int video_util_get_progress_transcoding(video_util_h handle, unsigned long *current_position, unsigned long *duration); + +/** + * @brief Retrieves all supported media format by invoking a specific callback for each supported media format. + * @remarks The callback invocation depends on the codec. + * @param[in] handle The handle to video util + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @post video_util_supported_file_format_cb() will be invoked + * @see video_util_get_file_format() + * @see video_util_set_file_format() + * @see video_util_supported_file_format_cb() + */ +int video_util_foreach_supported_file_format(video_util_h handle, video_util_supported_file_format_cb callback, void *user_data); + +/** + * @brief Retrieves all supported video encoder by invoking a specific callback for each supported video encoder. + * @remarks The callback invocation depends on the file format. + * @param[in] handle The handle to video util + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @post video_util_supported_video_encoder_cb() will be invoked + * @see video_util_get_video_codec() + * @see video_util_set_video_codec() + * @see video_util_supported_video_encoder_cb() + */ +int video_util_foreach_supported_video_codec(video_util_h handle, video_util_supported_video_encoder_cb callback, void *user_data); + +/** + * @brief Retrieves all supported audio encoder by invoking a specific callback for each supported audio encoder. + * @remarks The callback invocation depends on the file format. + * @param[in] handle The handle to video util + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #VIDEO_UTIL_ERROR_NONE Successful + * @retval #VIDEO_UTIL_ERROR_INVALID_PARAMETER Invalid parameter + * @post video_util_supported_audio_encoder_cb() will be invoked + * @see video_util_get_audio_codec() + * @see video_util_set_audio_codec() + * @see video_util_supported_audio_encoder_cb() + */ +int video_util_foreach_supported_audio_codec(video_util_h handle, video_util_supported_audio_encoder_cb callback, void *user_data); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*__TIZEN_MEDIA_VIDEO_UTIL_H__ */ diff --git a/include/video_util_private.h b/include/video_util_private.h new file mode 100755 index 0000000..9bed25b --- /dev/null +++ b/include/video_util_private.h @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __TIZEN_VIDEO_UTIL_PRIVATE_H__ +#define __TIZEN_VIDEO_UTIL_PRIVATE_H__ + +#include +#include +#include + +typedef bool (*video_util_supported_type_cb)(int type, void *user_data); + +typedef struct +{ + char *input_path; + bool accurate_mode; + video_util_video_codec_e video_codec; + video_util_audio_codec_e audio_codec; + video_util_file_format_e file_format; + int width; + int height; + int fps; + MMHandleType transcode_h; +}video_util_s; + +typedef struct +{ + void *user_data; + video_util_transcoding_completed_cb transcode_completed_cb; +}video_util_cb_s; + +typedef struct +{ + void *user_data; + video_util_supported_type_cb supported_type_cb; +}video_util_type_cb_s; + +typedef enum +{ + VIDEO_UTIL_TYPE_FORMAT = 0, + VIDEO_UTIL_TYPE_VIDEO_ENC, + VIDEO_UTIL_TYPE_AUDIO_ENC +}video_util_type_e; + +#endif /*__TIZEN_VIDEO_UTIL_PRIVATE_H__*/ diff --git a/include/video_util_type.h b/include/video_util_type.h new file mode 100755 index 0000000..0e71ce4 --- /dev/null +++ b/include/video_util_type.h @@ -0,0 +1,159 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __TIZEN_MEDIA_VIDEO_UTIL_TYPE_H__ +#define __TIZEN_MEDIA_VIDEO_UTIL_TYPE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef DEPRECATED_API +#define DEPRECATED_API __attribute__ ((deprecated)) +#endif + + +#define VIDEO_UTIL_ERROR_CLASS TIZEN_ERROR_MULTIMEDIA_CLASS | 0x90 + +/** +* @addtogroup CAPI_MEDIA_VIDEO_UTIL_MODULE +* @{ +*/ + +/** + * @ingroup CAPI_MEDIA_VIDEO_UTIL_MODULE + * @brief The enumerations of video util error + */ +typedef enum +{ + VIDEO_UTIL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + VIDEO_UTIL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + VIDEO_UTIL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + VIDEO_UTIL_ERROR_INVALID_OPERATION = VIDEO_UTIL_ERROR_CLASS | 0x01, /**< Invalid operation */ + VIDEO_UTIL_ERROR_BUSY = VIDEO_UTIL_ERROR_CLASS | 0x02, /**< Transcoding is already running */ +} video_util_error_e; + +/** + * @ingroup CAPI_MEDIA_VIDEO_UTIL_MODULE + * @brief The enumerations of video codec + */ +typedef enum +{ + VIDEO_UTIL_VIDEO_CODEC_MPEG4 = 0, /**< MPEG4 */ + VIDEO_UTIL_VIDEO_CODEC_H263, /**< H.263 */ + VIDEO_UTIL_VIDEO_CODEC_H264, /**< H.264 */ + VIDEO_UTIL_VIDEO_CODEC_NONE /**< no transcoding for video */ + +}video_util_video_codec_e; + +/** + * @ingroup CAPI_MEDIA_VIDEO_UTIL_MODULE + * @brief The enumerations of audio codec + */ +typedef enum +{ + VIDEO_UTIL_AUDIO_CODEC_AAC = 0, /**< AAC */ + VIDEO_UTIL_AUDIO_CODEC_AMRNB, /**< AMRNB */ + VIDEO_UTIL_AUDIO_CODEC_NONE /**< no transcoding for audio */ +}video_util_audio_codec_e; + + +/** + * @ingroup CAPI_MEDIA_VIDEO_UTIL_MODULE + * @brief The enumerations of media format + */ +typedef enum +{ + VIDEO_UTIL_FILE_FORMAT_3GP = 0, /**< 3GP */ + VIDEO_UTIL_FILE_FORMAT_MP4, /**< MP4 */ + VIDEO_UTIL_FILE_FORMAT_MAX /**< MAX */ +}video_util_file_format_e; + +/** + * @ingroup CAPI_MEDIA_VIDEO_UTIL_MODULE + * @brief The handle to video util + */ +typedef struct video_util_s *video_util_h; + +/** + * @ingroup CAPI_MEDIA_VIDEO_UTIL_MODULE + * @brief Called during the video transcoding regularly. + The interval of callback invocation depends on the framework. + * + * @param[in] current_position The current position in milliseconds + * @param[in] duration The duration in seconds + * @param[in] user_data The user data passed from the callback registration function + * @pre This callback function is invoked if you register this callback using video_util_set_progress_transcoding_cb(). + * @see video_util_start_transcoding() + */ +typedef void (*video_util_transcoding_progress_cb)(unsigned long current_position, unsigned long duration, void *user_data); + +/** + * @ingroup CAPI_MEDIA_VIDEO_UTIL_MODULE + * @brief Called when transcoding is finished just before storing in the file. + * + * @param[in] error_code The error code of video util + * @param[in] user_data The user data passed from the callback registration function + * @pre video_util_start_transcoding() will invoke this function. + */ +typedef void (*video_util_transcoding_completed_cb)(video_util_error_e error_code, void *user_data); + +/** + * @brief Gets called iteratively to notify you of supported file formats. + * @param[in] format The format of media files + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop + * @pre video_util_foreach_supported_file_format() will invoke this callback. + */ +typedef bool (*video_util_supported_file_format_cb)(video_util_file_format_e format, void *user_data); + +/** + * @brief Gets called iteratively to notify you of supported video codec. + * @param[in] format The codec of video + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop + * @pre video_util_foreach_supported_video_codec() will invoke this callback. + */ +typedef bool (*video_util_supported_video_encoder_cb)(video_util_video_codec_e codec, void *user_data); + + +/** + * @brief Gets called iteratively to notify you of supported audio codec. + * @param[in] format The codec of audio + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop + * @pre video_util_foreach_supported_audio_codec() will invoke this callback. + */ +typedef bool (*video_util_supported_audio_encoder_cb)(video_util_audio_codec_e codec, void *user_data); + +__attribute__ ((deprecated)) typedef bool (*video_util_progress_transcoding_cb)(video_util_error_e error, unsigned long current_position, unsigned long duration, void *user_data); + + + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /*__TIZEN_MEDIA_VIDEO_UTIL_TYPE_H__*/ diff --git a/packaging/capi-media-video-util.spec b/packaging/capi-media-video-util.spec new file mode 100755 index 0000000..e244301 --- /dev/null +++ b/packaging/capi-media-video-util.spec @@ -0,0 +1,60 @@ +Name: capi-media-video-util +Summary: A Video Utility library in Tizen Native API +Version: 0.1.5 +Release: 0 +Group: System/Libraries +License: Apache License, Version 2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(mm-common) +BuildRequires: pkgconfig(mm-transcode) +BuildRequires: pkgconfig(capi-base-common) + +BuildRequires: cmake +BuildRequires: gettext-devel + +%description +A Video Utility library in Tizen Native API + + +%package devel +Summary: A Video Utility library in Tizen Native API (Developement) +Group: TO_BE_FILLED +Requires: %{name} = %{version}-%{release} +Requires: pkgconfig(dlog) +Requires: pkgconfig(mm-common) +Requires: pkgconfig(mm-transcode) +Requires: pkgconfig(capi-base-common) + +%description devel +A Video Utility library in Tizen Native API (Developement) + +%prep +%setup -q + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install +mkdir -p %{buildroot}/%{_datadir}/license +cp -rf %{_builddir}/%{name}-%{version}/LICENSE.APLv2.0 %{buildroot}/%{_datadir}/license/%{name} + +%post + +%postun + + +%files +%manifest capi-media-video-util.manifest +%{_libdir}/lib*.so.* +%{_datadir}/license/%{name} + +%files devel +%{_libdir}/lib*.so +%{_libdir}/pkgconfig/*.pc +%{_includedir}/media/*.h + diff --git a/src/video_util.c b/src/video_util.c new file mode 100755 index 0000000..903f362 --- /dev/null +++ b/src/video_util.c @@ -0,0 +1,871 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "CAPI_MEDIA_VIDEO_UTIL" + +#define UTIL_SAFE_FREE(src) { if(src) {free(src); src = NULL;}} +#define UTIL_STRING_VALID(str) \ + ((str != NULL && strlen(str) > 0) ? true : false) + +#define VIDEO_UTIL_MINIMUM_WIDTH 128 +#define VIDEO_UTIL_MINIMUM_HEIGHT 96 +#define VIDEO_UTIL_MINIMUM_DURATION 1000 /*1 sec*/ +#define VIDEO_UTIL_MINIMUM_FPS 5 +#define VIDEO_UTIL_MAXIMUM_FPS 30 + +static int __video_util_create_transcode_handle(video_util_s *handle); +static int __video_util_destroy_transcode_handle(video_util_s *handle); +static int __video_util_check_transcode_is_busy(video_util_s * handle, bool *is_busy); +static bool __video_util_check_video_codec(video_util_video_codec_e video_codec); +static bool __video_util_check_audio_codec(video_util_audio_codec_e audio_codec); +static bool __video_util_check_file_format(video_util_file_format_e file_format); +static bool __video_util_check_resolution(int width, int height); +static bool __video_util_check_duration(int duration); +static bool __video_util_check_fps(int fps); +static video_util_error_e __video_util_error_convert(int error); +static void __video_util_transcode_completed_cb(int error, void *user_data); +static bool __video_util_type_callback(int codec_type, void *user_data); +static int __video_util_foreach_supported_type(video_util_type_e type, video_util_supported_type_cb callback, void *user_data); + +static int __video_util_create_transcode_handle(video_util_s *handle) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + MMHandleType transcode_h = 0; + + ret = mm_transcode_create(&transcode_h); + if(ret != MM_ERROR_NONE) + { + if(ret == MM_ERROR_INVALID_ARGUMENT) + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + else + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } + } + + ret = mm_transcode_prepare(transcode_h, handle->input_path, handle->file_format, handle->video_codec, handle->audio_codec); + if(ret != MM_ERROR_NONE) + { + if(ret == MM_ERROR_INVALID_ARGUMENT) + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + else + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } + } + + handle->transcode_h = transcode_h; + + return ret; +} + +//when should make new trandcode handle? input_filepath or file_format or video_codec or audio_codec is modified +static int __video_util_destroy_transcode_handle(video_util_s *handle) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + + if(handle->transcode_h) + { + ret = mm_transcode_destroy(handle->transcode_h); + LOGI("mm_transcode_destroy [%d]\n", ret); + if(ret != MM_ERROR_NONE) + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } + } + + handle->transcode_h = 0; + + return ret; +} + +int __video_util_check_transcode_is_busy(video_util_s * handle, bool *is_busy) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + + if(handle->transcode_h) + { + ret = mm_transcode_is_busy(handle->transcode_h, is_busy); + if(ret != MM_ERROR_NONE) + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } + } + else + { + *is_busy = false; + } + + return ret; +} + +static bool __video_util_check_video_codec(video_util_video_codec_e video_codec) +{ + if((video_codec < 0) || (video_codec > VIDEO_UTIL_VIDEO_CODEC_NONE )) + { + LOGE("invalid video_codec [%d]", video_codec); + return false; + } + + return true; +} + +static bool __video_util_check_audio_codec(video_util_audio_codec_e audio_codec) +{ + if((audio_codec < 0) || (audio_codec > VIDEO_UTIL_AUDIO_CODEC_NONE )) + { + LOGE("invalid audio_codec [%d]", audio_codec); + return false; + } + + return true; +} + +static bool __video_util_check_file_format(video_util_file_format_e file_format) +{ + if((file_format < 0) || (file_format >= VIDEO_UTIL_FILE_FORMAT_MAX )) + { + LOGE("invalid file_format [%d]", file_format); + return false; + } + + return true; +} + +static bool __video_util_check_resolution(int width, int height) +{ + if(((width > 0) && (width < VIDEO_UTIL_MINIMUM_WIDTH)) || (width < 0)) + { + LOGE("invalid width [%d]", width); + return false; + } + + if(((height > 0) && (height < VIDEO_UTIL_MINIMUM_HEIGHT)) || (height < 0)) + { + LOGE("invalid height [%d]", height); + return false; + } + + return true; +} + +static bool __video_util_check_duration(int duration) +{ + if(((duration > 0) && (duration < VIDEO_UTIL_MINIMUM_DURATION)) || (duration < 0)) + { + LOGE("invalid duration [%d]", duration); + return false; + } + + return true; +} + +static bool __video_util_check_fps(int fps) +{ + if((fps < 0) || ((fps > 0) && (fps < VIDEO_UTIL_MINIMUM_FPS)) || (fps > VIDEO_UTIL_MAXIMUM_FPS)) + { + LOGE("invalid fps [%d]", fps); + return false; + } + + return true; +} + +static video_util_error_e __video_util_error_convert(int error) +{ + LOGI("error [%d]\n", error); + + if(error == MM_ERROR_NONE) + { + return VIDEO_UTIL_ERROR_NONE; + } + else if(error == MM_ERROR_INVALID_ARGUMENT) + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + else + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } +} + +static void __video_util_transcode_completed_cb(int error, void *user_data) +{ + int error_value = VIDEO_UTIL_ERROR_NONE; + video_util_cb_s *_util_cb = (video_util_cb_s *)user_data; + + if((_util_cb != NULL) && (_util_cb->transcode_completed_cb != NULL)) + { + error_value = __video_util_error_convert(error); + _util_cb->transcode_completed_cb(error_value, _util_cb->user_data); + } + + UTIL_SAFE_FREE(_util_cb); + + return; +} + +static bool __video_util_type_callback(int codec_type, void *user_data) +{ + video_util_type_cb_s *codec_cb = (video_util_type_cb_s *)user_data; + + if(codec_cb != NULL) + { + if (codec_cb->supported_type_cb) { + codec_cb->supported_type_cb(codec_type, codec_cb->user_data); + } + } + + return true; +} + +static int __video_util_foreach_supported_type(video_util_type_e type, video_util_supported_type_cb callback, void *user_data) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + + video_util_type_cb_s *codec_cb = (video_util_type_cb_s*)calloc(1, sizeof(video_util_type_cb_s)); + codec_cb->user_data = user_data; + codec_cb->supported_type_cb = (video_util_supported_type_cb)callback; + + if(type == VIDEO_UTIL_TYPE_FORMAT) + { + ret = mm_transcode_get_supported_container_format((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb); + } + else if(type == VIDEO_UTIL_TYPE_VIDEO_ENC) + { + ret = mm_transcode_get_supported_video_encoder((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb); + } + else if(type == VIDEO_UTIL_TYPE_AUDIO_ENC) + { + ret = mm_transcode_get_supported_audio_encoder((mm_transcode_support_type_callback)__video_util_type_callback, (void *)codec_cb); + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + UTIL_SAFE_FREE(codec_cb); + + return ret; +} + +int video_util_create(video_util_h *handle) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + + LOGI("enter \n"); + + if(handle == NULL) + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + video_util_s *_handle = (video_util_s*)calloc(1,sizeof(video_util_s)); + if(_handle == NULL) + { + LOGE("OUT_OF_MEMORY(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_OUT_OF_MEMORY; + } + + _handle->input_path = NULL; + _handle->accurate_mode = false; + _handle->video_codec = 0; + _handle->audio_codec = 0; + _handle->file_format = 0; + _handle->width = 0; + _handle->height = 0; + _handle->fps = 0; + _handle->transcode_h = 0; + + *handle = (video_util_h)_handle; + + LOGI("leave \n"); + + return ret; +} + +int video_util_destroy(video_util_h handle) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + LOGI("enter \n"); + + if(!_handle) + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + ret = __video_util_destroy_transcode_handle(_handle); + + UTIL_SAFE_FREE(_handle->input_path); + UTIL_SAFE_FREE(_handle); + + LOGI("leave \n"); + + return ret; +} + +int video_util_set_file_path(video_util_h handle, const char *file_path) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + bool is_busy = false; + + if((_handle != NULL) && (UTIL_STRING_VALID(file_path))) + { + LOGI("file_path [%s]\n", file_path); + + if(_handle->input_path != NULL) + { + ret = __video_util_check_transcode_is_busy(_handle, &is_busy); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + + if(is_busy) + { + LOGE("BUSY!! Transcoding is already running.\n"); + return VIDEO_UTIL_ERROR_BUSY; + } + else + { + ret = __video_util_destroy_transcode_handle(_handle); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + + UTIL_SAFE_FREE(_handle->input_path); + } + } + + _handle->input_path = strdup(file_path); + if(_handle->input_path == NULL) + { + LOGE("OUT_OF_MEMORY(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_OUT_OF_MEMORY; + } + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_get_file_path(video_util_h handle, char **file_path) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && file_path) + { + if(UTIL_STRING_VALID(_handle->input_path)) + { + *file_path = strdup(_handle->input_path); + if(*file_path == NULL) + { + LOGE("OUT_OF_MEMORY(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_OUT_OF_MEMORY; + } + } + else + { + *file_path = NULL; + } + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_set_accurate_mode(video_util_h handle, bool accurate_mode) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + LOGI("accurate_mode [%d]\n", accurate_mode); + + if(_handle != NULL) + { + _handle->accurate_mode= accurate_mode; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_get_accurate_mode(video_util_h handle, bool *accurate_mode) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && accurate_mode) + { + *accurate_mode = _handle->accurate_mode; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_set_video_codec(video_util_h handle, video_util_video_codec_e codec) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + bool is_busy = false; + + LOGI("video_codec [%d]\n", codec); + + if((_handle != NULL) && (__video_util_check_video_codec(codec))) + { + ret = __video_util_check_transcode_is_busy(_handle, &is_busy); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + + if(is_busy) + { + LOGE("BUSY!! Transcoding is already running.\n"); + return VIDEO_UTIL_ERROR_BUSY; + } + else + { + ret = __video_util_destroy_transcode_handle(_handle); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + } + + _handle->video_codec= codec; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_get_video_codec(video_util_h handle, video_util_video_codec_e *codec) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && codec) + { + *codec = _handle->video_codec; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_set_audio_codec(video_util_h handle, video_util_audio_codec_e codec) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + bool is_busy = false; + + LOGI("audio_codec [%d]\n", codec); + + if((_handle != NULL) && (__video_util_check_audio_codec(codec))) + { + ret = __video_util_check_transcode_is_busy(_handle, &is_busy); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + + if(is_busy) + { + LOGE("BUSY!! Transcoding is already running.\n"); + return VIDEO_UTIL_ERROR_BUSY; + } + else + { + ret = __video_util_destroy_transcode_handle(_handle); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + } + + _handle->audio_codec= codec; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_get_audio_codec(video_util_h handle, video_util_audio_codec_e *codec) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && codec) + { + *codec = _handle->audio_codec; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_set_file_format(video_util_h handle, video_util_file_format_e format) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + bool is_busy = false; + + LOGI("file_format [%d]\n", format); + + if((_handle != NULL) && (__video_util_check_file_format(format))) + { + ret = __video_util_check_transcode_is_busy(_handle, &is_busy); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + + if(is_busy) + { + LOGE("BUSY!! Transcoding is already running.\n"); + return VIDEO_UTIL_ERROR_BUSY; + } + else + { + ret = __video_util_destroy_transcode_handle(_handle); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + } + + _handle->file_format= format; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_get_file_format(video_util_h handle, video_util_file_format_e *format) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && format) + { + *format = _handle->file_format; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_set_resolution(video_util_h handle, int width, int height) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + LOGI("width [%d] height [%d]\n", width, height); + + if((_handle != NULL) && (__video_util_check_resolution(width, height))) + { + _handle->width= width; + _handle->height= height; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_get_resolution(video_util_h handle, int *width, int *height) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && width && height) + { + *width = _handle->width; + *height = _handle->height; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_set_fps(video_util_h handle, int fps) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && __video_util_check_fps(fps)) + { + _handle->fps= fps; + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +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) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + mm_seek_mode_e accurate_mode = MM_SEEK_NUM; + bool is_busy = false; + + LOGI("start [%d] duration [%d]\n", start, duration); + + if(_handle && (__video_util_check_duration(duration)) && (UTIL_STRING_VALID(_handle->input_path)) && (UTIL_STRING_VALID(out_path)) && completed_cb) + { + if(!_handle->transcode_h) + { + ret = __video_util_create_transcode_handle(_handle); + if(ret != MM_ERROR_NONE) + { + return ret; + } + + if(!_handle->transcode_h) + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } + } + else + { + ret = __video_util_check_transcode_is_busy(_handle, &is_busy); + if(ret != VIDEO_UTIL_ERROR_NONE) + return ret; + + if(is_busy) + { + LOGE("BUSY!! Transcoding is already running.\n"); + return VIDEO_UTIL_ERROR_BUSY; + } + } + + LOGI("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); + + video_util_cb_s *_util_cb = (video_util_cb_s*)calloc(1, sizeof(video_util_cb_s)); + _util_cb->user_data = user_data; + _util_cb->transcode_completed_cb = completed_cb; + + if(_handle->accurate_mode) + accurate_mode = MM_SEEK_ACCURATE; + else + accurate_mode = MM_SEEK_INACCURATE; + + ret = mm_transcode(_handle->transcode_h, _handle->width, _handle->height, _handle->fps, start, duration, accurate_mode, out_path, (mm_transcode_progress_callback)progress_cb, (mm_transcode_completed_callback)__video_util_transcode_completed_cb, (void *)_util_cb); + + if(ret != MM_ERROR_NONE) + { + if(ret == MM_ERROR_INVALID_ARGUMENT) + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + else + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } + } + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_cancel_transcoding(video_util_h handle) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && (_handle->transcode_h)) + { + ret = mm_transcode_cancel(_handle->transcode_h); + if(ret != MM_ERROR_NONE) + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_get_progress_transcoding(video_util_h handle, unsigned long *current_position, unsigned long *duration) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + int value = 0; + + if(_handle && current_position && duration) + { + if(_handle->transcode_h) + { + 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); + if(ret != MM_ERROR_NONE) + { + LOGE("INVALID_OPERATION(0x%08x)", VIDEO_UTIL_ERROR_INVALID_OPERATION); + return VIDEO_UTIL_ERROR_INVALID_OPERATION; + } + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_foreach_supported_file_format(video_util_h handle, video_util_supported_file_format_cb callback, void *user_data) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && callback) + { + ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_FORMAT, (video_util_supported_type_cb)callback, user_data); + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_foreach_supported_video_codec(video_util_h handle, video_util_supported_video_encoder_cb callback, void *user_data) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && callback) + { + ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_VIDEO_ENC, (video_util_supported_type_cb)callback, user_data); + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int video_util_foreach_supported_audio_codec(video_util_h handle, video_util_supported_audio_encoder_cb callback, void *user_data) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_s *_handle = (video_util_s*)handle; + + if(_handle && callback) + { + ret = __video_util_foreach_supported_type(VIDEO_UTIL_TYPE_AUDIO_ENC, (video_util_supported_type_cb)callback, user_data); + } + else + { + LOGE("INVALID_PARAMETER(0x%08x)", VIDEO_UTIL_ERROR_INVALID_PARAMETER); + return VIDEO_UTIL_ERROR_INVALID_PARAMETER; + } + + return ret; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100755 index 0000000..cf3dadd --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,21 @@ +SET(fw_test "${fw_name}-test") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_test} REQUIRED glib-2.0 dlog capi-base-common mm-transcode) +FOREACH(flag ${${fw_test}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") + MESSAGE(${flag}) +ENDFOREACH() + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall") + +#ADD_EXECUTABLE("system-sensor" system-sensor.c) +#TARGET_LINK_LIBRARIES("system-sensor" ${fw_name} ${${fw_test}_LDFLAGS}) + +aux_source_directory(. sources) +FOREACH(src ${sources}) + GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) + MESSAGE("${src_name}") + ADD_EXECUTABLE(${src_name} ${src}) + TARGET_LINK_LIBRARIES(${src_name} ${fw_name} ${${fw_test}_LDFLAGS}) +ENDFOREACH() diff --git a/test/video_util_test.c b/test/video_util_test.c new file mode 100755 index 0000000..6290212 --- /dev/null +++ b/test/video_util_test.c @@ -0,0 +1,204 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include + +//#define CANCEL_TEST + +typedef struct +{ + video_util_h video_h; + int idx; + int start_time; + int duration; +}test_util_s; + +GMainLoop *g_loop = NULL; +int g_make_video_cnt = 5; +int g_make_video_interval = 10000; +int g_duration = 5000; + +static int test_transcode_do(test_util_s *_util_s); + +void test_transcode_completed_cb(video_util_error_e error, void *user_data) +{ + int idx = 0; + int start_position = 0; + + test_util_s *_util_s = (test_util_s *)user_data; + printf("transcode_completed_cb============= [%2d][%d]\n", _util_s->idx, error); + + if(_util_s->idx == (g_make_video_cnt-1)) + { + g_main_loop_quit(g_loop); + return; + } + + idx = _util_s->idx + 1; + start_position = _util_s->start_time + g_make_video_interval; + _util_s->idx = idx; + _util_s->start_time = start_position; + + test_transcode_do(_util_s); + +#ifdef CANCEL_TEST + int ret = VIDEO_UTIL_ERROR_NONE; + if(_util_s->idx == 3) + { + printf("Try cancel============= [%2d]]\n", _util_s->idx); + ret = video_util_cancel_transcoding(_util_s->video_h); + if(ret != VIDEO_UTIL_ERROR_NONE) + { + printf("[%d]error video_util_cancel_transcoding [%d]\n", __LINE__, ret); + g_main_loop_quit(g_loop); + return; + } + + _util_s->idx = 4; + test_transcode_do(_util_s); + return; + } +#endif + return; +} + +void test_transcode_progress_cb(unsigned long current_position, unsigned long duration, void *user_data) +{ + test_util_s *_util_s = (test_util_s *)user_data; + + printf("transcode_progress_cb-------------- [%2d][%ld][%ld]\n", _util_s->idx, current_position, duration); + +#if 0 + unsigned long pos = 0; + unsigned long dur = 0; + video_util_get_progress_transcoding(_util_s->video_h, &pos, &dur); + printf("transcode_progress_cb-------------- [%2d][%ld][%ld]\n", _util_s->idx, pos, dur); +#endif + return; +} + +bool test_transcode_spec_cb(int value, void *user_data) +{ + if(user_data != NULL) + printf("[%s]-----------", (char*)user_data); + printf("[%d] \n", value); + + return true; +} + +bool supported_spec_check(video_util_h handle) +{ + int ret = 0; + ret = video_util_foreach_supported_file_format(handle, (video_util_supported_file_format_cb)test_transcode_spec_cb, "format_check"); + printf("[%d] video_util_foreach_supported_file_format [%d]\n", __LINE__, ret); + ret = video_util_foreach_supported_video_codec(handle, (video_util_supported_video_encoder_cb)test_transcode_spec_cb, "video_codec_check"); + printf("[%d] video_util_foreach_supported_video_codec [%d]\n", __LINE__, ret); + ret = video_util_foreach_supported_audio_codec(handle, (video_util_supported_audio_encoder_cb)test_transcode_spec_cb, "audio_codec_check"); + printf("[%d] video_util_foreach_supported_audio_codec [%d]\n", __LINE__, ret); + + return true; +} + +static int test_transcode_do(test_util_s *util_s) +{ + int ret = 0; + char test_output_file_path[128] = {0, }; + + memset(test_output_file_path, 0x00, sizeof(test_output_file_path)); + snprintf(test_output_file_path, sizeof(test_output_file_path), "/opt/media/Videos/transcode_test_%d.mp4", util_s->idx); + + printf("g_start_time[%d] duration[%d] [%s]\n", util_s->start_time, util_s->duration, test_output_file_path); + + ret = video_util_start_transcoding(util_s->video_h, util_s->start_time, util_s->duration, test_output_file_path, test_transcode_progress_cb, test_transcode_completed_cb, util_s); + if(ret != VIDEO_UTIL_ERROR_NONE) + { + printf("[%d]error video_util_start_transcoding [%d]\n", __LINE__, ret); + g_main_loop_quit(g_loop); + return ret; + } + + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret = VIDEO_UTIL_ERROR_NONE; + video_util_h video_h = NULL; + test_util_s *_util_s = NULL; + char * test_video_file_path = "/opt/usr/media/Videos/Color.mp4"; + + ret = video_util_create(&video_h); + if(ret != VIDEO_UTIL_ERROR_NONE) + { + printf("[%d]error video_util_create [%d]\n", __LINE__, ret); + } + +#if 0 + supported_spec_check(video_h); +#endif + + ret = video_util_set_file_path(video_h, test_video_file_path); + ret = video_util_set_file_format(video_h, VIDEO_UTIL_FILE_FORMAT_3GP); + ret = video_util_set_video_codec(video_h, VIDEO_UTIL_VIDEO_CODEC_MPEG4); + ret = video_util_set_audio_codec(video_h, VIDEO_UTIL_AUDIO_CODEC_AAC); + ret = video_util_set_accurate_mode(video_h, 0); + ret = video_util_set_resolution(video_h, 176, 144); + ret = video_util_set_fps(video_h, 10); + + if(ret != VIDEO_UTIL_ERROR_NONE) + { + printf("[%d]error video_util_set condition [%d]\n", __LINE__, ret); + return 0; + } + + _util_s = (test_util_s*)calloc(1,sizeof(test_util_s)); + if(_util_s == NULL) + { + printf("[%d]error calloc\n", __LINE__); + return 0; + } + + _util_s->video_h = video_h; + _util_s->idx = 0; + _util_s->start_time = 0; + _util_s->duration = g_duration; + + test_transcode_do(_util_s); + + g_loop = g_main_loop_new(NULL, FALSE); + + g_main_loop_run(g_loop); + g_main_loop_unref(g_loop); + + ret = video_util_destroy(video_h); //destory handle in cb + if(ret != VIDEO_UTIL_ERROR_NONE) + { + printf("[%d]error video_util_destroy [%d]\n", __LINE__, ret); + } + else + { + printf("[%d]Success video_util_destroy [%d]\n", __LINE__, ret); + } + + if(_util_s != NULL) + free(_util_s); + + return 0; +}