From 873425f5eff94cbfa55eb740fe2135a73de27753 Mon Sep 17 00:00:00 2001 From: Joungkook Seo Date: Mon, 13 Jul 2015 09:22:56 +0900 Subject: [PATCH 2/8] Add initial code for mediademuxer [1] Update the code according to the ACR review [2] Update the code for sync with SPIN 2.4 [3] Fixed review comment of patch set(#3) [4] Sync with 2.4 and Refine code (2nd) [5] Fixed review comment of patch set(#5) Change-Id: I443660bb73e3726f92f6a5e58254fbc951abae9b Signed-off-by: Joungkook Seo --- AUTHORS | 2 + CMakeLists.txt | 112 +++ LICENSE.APLv2 | 204 ++++ NOTICE | 3 + capi-mediademuxer.manifest | 5 + capi-mediademuxer.pc.in | 13 + doc/mediademuxer_doc.h | 74 ++ include/mediademuxer.h | 372 +++++++ include/mediademuxer_error.h | 103 ++ include/mediademuxer_ini.h | 90 ++ include/mediademuxer_port.h | 564 +++++++++++ include/mediademuxer_private.h | 94 ++ include/mediademuxer_util.h | 97 ++ include/port_custom/mediademuxer_port_custom.h | 36 + include/port_ffmpeg/mediademuxer_port_ffmpeg.h | 36 + include/port_gst/mediademuxer_port_gst.h | 122 +++ packaging/capi-mediademuxer.spec | 80 ++ src/CMakeLists.txt | 4 + src/mediademuxer.c | 399 ++++++++ src/mediademuxer_ini.c | 243 +++++ src/mediademuxer_port.c | 545 ++++++++++ src/port_custom/mediademuxer_port_custom.c | 115 +++ src/port_ffmpeg/mediademuxer_port_ffmpeg.c | 119 +++ src/port_gst/mediademuxer_port_gst.c | 1280 ++++++++++++++++++++++++ test/CMakeLists.txt | 23 + test/mediademuxer_test.c | 661 ++++++++++++ 26 files changed, 5396 insertions(+) create mode 100755 AUTHORS create mode 100755 CMakeLists.txt create mode 100755 LICENSE.APLv2 create mode 100755 NOTICE create mode 100755 capi-mediademuxer.manifest create mode 100755 capi-mediademuxer.pc.in create mode 100644 doc/mediademuxer_doc.h create mode 100644 include/mediademuxer.h create mode 100755 include/mediademuxer_error.h create mode 100755 include/mediademuxer_ini.h create mode 100755 include/mediademuxer_port.h create mode 100755 include/mediademuxer_private.h create mode 100755 include/mediademuxer_util.h create mode 100755 include/port_custom/mediademuxer_port_custom.h create mode 100755 include/port_ffmpeg/mediademuxer_port_ffmpeg.h create mode 100755 include/port_gst/mediademuxer_port_gst.h create mode 100755 packaging/capi-mediademuxer.spec create mode 100755 src/CMakeLists.txt create mode 100755 src/mediademuxer.c create mode 100755 src/mediademuxer_ini.c create mode 100755 src/mediademuxer_port.c create mode 100755 src/port_custom/mediademuxer_port_custom.c create mode 100755 src/port_ffmpeg/mediademuxer_port_ffmpeg.c create mode 100755 src/port_gst/mediademuxer_port_gst.c create mode 100644 test/CMakeLists.txt create mode 100755 test/mediademuxer_test.c diff --git a/AUTHORS b/AUTHORS new file mode 100755 index 0000000..205b4f2 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Satheesan E N +Joungkook Seo diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..b064642 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,112 @@ + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_name "capi-mediademuxer") + +PROJECT(${fw_name}) + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +SET(INC_DIR include) +SET(INC_PORT_GST_DIR include/port_gst) +SET(INC_PORT_CUSTOM_DIR include/port_custom) +SET(INC_PORT_FFMPEG_DIR include/port_ffmpeg) +INCLUDE_DIRECTORIES(${INC_DIR} ${INC_PORT_GST_DIR} ${INC_PORT_CUSTOM_DIR} ${INC_PORT_FFMPEG_DIR}) + +SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0") +SET(pc_dependents "capi-base-common capi-media-tool") + +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 "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DTARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DTIZEN_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}") + +AUX_SOURCE_DIRECTORY (src MAIN_SRC) +AUX_SOURCE_DIRECTORY (src/port_gst PORT_GST_SRC) +AUX_SOURCE_DIRECTORY (src/port_custom PORT_CUST_SRC) +AUX_SOURCE_DIRECTORY (src/port_ffmpeg PORT_FFMPEG_SRC) + +LIST (APPEND SOURCES + ${MAIN_SRC} + ${PORT_FFMPEG_SRC} + ${PORT_CUST_SRC} + ${PORT_GST_SRC} + ) + +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_DIR}) +INSTALL( + DIRECTORY ${INC_DIR}/ DESTINATION include/media + FILES_MATCHING + PATTERN "mediademuxer_*.h" EXCLUDE + PATTERN "${INC_DIR}/*.h" + ) + +SET(PC_NAME ${fw_name}) +SET(PC_REQUIRED ${pc_dependents}) +SET(PC_LDFLAGS -l${fw_name}) +SET(PC_CFLAGS -I\${includedir}/media) + +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_INSTALL_DIR}/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 b/LICENSE.APLv2 new file mode 100755 index 0000000..9c13a9b --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + 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 100755 index 0000000..ccdad52 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +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-mediademuxer.manifest b/capi-mediademuxer.manifest new file mode 100755 index 0000000..a76fdba --- /dev/null +++ b/capi-mediademuxer.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/capi-mediademuxer.pc.in b/capi-mediademuxer.pc.in new file mode 100755 index 0000000..2d56d71 --- /dev/null +++ b/capi-mediademuxer.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=@LIB_INSTALL_DIR@ +includedir=/usr/include/media + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} \ No newline at end of file diff --git a/doc/mediademuxer_doc.h b/doc/mediademuxer_doc.h new file mode 100644 index 0000000..4e3c55f --- /dev/null +++ b/doc/mediademuxer_doc.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015 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_MEDIADEMUXER_DOC_H__ +#define __TIZEN_MEDIADEMUXER_DOC_H__ + +/** + * @file mediademuxer_doc.h + * @brief This file contains high level documentation of the CAPI MEDIA DEMUXER API. + */ + +/** + * @ingroup CAPI_MEDIA_FRAMEWORK + * @defgroup CAPI_MEDIADEMUXER_MODULE Media Demuxer + * @brief The @ref CAPI_MEDIADEMUXER_MODULE APIs provides functions for demuxing media data + * + * @section CAPI_MEDIADEMUXER_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_MEDIADEMUXER_MODULE_OVERVIEW Overview + * + * MEDIADEMUXER API allows :
+ * 1) To extract elementary audio, video or text data from a + * multiplexed stream
+ * 2) To choose one or multiple desired stream to extract.
+ * 3) To choose the local or remote input source.
+ * 4) To create single or multiple instances of media demuxer. One instance can demux only one
+ * input stream
+ * 5) To demux all the popular media formats such as MP4, AAC-NB, AAC-WB, MP3 etc.
+ * 6) To extract elementarty media sample information, such as timestamp, sample size, key-frame(I-frame) etc.
+ * 7) To identify encripted format
+ * 8) To seek to a different position-forward or backward- while extracting
+ *
+ * Typical Call Flow of mediamuxer APIs is:
+ * mediademuxer_create()
+ * mediademuxer_set_data_source()
+ * mediademuxer_prepare()
+ * mediademuxer_get_track_count()
+ * mediademuxer_select_track()
+ * mediademuxer_start()
+ * mediademuxer_get_track_info()
+ *
+ * while(EOS) {
+ *	if(track1 is set) {
+ *		mediademuxer_read_sample();
+ * 		if(seek_request)
+ *			mediademuxer_seek();
+ * 	}
+ *	else if(track2 is set) {
+ *		 mediademuxer_read_sample();
+ * 	}
+ * 	if(track2_not_needed)
+ * 		mediademuxer_unselect_track(track2);
+ *  }
+ * 
+ * mediademuxer_stop()
+ * mediademuxer_unprepare()
+ * mediademuxer_destroy()
+ */ + +#endif /* __TIZEN_MEDIADEMUXER_DOC_H__ */ diff --git a/include/mediademuxer.h b/include/mediademuxer.h new file mode 100644 index 0000000..2c6eb80 --- /dev/null +++ b/include/mediademuxer.h @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2015 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_MEDIADEMUXER_H__ +#define __TIZEN_MEDIADEMUXER_H__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef TIZEN_ERROR_MEDIA_DEMUXER +#define TIZEN_ERROR_MEDIA_DEMUXER -0x04000000 +#endif + +/** + * @file mediademuxer.h + * @brief This file contains the capi media demuxer API. + */ + +/** + * @addtogroup CAPI_MEDIADEMUXER_MODULE + * @{ + */ + +/** + * @brief Media Demuxer handle type. + * @since_tizen 3.0 + */ +typedef struct mediademuxer_s *mediademuxer_h; + +/** + * @brief Enumeration for media demuxer state + * @since_tizen 3.0 + */ +typedef enum { + MEDIADEMUXER_NONE, /**< The mediademuxer is not created */ + MEDIADEMUXER_IDLE, /**< The mediademuxer is created, but not prepared */ + MEDIADEMUXER_READY, /**< The mediademuxer is ready to demux media */ + MEDIADEMUXER_DEMUXING /**< The mediademuxer is demuxing media */ +} mediademuxer_state; + +/** + * @brief Enumeration for media demuxer error. + * @since_tizen 3.0 + */ +typedef enum { + MEDIADEMUXER_ERROR_NONE = TIZEN_ERROR_NONE, /*< Successful */ + MEDIADEMUXER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + MEDIADEMUXER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + MEDIADEMUXER_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ + MEDIADEMUXER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ + MEDIADEMUXER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + MEDIADEMUXER_ERROR_INVALID_STATE = TIZEN_ERROR_MEDIA_DEMUXER | 0x01, /**< Invalid state */ + MEDIADEMUXER_ERROR_INVALID_PATH = TIZEN_ERROR_MEDIA_DEMUXER | 0x02, /**< Invalid path */ + MEDIADEMUXER_ERROR_RESOURCE_LIMIT = TIZEN_ERROR_MEDIA_DEMUXER | 0x03, /**< Resource limit */ + MEDIADEMUXER_ERROR_SEEK_FAILED = TIZEN_ERROR_MEDIA_DEMUXER | 0x04, /**< Seek operation failure */ + MEDIADEMUXER_ERROR_DRM_NOT_PERMITTED = TIZEN_ERROR_MEDIA_DEMUXER | 0x05 /**< Not permitted format */ +} mediademuxer_error_e; + +/** + * @brief Called when error occurs in media demuxer. + * @details Following error codes can be delivered. + * #MEDIADEMUXER_ERROR_INVALID_OPERATION, + * #MEDIADEMUXER_ERROR_NOT_SUPPORTED, + * #MEDIADEMUXER_ERROR_INVALID_PATH, + * #MEDIADEMUXER_ERROR_RESOURCE_LIMIT, + * #MEDIADEMUXER_ERROR_SEEK_FAILED, + * #MEDIADEMUXER_ERROR_DRM_NOT_PERMITTED + * @since_tizen 3.0 + * @param[in] error The error that occurred in media demuxer + * @param[in] user_data The user data passed from the code where + * mediademuxer_set_error_cb() was invoked + * This data will be accessible from @a mediademuxer_error_cb + * @pre Create media demuxer handle by calling mediademuxer_create() function. + * @see mediademuxer_set_error_cb() + * @see mediademuxer_unset_error_cb() + */ +typedef void (*mediademuxer_error_cb)(mediademuxer_error_e error, void *user_data); + +/** + * @brief Creates a media demuxer handle for demuxing. + * @since_tizen 3.0 + * @remarks You must release @a demuxer using mediademuxer_destroy() function. + * @param[out] demuxer A new handle to media demuxer + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @post The media demuxer state will be #MEDIADEMUXER_STATE_IDLE. + * @see mediademuxer_destroy() + */ +int mediademuxer_create(mediademuxer_h *demuxer); + +/** + * @brief Sets the source path of input stream. + * @since_tizen 3.0 + * @remarks The mediastorage privilege(http://tizen.org/privilege/mediastorage) should be added if any video/audio files are used to play located in the internal storage. + * @remarks The externalstorage privilege(http://tizen.org/privilege/externalstorage) should be added if any video/audio files are used to play located in the external storage. + * @remarks You must release @a demuxer using mediademuxer_destroy() function. + * @param[in] demuxer The media demuxer handle + * @param[in] path The content location, such as the file path + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_PERMISSION_DENIED Permission denied + * @retval #MEDIADEMUXER_ERROR_INVALID_PATH Invalid path + * @pre The media muxer state will be #MEDIADEMUXER_STATE_IDLE by calling mediademuxer_create() function. + * */ +int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path); + +/** + * @brief Prepares the media demuxer for demuxing. + * @since_tizen 3.0 + * @remark User should call this before mediademuxer_start() function. + * @param[in] demuxer The media demuxer handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state should be #MEDIADEMUXER_STATE_IDLE. + * @post The media demuxer state will be #MEDIADEMUXER_STATE_READY. + * @see mediademuxer_set_data_source() + * @see mediademuxer_unprepare() + * */ +int mediademuxer_prepare(mediademuxer_h demuxer); + +/** + * @brief Gets the total track count present in the container stream. + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @param[out] count The number of tracks present + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state should be #MEDIADEMUXER_STATE_READY. + * @see mediademuxer_prepare() + * @see mediademuxer_select_track() + * */ +int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count); + +/** + * @brief Selects the track to be performed. + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @param[in] track_index The track index on which is selected for read + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state should be #MEDIADEMUXER_STATE_READY. + * @see mediademuxer_get_track_count() + * @see mediademuxer_start() + * */ +int mediademuxer_select_track(mediademuxer_h demuxer, int track_index); + +/** + * @brief Starts the media demuxer. + * @since_tizen 3.0 + * @remark User should call this before mediademuxer_read_sample() function. + * @param[in] demuxer The media demuxer handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state should be #MEDIADEMUXER_STATE_READY. + * @post The media demuxer state will be #MEDIADEMUXER_STATE_DEMUXING. + * @see mediademuxer_prepare() + * @see mediademuxer_get_track_count() + * @see mediademuxer_select_track() + * @see mediademuxer_get_track_info() + * */ +int mediademuxer_start(mediademuxer_h demuxer); + +/** + * @brief Retrieves the track format of the read sample. + * @since_tizen 3.0 + * @remarks The @a format should be released using media_format_unref() function. + * @param[in] demuxer The media demuxer handle + * @param[in] track_index The index of the track + * @param[out] format The media format handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state must be set to #MEDIADEMUXER_STATE_DEMUXING by calling + * mediademuxer_start() or set to #MEDIADEMUXER_STATE_READY by calling mediademuxer_prepare(). + * @see mediademuxer_get_track_count() + * @see mediademuxer_select_track() + * @see media_format_unref() + * @see #media_format_h + * */ +int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, + media_format_h *format); + +/** + * @brief Reads a frame(sample) of one single track. + * @since_tizen 3.0 + * @remark The @a outbuf should be released using media_packet_destroy() function. + * @remark Once this API is called, user app can call the mediatool APIs to extract + * side information such as pts, size, duration, flags etc. + * @param[in] demuxer The media demuxer handle + * @param[in] track_index The index of track of which data is needed + * @param[out] outbuf The media packet handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state should be #MEDIADEMUXER_STATE_DEMUXING. + * @see mediademuxer_start() + * @see mediademuxer_get_track_info() + * @see mediademuxer_seek() if need to seek to a particular location + * @see mediademuxer_unselect_track() + * @see mediademuxer_stop() + * @see media_packet_destroy() + * @see #media_packet_h + * */ +int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index, + media_packet_h *outbuf); + +/** + * @brief Seeks to a particular instance of time (in micro seconds). + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @param[in] pos The value of the new start position + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state +* @pre The media demuxer state should be #MEDIADEMUXER_STATE_DEMUXING. + * @see mediademuxer_read_sample() + * @see mediademuxer_stop() + * */ +int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos); + +/** + * @brief Unselects the selected track. + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @param[in] track_index The track index to be unselected + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state must be set to #MEDIADEMUXER_STATE_DEMUXING by calling + * mediademuxer_read_sample() or set to #MEDIADEMUXER_STATE_READY by calling mediademuxer_select_track(). + * @see mediademuxer_select_track() + * @see mediademuxer_read_sample() + * */ +int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index); + +/** + * @brief Stops the media demuxer. + * @since_tizen 3.0 + * @remark User can call this if need to stop demuxing if needed. + * @param[in] demuxer The media demuxer handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state must be set to #MEDIADEMUXER_STATE_DEMUXING. + * @post The media demuxer state will be in #MEDIADEMUXER_READY. + * @see mediademuxer_start() + * @see mediademuxer_unprepare() + * */ +int mediademuxer_stop(mediademuxer_h demuxer); + +/** + * @brief Resets the media demuxer. + * @since_tizen 3.0 + * @remarks User should call this before mediademuxer_destroy() function. + * @param[in] demuxer The media demuxer handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre The media demuxer state should be #MEDIADEMUXER_STATE_READY. + * @post The media demuxer state will be #MEDIADEMUXER_STATE_IDLE. + * @see mediademuxer_prepare() + * */ +int mediademuxer_unprepare(mediademuxer_h demuxer); + +/** + * @brief Removes the instance of media demuxer and clear all its context memory. + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @pre Create a media demuxer handle by calling mediademuxer_create() function. + * @post The media demuxer state will be #MEDIADEMUXER_STATE_NONE. + * @see mediademuxer_create() + * */ +int mediademuxer_destroy(mediademuxer_h demuxer); + +/** + * @brief Gets media demuxer state. + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @param[out] state The media demuxer sate + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid operation + * @pre Create a media demuxer handle by calling mediademuxer_create() function. + * @see #mediademuxer_state + * */ +int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state); + +/** + * @brief Registers a error callback function to be invoked when an error occurs. + * @details Following error codes can be delivered. + * #MEDIADEMUXER_ERROR_INVALID_OPERATION, + * #MEDIADEMUXER_ERROR_NOT_SUPPORTED, + * #MEDIADEMUXER_ERROR_INVALID_PATH, + * #MEDIADEMUXER_ERROR_RESOURCE_LIMIT, + * #MEDIADEMUXER_ERROR_SEEK_FAILED, + * #MEDIADEMUXER_ERROR_DRM_NOT_PERMITTED + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @param[in] callback Callback function pointer + * @param[in] user_data The user data passed from the code where + * mediademuxer_set_error_cb() was invoked + * This data will be accessible from @a mediademuxer_error_cb + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre Create a media demuxer handle by calling mediademuxer_create() function. + * @post mediademuxer_error_cb() will be invoked. + * @see mediademuxer_unset_error_cb() + * @see mediademuxer_error_cb() + * */ +int mediademuxer_set_error_cb(mediademuxer_h demuxer, + mediademuxer_error_cb callback, void *user_data); + +/** + * @brief Unregisters the error callback function. + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @see mediademuxer_error_cb() + * */ +int mediademuxer_unset_error_cb(mediademuxer_h demuxer); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_MEDIADEMUXER_H__ */ diff --git a/include/mediademuxer_error.h b/include/mediademuxer_error.h new file mode 100755 index 0000000..413f448 --- /dev/null +++ b/include/mediademuxer_error.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015 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_MEDIADEMUXER_ERROR_H__ +#define __TIZEN_MEDIADEMUXER_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MD_ERROR_NONE = 0, + MD_ERROR = -1, /**< codec happens error */ + MD_MEMORY_ERROR = -2, /**< codec memory is not enough */ + MD_PARAM_ERROR = -3, /**< codec parameter is error */ + MD_INVALID_ARG = -4, /** < codec has invalid arguments */ + MD_PERMISSION_DENIED = -5, + MD_INVALID_STATUS = -6, /**< codec works at invalid status */ + MD_NOT_SUPPORTED = -7, /**< codec can't support this specific video format */ + MD_INVALID_IN_BUF = -8, + MD_INVALID_OUT_BUF = -9, + MD_INTERNAL_ERROR = -10, + MD_HW_ERROR = -11, /**< codec happens hardware error */ + MD_NOT_INITIALIZED = -12, + MD_INVALID_STREAM = -13, + MD_OUTPUT_BUFFER_EMPTY = -14, + MD_OUTPUT_BUFFER_OVERFLOW = -15, /**< codec output buffer is overflow */ + MD_MEMORY_ALLOCED = -16, /**< codec has got memory and can decode one frame */ + MD_COURRPTED_INI = -17, /**< value in the ini file is not valid */ + MD_ERROR_FILE_NOT_FOUND = -18, + MD_EOS, /** read sample reached end of stream */ +} md_ret_e; + +#define MD_ERROR_CLASS 0x80000000 /**< Definition of number describing error group */ +#define MD_ERROR_COMMON_CLASS 0x80000100 /**< Category for describing common error group */ +#define MD_ERROR_GST_PORT_CLASS 0x80000200 /**< Category for describing gst_port error group */ +#define MD_ERROR_FFMPEG_PORT_CLASS 0x80000300 /**< Category for describing ffmpeg port error group */ +#define MD_ERROR_CUSTOM_PORT_CLASS 0x80000400 /**< Category for describing custom error group */ + +/* + MD_ERROR_CLASS +*/ +#define MD_ERROR_UNKNOWN (MD_ERROR_CLASS | 0x00) /**< Unclassified error */ +#define MD_ERROR_INVALID_ARGUMENT (MD_ERROR_CLASS | 0x01) /**< Invalid argument */ +#define MD_ERROR_OUT_OF_MEMORY (MD_ERROR_CLASS | 0x02) /**< Out of memory */ +#define MD_ERROR_OUT_OF_STORAGE (MD_ERROR_CLASS | 0x03) /**< Out of storage */ +#define MD_ERROR_INVALID_HANDLE (MD_ERROR_CLASS | 0x04) /**< Invalid handle */ +#define MD_ERROR_FILE_NOT_FOUND (MD_ERROR_CLASS | 0x05) /**< Cannot find file */ +#define MD_ERROR_FILE_READ (MD_ERROR_CLASS | 0x06) /**< Fail to read data from file */ +#define MD_ERROR_FILE_WRITE (MD_ERROR_CLASS | 0x07) /**< Fail to write data to file */ +#define MD_ERROR_END_OF_FILE (MD_ERROR_CLASS | 0x08) /**< End of file */ +#define MD_ERROR_NOT_SUPPORT_API (MD_ERROR_CLASS | 0x09) /**< Not supported API*/ +#define MD_ERROR_PORT_REG_FAILED (MD_ERROR_CLASS | 0x0a) /**< port regitstration failed error */ + +/* + MD_ERROR_COMMON_CLASS +*/ +#define MD_ERROR_COMMON_INVALID_ARGUMENT (MD_ERROR_COMMON_CLASS | 1) /**< Invalid argument */ +#define MD_ERROR_COMMON_NO_FREE_SPACE (MD_ERROR_COMMON_CLASS | 2) /**< Out of storage */ +#define MD_ERROR_COMMON_OUT_OF_MEMORY (MD_ERROR_COMMON_CLASS | 3) /**< Out of memory */ +#define MD_ERROR_COMMON_UNKNOWN (MD_ERROR_COMMON_CLASS | 4) /**< Unknown error */ +#define MD_ERROR_COMMON_INVALID_ATTRTYPE (MD_ERROR_COMMON_CLASS | 5) /**< Invalid argument */ +#define MD_ERROR_COMMON_INVALID_PERMISSION (MD_ERROR_COMMON_CLASS | 6) /**< Invalid permission */ +#define MD_ERROR_COMMON_OUT_OF_ARRAY (MD_ERROR_COMMON_CLASS | 7) /**< Out of array */ +#define MD_ERROR_COMMON_OUT_OF_RANGE (MD_ERROR_COMMON_CLASS | 8) /**< Out of value range*/ +#define MD_ERROR_COMMON_ATTR_NOT_EXIST (MD_ERROR_COMMON_CLASS | 9) /**< Attribute doesn't exist. */ + +/* + * MD_ERROR_GST_PORT_CLASS + */ +#define MD_ERROR_GST_PORT_NOT_INITIALIZED (MD_ERROR_GST_PORT_CLASS | 0x01) /**< GST Port instance is not initialized */ + +/* + MD_ERROR_FFMPEG_PORT_CLASS + */ +#define MD_ERROR_FFMPEG_PORT_NOT_INITIALIZED (MD_ERROR_FFMPEG_PORT_CLASS | 0x01) /**< FFMPEG Port instance is not initialized */ + +/* + MD_ERROR_CUSTOM_PORT_CLASS +*/ +#define MD_ERROR_CUSTOM_PORT_NOT_INITIALIZED (MD_ERROR_CUSTOM_PORT_CLASS | 0x01) /**< CUSTOM Port instance is not initialized */ + +/** + @} +*/ + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_MEDIADEMUXER_ERROR_H__ */ diff --git a/include/mediademuxer_ini.h b/include/mediademuxer_ini.h new file mode 100755 index 0000000..e563c08 --- /dev/null +++ b/include/mediademuxer_ini.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_ini.h + * @brief INI laoding and parsing procedures + */ + +#ifndef __TIZEN_MEDIADEMUXER_INI_H__ +#define __TIZEN_MEDIADEMUXER_INI_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MEDIADEMUXER_INI_DEFAULT_PATH "/usr/etc/mmfw_mediademuxer.ini" +#define MEDIADEMUXER_INI_MAX_STRLEN 100 +#define DEFAULT_PORT "GST_PORT" + +typedef enum { + GST_PORT = 0, + FFMPEG_PORT, + CUSTOM_PORT, +} port_mode; + +/* @ mark means the item has tested */ +typedef struct __md_ini { + port_mode port_type; + /* general */ + gchar port_name[MEDIADEMUXER_INI_MAX_STRLEN]; +} md_ini_t; + +/* NOTE : following content should be same with above default values */ +/* FIXIT : need smarter way to generate default ini file. */ +/* FIXIT : finally, it should be an external file */ +#define MEDIADEMUXER_DEFAULT_INI \ + "\ +[general] \n\ +\n\ +;Add general config parameters here\n\ +\n\ +\n\ +\n\ +[port_in_use] \n\ +\n\ +;mediademuxer_port = GST_PORT \n\ +;mediademuxer_port = FFMPEG_PORT \n\ +;mediademuxer_port = CUSTOM_PORT \n\ +mediademuxer_port = GST_PORT \n\ +\n\ +[gst_port] \n\ +\n\ +;Add gst port specific config paramters here\n\ +\n\ +\n\ +[ffmpeg_port] \n\ +\n\ +;Add ffmpeg port specific config paramters here\n\ +\n\ +\n\ +[custom_port] \n\ +\n\ +;Add custom port specific config paramters here\n\ +\n\ +\n\ +\n\ +" + +int md_ini_load(md_ini_t *ini); + +#ifdef __cplusplus +} +#endif +#endif /*__TIZEN_MEDIADEMUXER_INI_H__*/ diff --git a/include/mediademuxer_port.h b/include/mediademuxer_port.h new file mode 100755 index 0000000..86f1552 --- /dev/null +++ b/include/mediademuxer_port.h @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_port.h + * @brief general port based functions. sets specific function pointers + */ + +#ifndef __TIZEN_MEDIADEMUXER_PORT_H__ +#define __TIZEN_MEDIADEMUXER_PORT_H__ + +/*=========================================================================================== +| | +| INCLUDE FILES | +| | +========================================================================================== */ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @{ + + @par + This part describes APIs used for playback of multimedia contents. + All multimedia contents are created by a media demuxer through handle of playback. + In creating a demuxer, it displays the demuxer's status or information + by registering callback function. + + @par + In case of streaming playback, network has to be opend by using datanetwork API. + If proxy, cookies and the other attributes for streaming playback are needed, + set those attributes using mm_demuxer_set_attribute() before create demuxer. + + @par + The subtitle for local video playback is supported. Set "subtitle_uri" attribute + using mm_demuxer_set_attribute() before the application creates the demuxer. + Then the application could receive MMMessageParamType which includes subtitle string and duration. + + @par + MediaDemuxer can have 5 states, and each state can be changed by calling + described functions on "Figure1. State of MediaDemuxer". + + @par + @image html demuxer_state.jpg "Figure1. State of MediaDemuxer" width=12cm + @image latex demuxer_state.jpg "Figure1. State of MediaDemuxer" width=12cm + + @par + Most of functions which change demuxer state work as synchronous. But, mm_demuxer_start() should be used + asynchronously. Both mm_demuxer_pause() and mm_demuxer_resume() should also be used asynchronously + in the case of streaming data. + So, application have to confirm the result of those APIs through message callback function. + + @par + Note that "None" and Null" state could be reached from any state + by calling mm_demuxer_destroy() and mm_demuxer_unrealize(). + + @par +
+ + + + + + + + + + + + + + + + + + + + + + + + +
FUNCTIONPRE-STATEPOST-STATESYNC TYPE
md_create()NONENULLSYNC
md_destroy()NULLNONESYNC
md_set_data_source()NULLREADYSYNC
+ + @par + Following are the attributes supported in demuxer which may be set after initialization. \n + Those are handled as a string. + + @par +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PROPERTYTYPEVALID TYPE
"profile_uri"stringN/A
"content_duration"intrange
"content_video_width"intrange
"content_video_height"intrange
"profile_user_param"dataN/A
"profile_play_count"intrange
"streaming_type"intrange
"streaming_udp_timeout"intrange
"streaming_user_agent"stringN/A
"streaming_wap_profile"stringN/A
"streaming_network_bandwidth"intrange
"streaming_cookie"stringN/A
"streaming_proxy_ip"stringN/A
"streaming_proxy_port"intrange
"subtitle_uri"stringN/A
+ + @par + Following attributes are supported for playing stream data. Those value can be readable only and valid after starting playback.\n + Please use mm_fileinfo for local playback. + + @par +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PROPERTYTYPEVALID TYPE
"content_video_found"stringN/A
"content_video_codec"stringN/A
"content_video_track_num"intrange
"content_audio_found"stringN/A
"content_audio_codec"stringN/A
"content_audio_bitrate"intarray
"content_audio_channels"intrange
"content_audio_samplerate"intarray
"content_audio_track_num"intrange
"content_text_track_num"intrange
"tag_artist"stringN/A
"tag_title"stringN/A
"tag_album"stringN/A
"tag_genre"stringN/A
"tag_author"stringN/A
"tag_copyright"stringN/A
"tag_date"stringN/A
"tag_description"stringN/A
"tag_track_num"intrange
+ + */ + +/*=========================================================================================== +| | +| GLOBAL DEFINITIONS AND DECLARATIONS | +| | +========================================================================================== */ +/** + * @brief Called when error occurs in media demuxer. + * @details Following error codes can be delivered. + * #MEDIADEMUXER_ERROR_INVALID_OPERATION, + * #MEDIADEMUXER_ERROR_NOT_SUPPORTED, + * #MEDIADEMUXER_ERROR_INVALID_PATH, + * #MEDIADEMUXER_ERROR_RESOURCE_LIMIT, + * #MEDIADEMUXER_ERROR_SEEK_FAILED, + * #MEDIADEMUXER_ERROR_DRM_NOT_PERMITTED + * @since_tizen 3.0 + * @param[in] error The error that occurred in media demuxer + * @param[in] user_data The user data passed from the code where + * mediademuxer_set_error_cb() was invoked + * This data will be accessible from @a mediademuxer_error_cb + * @pre Create media demuxer handle by calling mediademuxer_create() function. + * @see mediademuxer_set_error_cb() + * @see mediademuxer_unset_error_cb() + */ +typedef void (*md_error_cb)(mediademuxer_error_e error, void *user_data); +/** + * Enumerations of demuxer state. + */ +/** + * Attribute validity structure + */ +typedef struct _media_port_demuxer_ops { + unsigned int n_size; + int (*init)(MMHandleType *pHandle); + int (*prepare)(MMHandleType pHandle, char *uri); + int (*get_track_count)(MMHandleType pHandle, int *count); + int (*set_track)(MMHandleType pHandle, int track); + int (*start)(MMHandleType pHandle); + int (*get_track_info)(MMHandleType pHandle, media_format_h *format, int track); + int (*read_sample)(MMHandleType pHandle, media_packet_h *outbuf, int track_indx); + int (*seek)(MMHandleType pHandle, int64_t pos1); + int (*unset_track)(MMHandleType pHandle, int track); + int (*stop)(MMHandleType pHandle); + int (*unprepare)(MMHandleType pHandle); + int (*destroy)(MMHandleType pHandle); + int (*set_error_cb)(MMHandleType demuxer, md_error_cb callback, void* user_data); + int (*get_data)(MMHandleType pHandle, char *buffer); +} media_port_demuxer_ops; + +/*=========================================================================================== +| | +| GLOBAL FUNCTION PROTOTYPES | +| | +========================================================================================== */ + +/** + * This function creates a demuxer object for parsing multimedia contents. \n + * The attributes of demuxer are created to get/set some values with application. \n + * And, proper port is selected to do the actual parsing of the mdia. + * + * @param demuxer [out] Handle of demuxer + * + * @return This function returns zero on success, or negative value with error code. \n + * Please refer 'mm_demuxer_error.h' to know it in detail. + * + * @par Example + * @code + MMHandleType demuxer; + md_create(&demuxer); + ... + md_destroy(&demuxer); + * @endcode + */ +int md_create(MMHandleType *demuxer); + +/** + * This function sets the input data source to parse. \n + * The source can be a local file or remote server file + * + * @param demuxer [in] Handle of demuxer + * @param uri [in] absolute path for the source media + * + * @return This function returns zero on success, or negative value with error code. \n + * Please refer 'mm_demuxer_error.h' to know it in detail. + * + * @par Example + * @code + MPhandle demuxer; + md_create(&demuxer); + if (md_set_data_source(demuxer) != MM_ERROR_NONE) +{ + MD_E("failed to set the source \n"); +} + md_destroy(&demuxer); + * @endcode + */ +int md_set_data_source(MMHandleType demuxer, const char *uri); + +/** + * This function releases demuxer object and all resources which were created by md_create(). \n + * And, demuxer handle will also be destroyed. + * + * @param demuxer [in] Handle of demuxer + * + * @return This function returns zero on success, or negative value with error code. + * @see md_create + * + * @par Example + * @code +if (md_destroy(g_demuxer) != MM_ERROR_NONE) +{ + MD_E("failed to destroy demuxer\n"); +} + * @endcode + */ +int md_destroy(MMHandleType demuxer); + +/** + * This function set up the internal structure of gstreamer, ffmpeg & custom to handle data set up md_set_data_source + * + * @param demuxer [in] Handle of demuxer + * + * @return This function returns zero on success, or negative value with error code. + * @see md_set_data_source + * + * @par Example + * @code +if (md_prepare(g_demuxer) != MM_ERROR_NONE) +{ + MD_E("failed to prepare demuxer\n"); +} + * @endcode + */ +int md_prepare(MMHandleType demuxer); + +/** + * This function get the total number of tracks present in the stream. + * + * @param demuxer [in] Handle of demuxer + * @param count [out] Total track number of streams available in the media + * + * @return This function returns zero on success, or negative value with error code. + * @see md_set_data_source + * + * @par Example + * @code +if (md_get_track_count(g_demuxer,count) != MM_ERROR_NONE) +{ + MD_E("failed to get count\n"); +} + * @endcode + */ +int md_get_track_count(MMHandleType demuxer, int *count); + +/** + * This function get the format of selected track present in the stream. + * + * @param demuxer [in] Handle of demuxer + * @param track [in] index for the track + * @param format [out] pointer to the Handle of media_format + * + * @return This function returns zero on success, or negative value with error code. + * + * @par Example + * @code +if (md_get_track_info(g_demuxer, format, track) != MM_ERROR_NONE) +{ + MD_E("failed to get track info\n"); +} + * @endcode + */ +int md_get_track_info(MMHandleType demuxer, int track, media_format_h *format); + +/** + * This function start the pipeline(in case of gst port it set the pipeline to play state). + * + * @param demuxer [in] Handle of demuxer + * + * @return This function returns zero on success, or negative value with error code. + */ +int md_start(MMHandleType demuxer); + +/** + * This function read a packet of data from demuxer + * + * @param demuxer [in] Handle of demuxer + * @param track_indx [in] selected track number + * @param outbuf [out] demuxed packet + * + * @return This function returns zero on success, or negative value with error code. + */ +int md_read_sample(MMHandleType demuxer, int track_indx, media_packet_h *outbuf); + +/** + * This function stop the pipeline in case of gst_port + * + * @param demuxer [in] Handle of demuxer + * + * @return This function returns zero on success, or negative value with error code. + * @see md_set_data_source + */ +int md_stop(MMHandleType demuxer); + + +/** + * This function destroy the pipeline + * + * @param demuxer [in] Handle of demuxer + * + * @return This function returns zero on success, or negative value with error code. + * @see md_set_data_source + */ +int md_unprepare(MMHandleType demuxer); + +/** + * This function is to select a track on which read need to be performed + * + * @param demuxer [in] Handle of demuxer + * @param index [in] index for the track to be selected + * + * @return This function returns zero on success, or negative value with error code. + * @see md_set_data_source + */ +int md_select_track(MMHandleType demuxer, int index); + +/** + * This function is to unselect a track on which readsample can't be performed + * + * @param demuxer [in] Handle of demuxer + * @param index [in] index for the track to be selected + * + * @return This function returns zero on success, or negative value with error code. + * @see md_set_data_source + */ +int md_unselect_track(MMHandleType demuxer, int index); + +/** + * This function is to seek to a particular position relative to current position + * + * @param demuxer [in] Handle of demuxer + * @param pos [in] relative position to seek + * + * @return This function returns zero on success, or negative value with error code. + * @see md_set_data_source + */ +int md_seek(MMHandleType demuxer, int64_t pos); + +/** + * This function is to set error call back function + * + * @param demuxer [in] Handle of demuxer + * @param callback [in] call back function pointer + * @param user_data [in] user specific data pointer + * + * @return This function returns zero on success, or negative value with error code. + */ +int md_set_error_cb(MMHandleType demuxer, md_error_cb callback, void *user_data); + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_MEDIADEMUXER_PORT_H__ */ diff --git a/include/mediademuxer_private.h b/include/mediademuxer_private.h new file mode 100755 index 0000000..a6beedf --- /dev/null +++ b/include/mediademuxer_private.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_private.h + * @brief contain information about the pError and return type, enum and structure prototype + */ + +#ifndef __TIZEN_MEDIADEMUXER_PRIVATE_H__ +#define __TIZEN_MEDIADEMUXER_PRIVATE_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "TIZEN_N_MEDIADEMUXER" + +#define DEMUXER_CHECK_CONDITION(condition,error,msg) \ + if(condition) {} else \ + { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \ + +#define DEMUXER_INSTANCE_CHECK(demuxer) \ + DEMUXER_CHECK_CONDITION(demuxer != NULL, MEDIADEMUXER_ERROR_INVALID_PARAMETER,"DEMUXER_ERROR_INVALID_PARAMETER") + +#define DEMUXER_STATE_CHECK(demuxer,expected_state) \ + DEMUXER_CHECK_CONDITION(demuxer->state == expected_state,MEDIADEMUXER_ERROR_INVALID_STATE,"DEMUXER_ERROR_INVALID_STATE") + +#define DEMUXER_NULL_ARG_CHECK(arg) \ + DEMUXER_CHECK_CONDITION(arg != NULL,MEDIADEMUXER_ERROR_INVALID_PARAMETER,"DEMUXER_ERROR_INVALID_PARAMETER") + +/** + * @brief Enumeration for media demuxer source type + * @since_tizen 3.0 + */ +typedef enum { + MEDIADEMUXER_SRC_NONE = 0, /**< Not defined src type */ + MEDIADEMUXER_SRC_FILE, /**< Local file src type */ + MEDIADEMUXER_SRC_RTP, /**< Rtp src type */ + MEDIADEMUXER_SRC_WFD, /**< Wfd src type */ + MEDIADEMUXER_SRC_HTTP, /**< Http src type */ + MEDIADEMUXER_SRC_SS, /**< Smooth streaming src type */ + MEDIADEMUXER_SRC_RTSP, /**< Rtsp src type */ + MEDIADEMUXER_SRC_UNKNOWN, /**< Unknown src type */ + MEDIADEMUXER_SRC_INVALID /**< Invalid src type */ +} mediademuxer_src_type; + +typedef struct _mediademuxer_s { + MMHandleType md_handle; + int state; + bool is_stopped; + pthread_t prepare_async_thread; + mediademuxer_error_cb error_cb; + void* error_cb_userdata; + mediademuxer_state demux_state; +} mediademuxer_s; + +typedef struct { + /* initialize values */ + media_port_demuxer_ops *demuxer_ops; + /* initialize values */ + md_ini_t ini; + /* port specific handle */ + /*Source information */ + char *uri_src; + mediademuxer_src_type uri_src_media_type; + MMHandleType mdport_handle; +} md_handle_t; + +int __convert_error_code(int code, char *func_name); + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_MEDIADEMUXER_PRIVATE_H__ */ diff --git a/include/mediademuxer_util.h b/include/mediademuxer_util.h new file mode 100755 index 0000000..ed99709 --- /dev/null +++ b/include/mediademuxer_util.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_util.h + * @brief contain information about utility function such as debug, error log and other. + */ + +#ifndef __TIZEN_MEDIADEMUXER_UTIL_H__ +#define __TIZEN_MEDIADEMUXER_UTIL_H__ + +#include +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//#define PRINT_ON_CONSOLE +#ifdef PRINT_ON_CONSOLE +#include +#include +#define PRINT_F g_print +#define MD_FENTER(); PRINT_F("function:[%s] ENTER\n",__func__); +#define MD_FLEAVE(); PRINT_F("function [%s] LEAVE\n",__func__); +#define MD_C PRINT_F +#define MD_E PRINT_F +#define MD_W PRINT_F +#define MD_I PRINT_F +#define MD_L PRINT_F +#define MD_V PRINT_F +#define MD_F PRINT_F +#else +#include +#include +#define MD_FENTER(); LOGI("function:[%s] ENTER\n",__func__); +#define MD_FLEAVE(); LOGI("function [%s] LEAVE\n",__func__); +#define MD_C LOGE /*MMF_DEBUG_LEVEL_0 */ +#define MD_E LOGE /*MMF_DEBUG_LEVEL_1 */ +#define MD_W LOGW /*MMF_DEBUG_LEVEL_2 */ +#define MD_I LOGI /*MMF_DEBUG_LEVEL_3 */ +#define MD_L LOGI /*MMF_DEBUG_LEVEL_4 */ +#define MD_V LOGV /*MMF_DEBUG_LEVEL_5 */ +#define MD_F LOGF /*MMF_DEBUG_LEVEL_6 - indicate that something in the executed code path is not fully implemented or handled yet */ +#endif + +/* general */ +#define MEDIADEMUXER_FREEIF(x) \ + if ( x ) \ + g_free( x ); \ + x = NULL; + +#if 1 +#define MEDIADEMUXER_FENTER(); MD_FENTER(); +#define MEDIADEMUXER_FLEAVE(); MD_FLEAVE(); +#else +#define MEDIADEMUXER_FENTER(); +#define MEDIADEMUXER_FLEAVE(); +#endif + +#define MEDIADEMUXER_CHECK_NULL( x_var ) \ + if ( ! x_var ) \ + { \ + MD_E("[%s] is NULL\n", #x_var ); \ + goto ERROR; \ + } + +#define MEDIADEMUXER_CHECK_SET_AND_PRINT( x_var, x_cond, ret, ret_val, err_text ) \ + if ( x_var != x_cond ) \ + { \ + ret = ret_val; \ + MD_E("%s\n", #err_text ); \ + goto ERROR; \ + } + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_MEDIADEMUXER_UTIL_H__ */ diff --git a/include/port_custom/mediademuxer_port_custom.h b/include/port_custom/mediademuxer_port_custom.h new file mode 100755 index 0000000..38ab5c3 --- /dev/null +++ b/include/port_custom/mediademuxer_port_custom.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_port_custom.h + * @brief Handling for Custom Port + */ + +#ifndef __TIZEN_MEDIADEMUXER_PORT_CUSTOM_H__ +#define __TIZEN_MEDIADEMUXER_PORT_CUSTOM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*Place holder*/ + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_MEDIADEMUXER_PORT_CUSTOM_H__ */ diff --git a/include/port_ffmpeg/mediademuxer_port_ffmpeg.h b/include/port_ffmpeg/mediademuxer_port_ffmpeg.h new file mode 100755 index 0000000..e86ca06 --- /dev/null +++ b/include/port_ffmpeg/mediademuxer_port_ffmpeg.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_port_ffmpeg.h + * @brief Handling for FFMPEG Port + */ + +#ifndef __TIZEN_MEDIADEMUXER_PORT_FFMPEG_H__ +#define __TIZEN_MEDIADEMUXER_PORT_FFMPEG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*Place holder*/ + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_MEDIADEMUXER_PORT_FFMPEG_H__ */ diff --git a/include/port_gst/mediademuxer_port_gst.h b/include/port_gst/mediademuxer_port_gst.h new file mode 100755 index 0000000..b02cce9 --- /dev/null +++ b/include/port_gst/mediademuxer_port_gst.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_port_gst.h + * @brief Handling for GST Port + */ + +#ifndef __TIZEN_MEDIADEMUXER_PORT_GST_H__ +#define __TIZEN_MEDIADEMUXER_PORT_GST_H__ + +#include +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +#define POLLING_INTERVAL 1000 +#define MAX_APP_BUFFER 100 + +#define MEDIADEMUXER_SET_STATE( x_element, x_state, error ) \ + do \ + { \ + MD_I("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME( x_element ) ); \ + if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state ( x_element, x_state) ) \ + { \ + MD_E("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME( x_element )); \ + goto error; \ + } \ + }while(0) + +#define MEDIADEMUXER_LINK_PAD( srcpad, sinkpad, error ) \ + do \ + { \ + if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad) ) \ + { \ + MD_E("failed to linkpad\n"); \ + goto error; \ + } \ + }while(0) + +typedef enum { + _GST_EVENT_TYPE_COMPLETE, + _GST_EVENT_TYPE_ERROR, + _GST_EVENT_TYPE_EOS, + _GST_EVENT_TYPE_NUM +} _gst_event_e; + +typedef struct track { + GstPad *pad; + GstCaps *caps; + gchar *name; + gchar *caps_string; + GstElement *appsink; + GstElement *fakesink; + GstElement *queue; + struct track *next; +} track; + +typedef struct track_info { + int num_audio_track; + int num_video_track; + int num_subtitle_track; + int num_other_track; + track *head; +} track_info; + +/* GST port Private data */ +typedef struct _mdgst_handle_t { + void *hdemux; /*< demux handle */ + int state; /*< demux current state */ + bool is_prepared; + GstElement *pipeline; + GstElement *filesrc; + GstElement *typefind; + GstElement *demux; + GstElement *fakesink; + gulong signal_handoff; + gint bus_whatch_id; + bool is_valid_container; + track_info info; + int state_change_timeout; + bool *selected_tracks; + int total_tracks; + GMutex *mutex; + /* for user cb */ + void* user_cb[_GST_EVENT_TYPE_NUM]; + void* user_data[_GST_EVENT_TYPE_NUM]; + +} mdgst_handle_t; + +/** + * @brief Called when the error has occured. + * @since_tizen 3.0 + * @details It will be invoked when the error has occured. + * @param[in] error_code The error code + * @param[in] user_data The user data passed from the callback registration function + * @pre It will be invoked when the error has occured if user register this callback using mediademuxer_set_error_cb(). + * @see mediademuxer_set_error_cb() + * @see mediademuxer_unset_error_cb() + */ +typedef void (*gst_error_cb)(mediademuxer_error_e error, void *user_data); + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_MEDIADEMUXER_PORT_GST_H__ */ diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec new file mode 100755 index 0000000..d25b022 --- /dev/null +++ b/packaging/capi-mediademuxer.spec @@ -0,0 +1,80 @@ +Name: capi-mediademuxer +Summary: A Media Demuxer library in Tizen Native API +Version: 0.1.1 +Release: 1 +Group: Multimedia/API +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(mm-common) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(capi-media-tool) +BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(gstreamer-1.0) +BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) +BuildRequires: pkgconfig(gstreamer-video-1.0) +BuildRequires: pkgconfig(gstreamer-app-1.0) +BuildRequires: pkgconfig(iniparser) + +Requires(post): /sbin/ldconfig +Requires(post): libprivilege-control +Requires(postun): /sbin/ldconfig + +%description + +%package devel +Summary: Multimedia Framework Demuxer Library (DEV) +Group: Multimedia/API +Requires: %{name} = %{version}-%{release} + +%description devel + +%prep +%setup -q + + +%build +%if 0%{?sec_build_binary_debug_enable} +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" +%endif +%ifarch %{arm} +export CFLAGS="$CFLAGS -DENABLE_FFMPEG_CODEC" +%endif + +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +%cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} + + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}%{_datadir}/license +mkdir -p %{buildroot}/usr/bin +cp test/mediademuxer_test %{buildroot}/usr/bin +cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/%{name} + +%make_install + +%post +/sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%manifest capi-mediademuxer.manifest +%{_libdir}/libcapi-mediademuxer.so.* +%{_datadir}/license/%{name} +%{_bindir}/* + +%files devel +%{_includedir}/media/*.h +%{_libdir}/pkgconfig/*.pc +%{_libdir}/libcapi-mediademuxer.so + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100755 index 0000000..eb5446c --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,4 @@ +message(In src folder...) +add_subdirectory(port_gst) +add_subdirectory(port_ffmpeg) +add_subdirectory(port_custom) diff --git a/src/mediademuxer.c b/src/mediademuxer.c new file mode 100755 index 0000000..79e538a --- /dev/null +++ b/src/mediademuxer.c @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2015 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 +#include + +#ifndef USE_TASK_QUEUE +#define USE_TASK_QUEUE +#endif + +/* +* Public Implementation +*/ +static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data); + +int mediademuxer_create(mediademuxer_h *demuxer) +{ + MD_I("mediademuxer_create\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + + mediademuxer_s *handle; + if (*demuxer == NULL) { + handle = (mediademuxer_s *) g_malloc(sizeof(mediademuxer_s)); + if (handle != NULL) { + memset(handle, 0, sizeof(mediademuxer_s)); + handle->demux_state = MEDIADEMUXER_NONE; + } else { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_OUT_OF_MEMORY(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_OUT_OF_MEMORY); + return MEDIADEMUXER_ERROR_OUT_OF_MEMORY; + } + } else { + MD_E("Already created the instance\n"); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + + ret = md_create(&handle->md_handle); + + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + free(handle); + handle = NULL; + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } else { + *demuxer = (mediademuxer_h) handle; + handle->is_stopped = false; + MD_I("[CoreAPI][%s] new handle : %p", __FUNCTION__, *demuxer); + } + /* set callback */ + md_set_error_cb(handle->md_handle, + (mediademuxer_error_cb) _mediademuxer_error_cb, + handle); + handle->demux_state = MEDIADEMUXER_IDLE; + return MEDIADEMUXER_ERROR_NONE; +} + +int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) +{ + MD_I("mediademuxer_set_data_source\n"); + mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && path && handle->demux_state == MEDIADEMUXER_IDLE) { + ret = md_set_data_source((MMHandleType) (handle->md_handle), path); + } else { + if (!path) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_PATH); + return MEDIADEMUXER_ERROR_INVALID_PATH; + } else { + if(handle->demux_state != MEDIADEMUXER_IDLE) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + } + return ret; +} + +int mediademuxer_prepare(mediademuxer_h demuxer) +{ + MD_I("mediademuxer_prepare\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && handle->demux_state == MEDIADEMUXER_IDLE) { + ret = md_prepare((MMHandleType) (handle->md_handle)); + if (ret == MEDIADEMUXER_ERROR_NONE) + handle->demux_state = MEDIADEMUXER_READY; + } else { + if(handle->demux_state != MEDIADEMUXER_IDLE) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count) +{ + MD_I("mediademuxer_get_track_count\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && handle->demux_state == MEDIADEMUXER_READY) { + ret = md_get_track_count((MMHandleType) (handle->md_handle), count); + } else { + if(handle->demux_state != MEDIADEMUXER_READY) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_select_track(mediademuxer_h demuxer, int track_index) +{ + MD_I("mediademuxer_select_track\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && handle->demux_state == MEDIADEMUXER_READY) { + ret = md_select_track((MMHandleType) (handle->md_handle), track_index); + } else { + if(handle->demux_state != MEDIADEMUXER_READY) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_start(mediademuxer_h demuxer) +{ + MD_I("mediademuxer_start\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && handle->demux_state == MEDIADEMUXER_READY) { + ret = md_start((MMHandleType) (handle->md_handle)); + if (ret == MEDIADEMUXER_ERROR_NONE) + handle->demux_state = MEDIADEMUXER_DEMUXING; + } else { + if(handle->demux_state != MEDIADEMUXER_READY) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, + media_format_h *format) +{ + MD_I("mediademuxer_get_track_info\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (track_index < 0 || format == NULL) { + MD_E("Invalid input parameters\n"); + return MEDIADEMUXER_ERROR_INVALID_PARAMETER; + } + if (handle && (handle->demux_state == MEDIADEMUXER_READY + || handle->demux_state == MEDIADEMUXER_DEMUXING)) { + ret = md_get_track_info((MMHandleType) (handle->md_handle), track_index, format); + } else { + if(handle->demux_state != MEDIADEMUXER_READY) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index, + media_packet_h *outbuf) +{ + MD_I("mediademuxer_read_sample\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (outbuf == NULL || track_index < 0) { + return MEDIADEMUXER_ERROR_INVALID_PARAMETER; + } + if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) { + ret = md_read_sample((MMHandleType) (handle->md_handle), track_index, outbuf); + } else { + if(handle->demux_state != MEDIADEMUXER_DEMUXING) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos) +{ + MD_I("mediademuxer_seek\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) { + ret = md_seek((MMHandleType) (handle->md_handle), pos); + } else { + if(handle->demux_state != MEDIADEMUXER_DEMUXING) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index) +{ + MD_I("mediademuxer_unselect_track\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && (handle->demux_state == MEDIADEMUXER_READY + || handle->demux_state == MEDIADEMUXER_DEMUXING)) { + ret = md_unselect_track((MMHandleType) (handle->md_handle), track_index); + } else { + if(handle->demux_state != MEDIADEMUXER_READY) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_stop(mediademuxer_h demuxer) +{ + MD_I("mediademuxer_stop\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) { + ret = md_stop((MMHandleType) (handle->md_handle)); + if (ret == MEDIADEMUXER_ERROR_NONE) + handle->demux_state = MEDIADEMUXER_READY; + } else { + if(handle->demux_state != MEDIADEMUXER_DEMUXING) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_unprepare(mediademuxer_h demuxer) +{ + MD_I("mediademuxer_unprepare\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && handle->demux_state == MEDIADEMUXER_READY) { + ret = md_unprepare((MMHandleType) (handle->md_handle)); + if (ret == MEDIADEMUXER_ERROR_NONE) + handle->demux_state = MEDIADEMUXER_IDLE; + } else { + if(handle->demux_state != MEDIADEMUXER_READY) + return MEDIADEMUXER_ERROR_INVALID_STATE; + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_destroy(mediademuxer_h demuxer) +{ + MD_I("mediademuxer_destroy\n"); + mediademuxer_error_e ret; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle && handle->demux_state == MEDIADEMUXER_IDLE) { + ret = md_destroy(handle->md_handle); + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } else { + MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__, + handle); + } + } else { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + handle->demux_state = MEDIADEMUXER_NONE; + return MEDIADEMUXER_ERROR_NONE; +} + +int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state) +{ + MD_I("mediademuxer_get_state\n"); + int ret = MEDIADEMUXER_ERROR_NONE; + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle = (mediademuxer_s *)(demuxer); + if (state != NULL) { + *state = handle->demux_state; + } else { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + ret = MEDIADEMUXER_ERROR_INVALID_OPERATION; + } + return ret; +} + +int mediademuxer_set_error_cb(mediademuxer_h demuxer, + mediademuxer_error_cb callback, void *user_data) +{ + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle->demux_state != MEDIADEMUXER_IDLE) + return MEDIADEMUXER_ERROR_INVALID_STATE; + handle->error_cb = callback; + handle->error_cb_userdata = user_data; + MD_I("set error_cb(%p)", callback); + return MEDIADEMUXER_ERROR_NONE; +} + +int mediademuxer_unset_error_cb(mediademuxer_h demuxer) +{ + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle->demux_state != MEDIADEMUXER_IDLE) + return MEDIADEMUXER_ERROR_INVALID_STATE; + handle->error_cb = NULL; + handle->error_cb_userdata = NULL; + MD_I("mediademuxer_unset_error_cb\n"); + return MEDIADEMUXER_ERROR_NONE; +} + +static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data) +{ + if(user_data == NULL){ + MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n",error); + return 0; + } + mediademuxer_s * handle = (mediademuxer_s *) user_data; + if(handle->demux_state != MEDIADEMUXER_IDLE) + return MEDIADEMUXER_ERROR_INVALID_STATE; + if ( handle->error_cb ) { + ((mediademuxer_error_cb)handle->error_cb)(error, handle->error_cb_userdata); + } + else { + MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n",error); + } + return 0; +} diff --git a/src/mediademuxer_ini.c b/src/mediademuxer_ini.c new file mode 100755 index 0000000..07213d1 --- /dev/null +++ b/src/mediademuxer_ini.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_ini.c + * @brief INI laoding and parsing procedures + */ + +#ifndef __MEDIADEMUXER_INI_C__ +#define __MEDIADEMUXER_INI_C__ + +/* includes here */ +#include +#include +#include +#include +#include +#include +#include "iniparser.h" +#include +#include + +/* internal functions, macros here */ +#ifdef MEDIADEMUXER_DEFAULT_INI +static gboolean _generate_default_ini(void); +#endif + +static void _md_ini_check_ini_status(void); + +/* macro */ +#define MEDIADEMUXER_INI_GET_STRING( x_dict, x_item, x_ini, x_default ) \ + do \ + { \ + gchar* str = iniparser_getstring(x_dict, x_ini, x_default); \ + \ + if ( str && \ + ( strlen( str ) > 0 ) && \ + ( strlen( str ) < MEDIADEMUXER_INI_MAX_STRLEN ) ) \ + { \ + strcpy ( x_item, str ); \ + } \ + else \ + { \ + strcpy ( x_item, x_default ); \ + } \ + }while(0) + +#define MEDIADEMUXER_INI_GET_COLOR( x_dict, x_item, x_ini, x_default ) \ + do \ + { \ + gchar* str = iniparser_getstring(x_dict, x_ini, x_default); \ + \ + if ( str && \ + ( strlen( str ) > 0 ) && \ + ( strlen( str ) < MEDIADEMUXER_INI_MAX_STRLEN ) ) \ + { \ + x_item = (guint) strtoul(str, NULL, 16); \ + } \ + else \ + { \ + x_item = (guint) strtoul(x_default, NULL, 16); \ + } \ + }while(0) + +/* x_ini is the list of index to set TRUE at x_list[index] */ +#define MEDIADEMUXER_INI_GET_BOOLEAN_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \ + do \ + { \ + int index = 0; \ + const char *delimiters = " ,"; \ + char *usr_ptr = NULL; \ + char *token = NULL; \ + gchar temp_arr[MEDIADEMUXER_INI_MAX_STRLEN] = {0}; \ + MMMEDIADEMUXER_INI_GET_STRING( x_dict, temp_arr, x_ini, x_default); \ + token = strtok_r( temp_arr, delimiters, &usr_ptr ); \ + while (token) \ + { \ + index = atoi(token); \ + if (index < 0 || index > x_list_max -1) \ + { \ + MD_W("%d is not valid index\n", index); \ + } \ + else \ + { \ + x_list[index] = TRUE; \ + } \ + token = strtok_r( NULL, delimiters, &usr_ptr ); \ + } \ + }while(0) + +/* x_ini is the list of value to be set at x_list[index] */ +#define MEDIADEMUXER_INI_GET_INT_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \ + do \ + { \ + int index = 0; \ + int value = 0; \ + const char *delimiters = " ,"; \ + char *usr_ptr = NULL; \ + char *token = NULL; \ + gchar temp_arr[MEDIADEMUXER_INI_MAX_STRLEN] = {0}; \ + MMMEDIADEMUXER_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \ + token = strtok_r( temp_arr, delimiters, &usr_ptr ); \ + while (token) \ + { \ + if ( index > x_list_max -1) \ + { \ + MD_E("%d is not valid index\n", index); \ + break; \ + } \ + else \ + { \ + value = atoi(token); \ + x_list[index] = value; \ + index++; \ + } \ + token = strtok_r( NULL, delimiters, &usr_ptr ); \ + } \ + }while(0) + +int md_ini_load(md_ini_t *ini) +{ + dictionary *dict = NULL; + _md_ini_check_ini_status(); + + /* first, try to load existing ini file */ + dict = iniparser_load(MEDIADEMUXER_INI_DEFAULT_PATH); + + /* if no file exists. create one with set of default values */ + if (!dict) { +#ifdef MEDIADEMUXER_DEFAULT_INI + MD_L("No inifile found. demuxer will create default inifile.\n"); + if (FALSE == _generate_default_ini()) { + MD_W("Creating default inifile failed. MediaDemuxer will use default values.\n"); + } else { + /* load default ini */ + dict = iniparser_load(MEDIADEMUXER_INI_DEFAULT_PATH); + } +#else + MD_L("No ini file found. \n"); + return MD_ERROR_FILE_NOT_FOUND; +#endif + } + + /* get ini values */ + memset(ini, 0, sizeof(md_ini_t)); + + if (dict) { /* if dict is available */ + /* general */ + MEDIADEMUXER_INI_GET_STRING(dict, ini->port_name, + "port_in_use:mediademuxer_port", + DEFAULT_PORT); + } else { /* if dict is not available just fill the structure with default value */ + + MD_W("failed to load ini. using hardcoded default\n"); + strncpy(ini->port_name, DEFAULT_PORT, + MEDIADEMUXER_INI_MAX_STRLEN - 1); + } + + if (0 == strcmp(ini->port_name, "GST_PORT")) + ini->port_type = GST_PORT; + else if (0 == strcmp(ini->port_name, "FFMPEG_PORT")) + ini->port_type = FFMPEG_PORT; + else if (0 == strcmp(ini->port_name, "CUSTOM_PORT")) + ini->port_type = CUSTOM_PORT; + else { + MD_E("Invalid port is set to [%s] [%d]\n", ini->port_name, + ini->port_type); + goto ERROR; + } + MD_L("The port is set to [%s] [%d]\n", ini->port_name, ini->port_type); + + /* free dict as we got our own structure */ + iniparser_freedict(dict); + + /* dump structure */ + MD_L("demuxer settings -----------------------------------\n"); + + /* general */ + MD_L("port_name: %s\n", ini->port_name); + MD_L("port_type : %d\n", ini->port_type); + + return MD_ERROR_NONE; +ERROR: + return MD_COURRPTED_INI; + +} + +static void _md_ini_check_ini_status(void) +{ + struct stat ini_buff; + + if (g_stat(MEDIADEMUXER_INI_DEFAULT_PATH, &ini_buff) < 0) { + MD_W("failed to get demuxer ini status\n"); + } else { + if (ini_buff.st_size < 5) { + MD_W("demuxer.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size); + + if (g_remove(MEDIADEMUXER_INI_DEFAULT_PATH) == -1) { + MD_E("failed to delete corrupted ini"); + } + } + } +} + +#ifdef MEDIADEMUXER_DEFAULT_INI +static gboolean _generate_default_ini(void) +{ + FILE *fp = NULL; + gchar *default_ini = MEDIADEMUXER_DEFAULT_INI; + + /* create new file */ + fp = fopen(MEDIADEMUXER_INI_DEFAULT_PATH, "wt"); + + if (!fp) { + return FALSE; + } + + /* writing default ini file */ + if (strlen(default_ini) != + fwrite(default_ini, 1, strlen(default_ini), fp)) { + fclose(fp); + return FALSE; + } + + fclose(fp); + return TRUE; +} +#endif + +#endif /* #ifdef _MEDIADEMUXER_INI_C_ */ diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c new file mode 100755 index 0000000..346c99e --- /dev/null +++ b/src/mediademuxer_port.c @@ -0,0 +1,545 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_port.c + * @brief general port based functions. sets specific function pointers + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* function type */ +extern int gst_port_register(media_port_demuxer_ops *pOps); +extern int ffmpeg_port_register(media_port_demuxer_ops *pOps); +extern int custom_port_register(media_port_demuxer_ops *pOps); +int __md_util_exist_file_path(const char *file_path); +bool __md_util_is_sdp_file(const char *path); +mediademuxer_src_type __md_util_media_type(char **uri); +int _md_util_parse(MMHandleType demuxer, const char *type); + +/* + * Sequence of functions should be same as the port enumeration + * "port_mode" in mm_demuxer_ini.h file + */ +typedef int (*register_port)(media_port_demuxer_ops *); +register_port register_port_func[] = { + &gst_port_register, + &ffmpeg_port_register, + &custom_port_register +}; + +int md_create(MMHandleType *demuxer) +{ + int result = MD_ERROR_NONE; + media_port_demuxer_ops *pOps = NULL; + md_handle_t *new_demuxer = NULL; + MEDIADEMUXER_FENTER(); + new_demuxer = (md_handle_t *) g_malloc(sizeof(md_handle_t)); + MD_I("md_create allocatiing new_demuxer %p:\n", new_demuxer); + MEDIADEMUXER_CHECK_NULL(new_demuxer); + memset(new_demuxer, 0, sizeof(md_handle_t)); + + /* alloc ops structure */ + pOps = (media_port_demuxer_ops *) g_malloc(sizeof(media_port_demuxer_ops)); + MEDIADEMUXER_CHECK_NULL(pOps); + + new_demuxer->demuxer_ops = pOps; + MD_I("md_create allocating new_demuxer->demuxer_ops %p:\n", + new_demuxer->demuxer_ops); + pOps->n_size = sizeof(media_port_demuxer_ops); + + new_demuxer->uri_src = NULL; + new_demuxer->uri_src_media_type = MEDIADEMUXER_SRC_INVALID; + /* load ini files */ + result = md_ini_load(&new_demuxer->ini); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_COURRPTED_INI, "can't load ini"); + + register_port_func[new_demuxer->ini.port_type](pOps); + result = pOps->init(&new_demuxer->mdport_handle); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_NOT_INITIALIZED, + "md_create failed"); + *demuxer = (MMHandleType) new_demuxer; + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + *demuxer = (MMHandleType) 0; + if (pOps) + g_free(pOps); + if (new_demuxer) + g_free(new_demuxer); + MEDIADEMUXER_FLEAVE(); + return result; +} + +int __md_util_exist_file_path(const char *file_path) +{ + int fd = 0; + struct stat stat_results = { 0, }; + MEDIADEMUXER_FENTER(); + + if (!file_path || !strlen(file_path)) + return MD_ERROR_FILE_NOT_FOUND; + + fd = open(file_path, O_RDONLY); + if (fd < 0) { + MD_E("failed to open file by %s (%d)\n", strerror(errno), errno); + if (EACCES == errno) { + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_FILE_NOT_FOUND; + } + } + + if (fstat(fd, &stat_results) < 0) { + MD_E("failed to get file status\n"); + close(fd); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_FILE_NOT_FOUND; + } else if (stat_results.st_size == 0) { + MD_E("file size is zero\n"); + close(fd); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_FILE_NOT_FOUND; + } else { + MD_E("file size : %lld bytes\n", + (long long)stat_results.st_size); + } + close(fd); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +} + +bool __md_util_is_sdp_file(const char *path) +{ + gboolean ret = FALSE; + gchar *uri = NULL; + MEDIADEMUXER_FENTER(); + return_val_if_fail(path, FALSE); + uri = g_ascii_strdown(path, -1); + if (uri == NULL) { + return FALSE; + } + /* trimming */ + g_strstrip(uri); + /* strlen(".sdp") == 4 */ + if (strlen(uri) <= 4) { + MD_W("path is too short.\n"); + return ret; + } + /* first, check extension name */ + ret = g_str_has_suffix(uri, "sdp"); + /* second, if no suffix is there, check it's contents */ + if (!ret) { + /* FIXIT : do it soon */ + } + g_free(uri); + uri = NULL; + MEDIADEMUXER_FLEAVE(); + return ret; +} + +mediademuxer_src_type __md_util_media_type(char **uri) +{ + char *path = NULL; + char *new_uristr = NULL; + char *old_uristr = NULL; + MEDIADEMUXER_FENTER(); + if ((path = strstr((*uri), "file://"))) { + int file_stat = MD_ERROR_NONE; + file_stat = __md_util_exist_file_path(path + 7); + if (file_stat == MD_ERROR_NONE) { + if (__md_util_is_sdp_file(path)) { + MD_L("uri is actually a file but it's sdp file. giving it to rtspsrc\n"); + return MEDIADEMUXER_SRC_RTSP; + } else { + return MEDIADEMUXER_SRC_FILE; + } + return MD_ERROR_NONE; + } else { + MD_E("could access %s.\n", path); + } + } else if ((path = strstr(*uri, "rtsp://"))) { + if (strlen(path)) { + if ((path = strstr(*uri, "/wfd1.0/"))) { + return (MEDIADEMUXER_SRC_WFD); + } else { + return (MEDIADEMUXER_SRC_RTSP); + } + } + } else if ((path = strstr(*uri, "http://"))) { + if (strlen(path)) { + if (g_str_has_suffix(g_ascii_strdown(*uri, strlen(*uri)), ".ism/manifest") || + g_str_has_suffix(g_ascii_strdown(*uri, strlen(*uri)), ".isml/manifest")) { + return (MEDIADEMUXER_SRC_SS); + } else { + return (MEDIADEMUXER_SRC_HTTP); + } + } + } else { + int file_stat = MD_ERROR_NONE; + file_stat = __md_util_exist_file_path(*uri); + if (file_stat == MD_ERROR_NONE) { + int len_uri = strlen(*uri); + old_uristr = (char *)g_malloc(sizeof(char) * (len_uri + 1)); + MEDIADEMUXER_CHECK_NULL(old_uristr); + MD_L("allocating temp old_uristr[%p] \n", old_uristr); + strncpy(old_uristr, *uri, len_uri + 1); + /* need to added 7 char for file:// + 1 for '\0'+ uri len */ + new_uristr = (char *)realloc(*uri, (7 + len_uri + 1) * sizeof(char)); + MEDIADEMUXER_CHECK_NULL(new_uristr); + MD_L("reallocating uri[%p] to new_uristr[%p] \n", *uri, new_uristr); + *uri = new_uristr; + g_snprintf(*uri, 7 + len_uri + 1, "file://%s", old_uristr); + MD_L("deallocating old_uristr[%p] \n", old_uristr); + free(old_uristr); + old_uristr = NULL; + if (__md_util_is_sdp_file((char *)(*uri))) { + MD_L("uri is actually a file but it's sdp file. giving it to rtspsrc\n"); + return (MEDIADEMUXER_SRC_RTSP); + } else { + return (MEDIADEMUXER_SRC_FILE); + } + } else { + goto ERROR; + } + } + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +ERROR: + if (new_uristr) + free(new_uristr); + if (old_uristr) + free(old_uristr); + MEDIADEMUXER_FLEAVE(); + return MEDIADEMUXER_SRC_INVALID; +} + +int _md_util_parse(MMHandleType demuxer, const char *type) +{ + char *media_type_string = NULL; + int lenght_string = 0; + int result = MD_ERROR_NONE; + md_handle_t *new_demuxer = NULL; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(demuxer); + new_demuxer = (md_handle_t *) demuxer; + lenght_string = strlen(type); + media_type_string = (char *)g_malloc(sizeof(char) * (lenght_string + 1)); + MEDIADEMUXER_CHECK_NULL(media_type_string); + MD_L("media_type_string allocating %p\n", media_type_string); + strncpy(media_type_string, type, lenght_string + 1); + /*Set media_type depending upon the header of string else consider using file protocol */ + if (new_demuxer->uri_src) { + free(new_demuxer->uri_src); + MD_L("new_demuxer->uri_src deallocating %p\n", new_demuxer->uri_src); + } + new_demuxer->uri_src_media_type = __md_util_media_type(&media_type_string); + if (new_demuxer->uri_src_media_type != MEDIADEMUXER_SRC_INVALID) { + new_demuxer->uri_src = media_type_string; + MD_L("uri:%s\n uri_type:%d\n", new_demuxer->uri_src, + new_demuxer->uri_src_media_type); + } else { + MD_E("Error while setiing source\n"); + MD_E("deallocating media_type_string %p\n", media_type_string); + free(media_type_string); + goto ERROR; + } + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_set_data_source(MMHandleType demuxer, const char *uri) +{ + int result = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(demuxer); + result = _md_util_parse(demuxer, (const char *)uri); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR_INVALID_ARGUMENT, + "error while parsing the file"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_prepare(MMHandleType demuxer) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->prepare(md_handle->mdport_handle, md_handle->uri_src); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error while doing prepare"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_get_track_count(MMHandleType demuxer, int *count) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->get_track_count(md_handle->mdport_handle, count); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, + result, MD_ERROR, + "error while getting track count"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_select_track(MMHandleType demuxer, int track) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->set_track(md_handle->mdport_handle, track); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error select track"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_start(MMHandleType demuxer) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->start(md_handle->mdport_handle); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error while doing start"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_get_track_info(MMHandleType demuxer, int track, media_format_h *format) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->get_track_info(md_handle->mdport_handle, format, track); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, + result, MD_ERROR, + "error while getting track count"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_read_sample(MMHandleType demuxer, int track_indx, media_packet_h *outbuf) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->read_sample(md_handle->mdport_handle, outbuf, track_indx); + if (result == MD_EOS || result == MD_ERROR_NONE) { + return result; + } else { + MD_E("error while reading sample\n"); + goto ERROR; + } + MEDIADEMUXER_FLEAVE(); +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_seek(MMHandleType demuxer, int64_t pos) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->seek(md_handle->mdport_handle, pos); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error while doing seek"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_unselect_track(MMHandleType demuxer, int track) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->unset_track(md_handle->mdport_handle, track); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error unselect track"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_stop(MMHandleType demuxer) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->stop(md_handle->mdport_handle); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error while doing stop"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_unprepare(MMHandleType demuxer) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->unprepare(md_handle->mdport_handle); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error while doing stop"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} + +int md_destroy(MMHandleType demuxer) +{ + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_CHECK_NULL(md_handle); + MEDIADEMUXER_FENTER(); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->destroy(md_handle->mdport_handle); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error while doing destroy"); + + /* free mediademuxer structure */ + if (md_handle) { + if (md_handle->demuxer_ops) { + MD_I("md_destroy deallocating md_handle->demuxer_ops %p:\n", md_handle->demuxer_ops); + g_free((void *)(md_handle->demuxer_ops)); + } + if (md_handle->uri_src) { + MD_I("md_destroy deallocating md_handle->uri_src %p:\n", + md_handle->uri_src); + g_free((void *)(md_handle->uri_src)); + } + MD_I("md_destroy deallocating md_handle %p:\n", md_handle); + g_free((void *)md_handle); + md_handle = NULL; + } + MEDIADEMUXER_FLEAVE(); + return result; + +ERROR: + return result; +} + +int md_set_error_cb(MMHandleType demuxer, + mediademuxer_error_cb callback, void *user_data) +{ + MEDIADEMUXER_FENTER(); + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->set_error_cb(md_handle->mdport_handle, callback,user_data); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error while setting error call back"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} diff --git a/src/port_custom/mediademuxer_port_custom.c b/src/port_custom/mediademuxer_port_custom.c new file mode 100755 index 0000000..15c7bfc --- /dev/null +++ b/src/port_custom/mediademuxer_port_custom.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_port_custom.c + * @brief Handling for Custom Port, defined function and there implementation + */ + +#include +#include +#include +#include +#include + +static int custom_demuxer_init(MMHandleType *pHandle); +static int custom_demuxer_prepare(MMHandleType pHandle, char *uri); +static int custom_demuxer_get_data_count(MMHandleType pHandle, int *count); +static int custom_demuxer_get_track_info(MMHandleType pHandle, + media_format_h *format, int track); +static int custom_demuxer_set_track(MMHandleType pHandle, int track); +static int custom_demuxer_get_data(MMHandleType pHandle, char *buffer); + +/*Media Demuxer API common*/ +static media_port_demuxer_ops def_demux_ops = { + .n_size = 0, + .init = custom_demuxer_init, + .prepare = custom_demuxer_prepare, + .get_track_count = custom_demuxer_get_data_count, + .get_track_info = custom_demuxer_get_track_info, + .set_track = custom_demuxer_set_track, + .get_data = custom_demuxer_get_data, +}; + +int custom_port_register(media_port_demuxer_ops *pOps) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(pOps); + + def_demux_ops.n_size = sizeof(def_demux_ops); + + memcpy((char *)pOps + sizeof(pOps->n_size), + (char *)&def_demux_ops + sizeof(def_demux_ops.n_size), + pOps->n_size - sizeof(pOps->n_size)); + + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + ret = MD_ERROR_INVALID_ARGUMENT; + return ret; +} + +static int custom_demuxer_init(MMHandleType *pHandle) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int custom_demuxer_prepare(MMHandleType pHandle, char *uri) +{ + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return 0; +} + + +static int custom_demuxer_get_data_count(MMHandleType pHandle, int *count) +{ + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return 0; +} + +static int custom_demuxer_get_track_info(MMHandleType pHandle, + media_format_h *format, int track) +{ + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return 0; +} + +static int custom_demuxer_set_track(MMHandleType pHandle, int track) +{ + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return 0; +} + +static int custom_demuxer_get_data(MMHandleType pHandle, char *buffer) +{ + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return 0; +} diff --git a/src/port_ffmpeg/mediademuxer_port_ffmpeg.c b/src/port_ffmpeg/mediademuxer_port_ffmpeg.c new file mode 100755 index 0000000..7e55d4e --- /dev/null +++ b/src/port_ffmpeg/mediademuxer_port_ffmpeg.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_port_ffmpeg.c + * @brief Handling for FFMPEG Port, defined function and there implementation + */ + +#include +#include +#include +#include +#include + +static int ffmpeg_demuxer_init(MMHandleType *pHandle); +static int ffmpeg_demuxer_prepare(MMHandleType pHandle, char *uri); +static int ffmpeg_demuxer_get_data_count(MMHandleType pHandle, int *count); +static int ffmpeg_demuxer_get_track_info(MMHandleType pHandle, + media_format_h *format, int track); +static int ffmpeg_demuxer_set_track(MMHandleType pHandle, int track); +static int ffmpeg_demuxer_get_data(MMHandleType pHandle, char *buffer); + +/*Media Demuxer API common*/ +static media_port_demuxer_ops def_demux_ops = { + .n_size = 0, + .init = ffmpeg_demuxer_init, + .prepare = ffmpeg_demuxer_prepare, + .get_track_count = ffmpeg_demuxer_get_data_count, + .get_track_info = ffmpeg_demuxer_get_track_info, + .set_track = ffmpeg_demuxer_set_track, + .get_data = ffmpeg_demuxer_get_data, +}; + +int ffmpeg_port_register(media_port_demuxer_ops *pOps) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(pOps); + + def_demux_ops.n_size = sizeof(def_demux_ops); + + memcpy((char *)pOps + sizeof(pOps->n_size), + (char *)&def_demux_ops + sizeof(def_demux_ops.n_size), + pOps->n_size - sizeof(pOps->n_size)); + + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + ret = MD_ERROR_INVALID_ARGUMENT; + return ret; +} + +static int ffmpeg_demuxer_init(MMHandleType *pHandle) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int ffmpeg_demuxer_prepare(MMHandleType pHandle, char *uri) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int ffmpeg_demuxer_get_data_count(MMHandleType pHandle, int *count) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int ffmpeg_demuxer_get_track_info(MMHandleType pHandle, + media_format_h *format, int track) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int ffmpeg_demuxer_set_track(MMHandleType pHandle, int track) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int ffmpeg_demuxer_get_data(MMHandleType pHandle, char *buffer) +{ + int ret = MD_ERROR_NONE; + MEDIADEMUXER_FENTER(); + MD_E("%s:exit: Not implemented\n", __func__); + MEDIADEMUXER_FLEAVE(); + return ret; +} diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c new file mode 100755 index 0000000..1ed26b9 --- /dev/null +++ b/src/port_gst/mediademuxer_port_gst.c @@ -0,0 +1,1280 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file mediademuxer_port_gst.c + * @brief Handling for GStreamer Port, defined function and there implementation + */ + +#include +#include +#include +#include +#include +#include + +static int gst_demuxer_init(MMHandleType *pHandle); +static int gst_demuxer_prepare(MMHandleType pHandle, char *uri); +static int gst_demuxer_get_data_count(MMHandleType pHandle, int *count); +static int gst_demuxer_set_track(MMHandleType pHandle, int track); +static int gst_demuxer_start(MMHandleType pHandle); +static int gst_demuxer_read_sample(MMHandleType pHandle, + media_packet_h *outbuf, int track_indx); +static int gst_demuxer_get_track_info(MMHandleType pHandle, + media_format_h *format, int index); +static int gst_demuxer_seek(MMHandleType pHandle, gint64 pos1); +static int gst_demuxer_unset_track(MMHandleType pHandle, int track); +static int gst_demuxer_stop(MMHandleType pHandle); +static int gst_demuxer_unprepare(MMHandleType pHandle); +static int gst_demuxer_destroy(MMHandleType pHandle); +static int gst_set_error_cb(MMHandleType pHandle, + gst_error_cb callback, void* user_data); + +/*Media Demuxer API common*/ +static media_port_demuxer_ops def_demux_ops = { + .n_size = 0, + .init = gst_demuxer_init, + .prepare = gst_demuxer_prepare, + .get_track_count = gst_demuxer_get_data_count, + .set_track = gst_demuxer_set_track, + .start = gst_demuxer_start, + .get_track_info = gst_demuxer_get_track_info, + .read_sample = gst_demuxer_read_sample, + .seek = gst_demuxer_seek, + .unset_track = gst_demuxer_unset_track, + .stop = gst_demuxer_stop, + .unprepare = gst_demuxer_unprepare, + .destroy = gst_demuxer_destroy, + .set_error_cb = gst_set_error_cb, +}; + +int gst_port_register(media_port_demuxer_ops *pOps) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pOps); + def_demux_ops.n_size = sizeof(def_demux_ops); + + memcpy((char *)pOps + sizeof(pOps->n_size), + (char *)&def_demux_ops + sizeof(def_demux_ops.n_size), + pOps->n_size - sizeof(pOps->n_size)); + + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + ret = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int gst_demuxer_init(MMHandleType *pHandle) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + mdgst_handle_t *new_mediademuxer = NULL; + new_mediademuxer = (mdgst_handle_t *) g_malloc(sizeof(mdgst_handle_t)); + MD_I("gst_demuxer_init allocating new_mediademuxer:%p\n", new_mediademuxer); + if (!new_mediademuxer) { + MD_E("Cannot allocate memory for demuxer\n"); + ret = MD_ERROR; + goto ERROR; + } + memset(new_mediademuxer, 0, sizeof(mdgst_handle_t)); + new_mediademuxer->is_prepared = false; + (new_mediademuxer->info).num_audio_track = 0; + (new_mediademuxer->info).num_video_track = 0; + (new_mediademuxer->info).num_subtitle_track = 0; + (new_mediademuxer->info).num_other_track = 0; + (new_mediademuxer->info).head = NULL; + *pHandle = (MMHandleType) new_mediademuxer; + new_mediademuxer->total_tracks = 0; + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +gboolean __gst_bus_call(GstBus *bus, GstMessage *msg, gpointer data) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + switch (GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: { + MD_I("EOS Reached"); + } + break; + case GST_MESSAGE_ERROR: { + GError *error = NULL; + gst_message_parse_error(msg, &error, NULL); + if (!error) { + MD_I("GST error message parsing failed"); + break; + } + MD_E("Error: %s\n", error->message); + g_error_free(error); + } + break; + default: + break; + } + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static void __gst_no_more_pad(GstElement *element, gpointer data) +{ + MEDIADEMUXER_FENTER(); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) data; + int loop_track; + track_info *head_track = &(gst_handle->info); + track *head = head_track->head; + gst_handle->selected_tracks = + (bool *) g_malloc(sizeof(bool) * (gst_handle->total_tracks)); + MD_I("Allocating %p to core->selected_tracks \n", gst_handle->selected_tracks); + if (!gst_handle->selected_tracks) { + MD_E("[%s]Memory allocation failed\n", __FUNCTION__); + return; + } else { + for (loop_track = 0; loop_track < gst_handle->total_tracks; + loop_track++) + gst_handle->selected_tracks[loop_track] = false; + } + MD_I("Number of video tracks are %d\n", head_track->num_video_track); + MD_I("Number of audio tracks are %d\n", head_track->num_audio_track); + MD_I("Number of subtitle tracks are %d\n", + head_track->num_subtitle_track); + MD_I("Number of other tracks are %d\n", head_track->num_other_track); + while (head) { + MD_I("track caps[%s]\n", head->name); + head = head->next; + } + gst_handle->is_prepared = true; + MD_I("core->is_prepared: "); + gst_handle->is_prepared ? MD_I("true\n") : MD_I("false\n"); + MEDIADEMUXER_FLEAVE(); +} + +void __gst_free_stuct(track **head) +{ + MEDIADEMUXER_FENTER(); + track *temp = NULL; + temp = *head; + while (temp) { + /* + if (temp->pad) { + MD_I("deallocate GST_PAD %p\n", temp->pad); + gst_object_unref(temp->pad); + } */ + if (temp->name) { + MD_I("deallocate GST_PAD name %p\n", temp->name); + g_free(temp->name); + } + if (temp->caps_string) { + MD_I("deallocate GST_PAD caps_string %p\n", + temp->caps_string); + g_free(temp->caps_string); + } + if (temp->caps) { + MD_I("deallocate GST_PAD caps_ %p\n", temp->caps); + gst_caps_unref(temp->caps); + } + + if (temp->next) { + track *next = temp->next; + MD_I("deallocate memory %p\n", temp); + free(temp); + temp = next; + } else { + MD_I("deallocate memory %p\n", temp); + free(temp); + temp = NULL; + *head = NULL; + } + } + MEDIADEMUXER_FLEAVE(); +} + +int __gst_add_track_info(GstPad *pad, gchar *name, track **head, + GstElement *pipeline) +{ + MEDIADEMUXER_FENTER(); + GstPad *apppad = NULL; + track *temp = NULL; + temp = (track *)(g_malloc(sizeof(track))); + if (!temp) { + MD_E("Not able to allocate memory"); + return MD_ERROR; + } else { + MD_I("allocate memory %p", temp); + } + temp->pad = pad; + temp->caps = gst_pad_get_current_caps(pad); + temp->name = name; + temp->caps_string = gst_caps_to_string(temp->caps); + temp->next = NULL; + temp->appsink = gst_element_factory_make("appsink", NULL); + if (!temp->appsink) { + MD_E("factory not able to make appsink"); + __gst_free_stuct(head); + return MD_ERROR; + } + gst_bin_add_many(GST_BIN(pipeline), temp->appsink, NULL); + gst_app_sink_set_max_buffers((GstAppSink *) temp->appsink, MAX_APP_BUFFER); + MEDIADEMUXER_SET_STATE(temp->appsink, GST_STATE_PAUSED, ERROR); + apppad = gst_element_get_static_pad(temp->appsink, "sink"); + if (!apppad) { + MD_E("sink pad of appsink not avaible"); + __gst_free_stuct(head); + return MD_ERROR; + } + MEDIADEMUXER_LINK_PAD(pad, apppad, ERROR); + /*gst_pad_link(pad, fpad) */ + if (*head == NULL) { + *head = temp; + } else { + track *prev = *head; + while (prev->next) { + prev = prev->next; + } + prev->next = temp; + } + gst_object_unref(apppad); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +ERROR: + if (apppad) + gst_object_unref(apppad); + __gst_free_stuct(head); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +static void __gst_on_pad_added(GstElement *element, GstPad *pad, gpointer data) +{ + MEDIADEMUXER_FENTER(); + MD_I("Dynamic pad created, linking demuxer/decoder\n"); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) data; + track_info *head_track = &(gst_handle->info); + gchar *name = gst_pad_get_name(pad); + gst_handle->total_tracks++; + if (__gst_add_track_info(pad, name, &(head_track->head), gst_handle->pipeline) + != MD_ERROR_NONE) { + MD_E("unable to added track info"); + head_track->num_audio_track = 0; + head_track->num_video_track = 0; + head_track->num_subtitle_track = 0; + head_track->num_other_track = 0; + __gst_free_stuct(&(head_track->head)); + return; + } + if (name[0] == 'v') { + MD_I("found Video Pad\n"); + (head_track->num_video_track)++; + } else if (name[0] == 'a') { + MD_I("found Audio Pad\n"); + (head_track->num_audio_track)++; + } else if (name[0] == 's') { + MD_I("found subtitle Pad\n"); + (head_track->num_subtitle_track)++; + } else { + MD_I("found Pad %s\n", name); + (head_track->num_other_track)++; + } + MEDIADEMUXER_FLEAVE(); +} + +static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) +{ + MEDIADEMUXER_FENTER(); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) data; + GstPad *pad = NULL; + GstPad *aud_pad = NULL; + GstPad *aud_srcpad = NULL; + GstPad *fake_pad = NULL; + GstElement *id3tag = NULL; + gchar *name; + gchar *type; + track_info *head_track = &(gst_handle->info); + track *trck; + gst_handle->is_valid_container = true; + type = gst_caps_to_string(caps); + if (strstr(type, "adts")) { + gst_handle->demux = gst_element_factory_make("aacparse", NULL); + } else if (strstr(type, "audio/mpeg")) { + gst_handle->demux = gst_element_factory_make("mpegaudioparse", NULL); + } else if (strstr(type, "application/x-id3")) { + id3tag = gst_element_factory_make("id3demux", NULL); + gst_handle->demux = gst_element_factory_make("mpegaudioparse", NULL); + } else if (strstr(type, "audio/x-amr-nb-sh") + || strstr(type, "audio/x-amr-wb-sh")) { + gst_handle->demux = gst_element_factory_make("amrparse", NULL); + } + g_free(type); + if (!gst_handle->demux) { + gst_handle->is_valid_container = false; + MD_E("factory not able to create audio parse element\n"); + goto ERROR; + } else { + gst_bin_add_many(GST_BIN(gst_handle->pipeline), + gst_handle->demux, id3tag, NULL); + pad = gst_element_get_static_pad(gst_handle->typefind, "src"); + if (!pad) { + MD_E("fail to get typefind src pad.\n"); + goto ERROR; + } + if (!id3tag) { + aud_pad = gst_element_get_static_pad(gst_handle->demux, "sink"); + } else { + aud_pad = gst_element_get_static_pad(id3tag, "sink"); + } + if (!aud_pad) { + MD_E("fail to get audio parse sink pad.\n"); + goto ERROR; + } + fake_pad = gst_element_get_static_pad(gst_handle->fakesink, "sink"); + if (!fake_pad) { + MD_E("fail to get fakesink sink pad.\n"); + goto ERROR; + } + gst_pad_unlink(pad, fake_pad); + MEDIADEMUXER_LINK_PAD(pad, aud_pad, ERROR); + if (!id3tag) { + MEDIADEMUXER_SET_STATE(gst_handle->demux, + GST_STATE_PAUSED, ERROR); + } else { + MEDIADEMUXER_SET_STATE(id3tag, GST_STATE_PAUSED, ERROR); + MEDIADEMUXER_SET_STATE(gst_handle->demux, + GST_STATE_PAUSED, ERROR); + gst_element_link(id3tag, gst_handle->demux); + } + if (pad) + gst_object_unref(pad); + if (aud_pad) + gst_object_unref(aud_pad); + if (fake_pad) + gst_object_unref(fake_pad); + } + + /* calling "on_pad_added" function to set the caps*/ + aud_srcpad = gst_element_get_static_pad(gst_handle->demux, "src"); + if (!aud_srcpad) { + MD_E("fail to get audioparse source pad.\n"); + goto ERROR; + } + gst_handle->total_tracks++; + name = gst_pad_get_name(aud_srcpad); + if (__gst_add_track_info(aud_srcpad, name, &(head_track->head), gst_handle->pipeline) + != MD_ERROR_NONE) { + MD_E("unable to added track info"); + head_track->num_audio_track = 0; + head_track->num_video_track = 0; + head_track->num_subtitle_track = 0; + head_track->num_other_track = 0; + __gst_free_stuct(&(head_track->head)); + goto ERROR; + } + if (aud_srcpad) + gst_object_unref(aud_srcpad); + + trck = head_track->head; + while (aud_srcpad != trck->pad && trck != NULL) { + trck = trck->next; + } + if (trck != NULL) { + trck->caps = caps; + trck->caps_string = gst_caps_to_string(trck->caps); + MD_I("caps set to %s\n",trck->caps_string); + g_strlcpy(name,"audio",strlen(name)); + trck->name = name; + } + (head_track->num_audio_track)++; + __gst_no_more_pad(gst_handle->demux, data); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +ERROR: + gst_handle->is_valid_container = false; + if (gst_handle->demux) + gst_object_unref(gst_handle->demux); + if (pad) + gst_object_unref(pad); + if (aud_pad) + gst_object_unref(aud_pad); + if (fake_pad) + gst_object_unref(fake_pad); + if (aud_srcpad) + gst_object_unref(aud_srcpad); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +static void __gst_cb_typefind(GstElement *tf, guint probability, + GstCaps *caps, gpointer data) +{ + MEDIADEMUXER_FENTER(); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) data; + GstPad *pad = NULL; + GstPad *qt_pad = NULL; + GstPad *fake_pad = NULL; + gchar *type; + type = gst_caps_to_string(caps); + if (type) { + MD_I("Media type %s found, probability %d%%\n", type, probability); + if (strstr(type, "quicktime")) { + gst_handle->is_valid_container = true; + gst_handle->demux = gst_element_factory_make("qtdemux", NULL); + if (!gst_handle->demux) { + gst_handle->is_valid_container = false; + MD_E("factory not able to create qtdemux\n"); + goto ERROR; + } else { + g_signal_connect(gst_handle->demux, "pad-added", + G_CALLBACK(__gst_on_pad_added), gst_handle); + g_signal_connect(gst_handle->demux, "no-more-pads", + G_CALLBACK(__gst_no_more_pad), gst_handle); + gst_bin_add_many(GST_BIN(gst_handle->pipeline), + gst_handle->demux, NULL); + pad = gst_element_get_static_pad(gst_handle->typefind, "src"); + if (!pad) { + MD_E("fail to get typefind src pad.\n"); + goto ERROR; + } + qt_pad = gst_element_get_static_pad(gst_handle->demux, "sink"); + if (!qt_pad) { + MD_E("fail to get qtdemuc sink pad.\n"); + goto ERROR; + } + fake_pad = gst_element_get_static_pad(gst_handle->fakesink, "sink"); + if (!fake_pad) { + MD_E("fail to get fakesink sink pad.\n"); + goto ERROR; + } + gst_pad_unlink(pad, fake_pad); + MEDIADEMUXER_LINK_PAD(pad, qt_pad, ERROR); + MEDIADEMUXER_SET_STATE(gst_handle->demux, + GST_STATE_PAUSED, ERROR); + if (pad) + gst_object_unref(pad); + if (qt_pad) + gst_object_unref(qt_pad); + if (fake_pad) + gst_object_unref(fake_pad); + } + } else if ((strstr(type, "adts")) + || (strstr(type, "audio/mpeg")) + || (strstr(type, "application/x-id3")) + || (strstr(type, "audio/x-amr-nb-sh")) + || (strstr(type, "audio/x-amr-wb-sh"))) { + MD_I("Audio only format is found\n"); + __gst_create_audio_only_pipeline(data, caps); + } else { + gst_handle->is_valid_container = false; + MD_E("Not supported container %s\n", type); + } + g_free(type); + } + MEDIADEMUXER_FLEAVE(); + return; +ERROR: + gst_handle->is_valid_container = false; + if (gst_handle->demux) + gst_object_unref(gst_handle->demux); + if (type) + g_free(type); + if (pad) + gst_object_unref(pad); + if (qt_pad) + gst_object_unref(qt_pad); + if (fake_pad) + gst_object_unref(fake_pad); + MEDIADEMUXER_FLEAVE(); + return; +} + +static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + GstBus *bus = NULL; + + /* Initialize GStreamer */ + /* Note: Replace the arguments of gst_init to pass the command line args to GStreamer. */ + gst_init(NULL, NULL); + + /* Create the empty pipeline */ + gst_handle->pipeline = gst_pipeline_new("Demuxer Gst pipeline"); + if (!gst_handle->pipeline) { + MD_E("pipeline create fail"); + ret = MD_ERROR; + goto ERROR; + } + + /* Create the elements */ + gst_handle->filesrc = gst_element_factory_make("filesrc", NULL); + if (!gst_handle->filesrc) { + MD_E("filesrc creation failed"); + ret = MD_ERROR; + goto ERROR; + } + + /* Modify the source's properties */ + g_object_set(G_OBJECT(gst_handle->filesrc), "location", uri + 7, NULL); + gst_handle->typefind = gst_element_factory_make("typefind", NULL); + if (!gst_handle->typefind) { + MD_E("typefind creation failed"); + ret = MD_ERROR; + goto ERROR; + } + g_signal_connect(gst_handle->typefind, "have-type", + G_CALLBACK(__gst_cb_typefind), gst_handle); + gst_handle->fakesink = gst_element_factory_make("fakesink", NULL); + if (!gst_handle->fakesink) { + MD_E("fakesink creation failed"); + ret = MD_ERROR; + goto ERROR; + } + + /* Build the pipeline */ + gst_bin_add_many(GST_BIN(gst_handle->pipeline), + gst_handle->filesrc, + gst_handle->typefind, + gst_handle->fakesink, + NULL); + gst_element_link_many(gst_handle->filesrc, + gst_handle->typefind, + gst_handle->fakesink, + NULL); + + /* connect signals, bus watcher */ + bus = gst_pipeline_get_bus(GST_PIPELINE(gst_handle->pipeline)); + gst_handle->bus_whatch_id = gst_bus_add_watch(bus, __gst_bus_call, gst_handle); + gst_object_unref(bus); + + /* set pipeline state to PAUSED */ + MEDIADEMUXER_SET_STATE(gst_handle->pipeline, GST_STATE_PAUSED, ERROR); + + int count = 0; + while (gst_handle->is_prepared != true) { + count++; + usleep(POLLING_INTERVAL); + MD_I("Inside while loop\n"); + if (count > POLLING_INTERVAL) { + MD_E("Error occure\n"); + ret = MD_ERROR; + } + } + + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int gst_demuxer_prepare(MMHandleType pHandle, char *uri) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; + + MD_I("gst_demuxer_prepare Creating pipeline %p", new_mediademuxer); + ret = _gst_create_pipeline(new_mediademuxer, uri); + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int gst_demuxer_get_data_count(MMHandleType pHandle, int *count) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; + + *count = (new_mediademuxer->info).num_video_track + + (new_mediademuxer->info).num_audio_track + + (new_mediademuxer->info).num_subtitle_track + + (new_mediademuxer->info).num_other_track; + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +int _gst_set_appsink(track *temp, int index, int loop) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + int count = 0; + if (index >= loop && index < 0) + goto ERROR; + while (count != index) { + temp = temp->next; + count++; + } + gst_app_sink_set_max_buffers((GstAppSink *)(temp->appsink), (guint) MAX_APP_BUFFER); + gst_app_sink_set_drop((GstAppSink *)(temp->appsink), false); + + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +static int gst_demuxer_set_track(MMHandleType pHandle, int track) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_INVALID_ARG; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; + + if (track >= new_mediademuxer->total_tracks || track < 0) { + goto ERROR; + } + new_mediademuxer->selected_tracks[track] = true; + _gst_set_appsink((((mdgst_handle_t *) pHandle)->info).head, track, + new_mediademuxer->total_tracks); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int gst_demuxer_start(MMHandleType pHandle) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) pHandle; + + int indx; + for (indx = 0; indx < gst_handle->total_tracks; indx++) { + MD_I("track indx[%d] is marked as [%d]. (0- not selected, 1= selected)\n", + indx, gst_handle->selected_tracks[indx]); + /* + if (gst_handle->selected_tracks[indx] == false) + _gst_demuxer_unset(pHandle, indx); + */ + } + + track_info *head_track = &(gst_handle->info); + MD_I("Total Audio track=%d, Video track=%d, text track=%d\n", + head_track->num_audio_track, head_track->num_video_track, + head_track->num_subtitle_track); + + track *temp = head_track->head; + indx = 0; + while (temp) { + MD_I("Got one element %p\n", temp->appsink); + if (gst_element_set_state(temp->appsink, GST_STATE_PLAYING) == + GST_STATE_CHANGE_FAILURE) { + MD_E("Failed to set into PLAYING state"); + ret = MD_ERROR_UNKNOWN; + } + MD_I("set the state to playing\n"); + indx++; + if (temp->next) { + track *next = temp->next; + temp = next; + } else { + temp = NULL; + } + } + + MD_I("gst_demuxer_start pipeine %p", gst_handle); + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +int _set_mime_video(media_format_h format, track *head) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + GstStructure *struc = NULL; + int src_width; + int src_height; + struc = gst_caps_get_structure(head->caps, 0); + if (!struc) { + MD_E("cannot get structure from caps.\n"); + goto ERROR; + } + if (gst_structure_has_name(struc, "video/x-h264")) { + const gchar *version = + gst_structure_get_string(struc, "stream-format"); + if (strncmp(version, "avc", 3) == 0) { + gst_structure_get_int(struc, "width", &src_width); + gst_structure_get_int(struc, "height", &src_height); + if (media_format_set_video_mime(format, MEDIA_FORMAT_H264_SP)) + goto ERROR; + if (media_format_set_video_width(format, src_width)) + goto ERROR; + if (media_format_set_video_height(format, src_height)) + goto ERROR; + } + } else { + MD_I("Video mime not supported so far\n"); + goto ERROR; + } + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +int _set_mime_audio(media_format_h format, track *head) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + GstStructure *struc = NULL; + int rate = 0; + int channels = 0; + int id3_flag = 0; + struc = gst_caps_get_structure(head->caps, 0); + if (!struc) { + MD_E("cannot get structure from caps.\n"); + goto ERROR; + } + + if (gst_structure_has_name(struc, "application/x-id3")) { + id3_flag = 1; + } + if (gst_structure_has_name(struc, "audio/mpeg") || id3_flag) { + gint mpegversion; + int layer; + gst_structure_get_int(struc, "mpegversion", &mpegversion); + if (mpegversion == 4 || mpegversion == 2 ) { + gst_structure_get_int(struc, "channels", &channels); + gst_structure_get_int(struc, "rate", &rate); + if (media_format_set_audio_mime(format, MEDIA_FORMAT_AAC_LC)) + goto ERROR; + if(channels == 0) + channels = 2; /* default */ + if (media_format_set_audio_channel(format, channels)) + goto ERROR; + if(rate == 0) + rate = 44100; /* default */ + if (media_format_set_audio_samplerate(format, rate)) + goto ERROR; + if (media_format_set_audio_bit(format, 0)) + goto ERROR; + } + if (mpegversion == 1 || id3_flag ) { + gst_structure_get_int(struc, "layer", &layer); + if((layer == 3) || (id3_flag == 1)) { + gst_structure_get_int(struc, "channels", &channels); + gst_structure_get_int(struc, "rate", &rate); + if (media_format_set_audio_mime(format, MEDIA_FORMAT_MP3)) + goto ERROR; + if(channels == 0) + channels = 2; /* default */ + if (media_format_set_audio_channel(format, channels)) + goto ERROR; + if(rate == 0) + rate = 44100; /* default */ + if (media_format_set_audio_samplerate(format, rate)) + goto ERROR; + if (media_format_set_audio_bit(format, 0)) + goto ERROR; + } + else { + MD_I("No Support for MPEG%d Layer %d media\n",mpegversion,layer); + goto ERROR; + } + } + }else if (gst_structure_has_name(struc, "audio/x-amr-nb-sh") || + gst_structure_has_name(struc, "audio/x-amr-wb-sh")) { + media_format_mimetype_e mime_type; + gst_structure_get_int(struc, "channels", &channels); + gst_structure_get_int(struc, "rate", &rate); + if (gst_structure_has_name(struc, "audio/x-amr-nb-sh")) { + mime_type= MEDIA_FORMAT_AMR_NB; + rate = 8000; + } + else { + mime_type = MEDIA_FORMAT_AMR_WB; + rate = 16000; + } + if (media_format_set_audio_mime(format,mime_type)) + goto ERROR; + if(channels == 0) + channels = 1; /* default */ + if (media_format_set_audio_channel(format, channels)) + goto ERROR; + if (media_format_set_audio_samplerate(format, rate)) + goto ERROR; + if (media_format_set_audio_bit(format, 0)) + goto ERROR; + } + else { + MD_I("Audio mime not supported so far\n"); + goto ERROR; + } + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +static int gst_demuxer_get_track_info(MMHandleType pHandle, + media_format_h *format, int index) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; + + track *temp = NULL; + int loop; + int count = 0; + temp = (new_mediademuxer->info).head; + loop = (new_mediademuxer->info).num_video_track + + (new_mediademuxer->info).num_audio_track + + (new_mediademuxer->info).num_subtitle_track + + (new_mediademuxer->info).num_other_track; + if (index >= loop && index < 0) + goto ERROR; + + ret = media_format_create(format); + if(ret != MEDIA_FORMAT_ERROR_NONE){ + MD_E("Mediaformat creation failed. returned %d\n",ret); + ret = MD_INTERNAL_ERROR; + goto ERROR; + } + while (count != index) { + temp = temp->next; + count++; + } + + MD_I("CAPS for selected track [%d] is [%s]\n", index, temp->caps_string); + MD_I("format ptr[%p]\n", *format); + if (temp->name[0] == 'a') { + MD_I("Setting for Audio \n"); + _set_mime_audio(*format, temp); + } else if (temp->name[0] == 'v') { + MD_I("Setting for Video \n"); + _set_mime_video(*format, temp); + } else { + MD_I("Not supported so far (except audio and video)\n"); + } + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt, + GstBuffer *buffer) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(out_pkt); + void *pkt_data; + uint64_t size; + GstMapInfo map; + + if (!gst_buffer_map(buffer, &map, GST_MAP_READ)) { + MD_E("gst_buffer_map failed\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } + /* copy data*/ + media_packet_get_buffer_size(out_pkt, &size); + MD_I("Media packet Buffer capacity: %llu GST Buffer size = %d\n", size, map.size); + if (size < (uint64_t)map.size) { + MD_W("Media packet Buffer capacity[%llu] is \ + less than the GST Buffer size[%d]. Resizing...\n", size, map.size); + ret = media_packet_set_buffer_size(out_pkt, (uint64_t)map.size); + media_packet_get_buffer_size(out_pkt, &size); + MD_I("Media packet Buffer NEW capacity: %llu \n", size); + } + if (media_packet_get_buffer_data_ptr(out_pkt, &pkt_data)) { + MD_E("unable to get the buffer pointer from media_packet_get_buffer_data_ptr\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } + memcpy((char *)pkt_data, map.data, map.size); + if (media_packet_set_pts(out_pkt, GST_BUFFER_PTS(buffer))) { + MD_E("unable to set the pts\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } + if (media_packet_set_dts(out_pkt, GST_BUFFER_DTS(buffer))) { + MD_E("unable to set the dts\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } + if (media_packet_set_duration(out_pkt, GST_BUFFER_DURATION(buffer))) { + MD_E("unable to set the duration\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } + if (media_packet_set_buffer_size(out_pkt, gst_buffer_get_size(buffer))) { + MD_E("unable to set the buffer size\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } + if (media_packet_set_flags(out_pkt, GST_BUFFER_FLAGS(buffer))) { + MD_E("unable to set the buffer size\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } +ERROR: + gst_buffer_unmap(buffer, &map); + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int gst_demuxer_read_sample(MMHandleType pHandle, + media_packet_h *outbuf, int track_indx) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *demuxer = (mdgst_handle_t *) pHandle; + + media_packet_h mediabuf = NULL; + media_format_h mediafmt = NULL; + int indx = 0; + track *atrack = demuxer->info.head; + if ((demuxer->selected_tracks)[track_indx] == false) { + MD_E("Track Not selected\n"); + ret = MD_ERROR; + goto ERROR; + } + while (atrack) { + if (indx == track_indx) /*Got the requird track details*/ + break; + if (atrack->next) { + track *next = atrack->next; + atrack = next; + } else { + MD_E("Invalid track Index\n"); + ret = MD_ERROR_INVALID_ARGUMENT; + goto ERROR; + } + indx++; + } + if (atrack->name[0] == 'a') { + if (media_format_create(&mediafmt)) { + MD_E("media_format_create failed\n"); + ret = MD_ERROR; + goto ERROR; + } + if (media_format_set_audio_mime(mediafmt, MEDIA_FORMAT_AAC)) { + MD_E("media_format_set_audio_mime failed\n"); + ret = MD_ERROR; + goto ERROR; + } + if (media_packet_create_alloc(mediafmt, NULL, NULL, &mediabuf)) { + MD_E("media_packet_create_alloc failed\n"); + ret = MD_ERROR; + goto ERROR; + } + } + else if (atrack->name[0] == 'v'){ + if (media_format_create(&mediafmt)) { + MD_E("media_format_create failed\n"); + ret = MD_ERROR; + goto ERROR; + } + if (media_format_set_video_mime(mediafmt, MEDIA_FORMAT_H264_SP)) { + MD_E("media_format_set_ivideo_mime failed\n"); + ret = MD_ERROR; + goto ERROR; + } + if (media_format_set_video_width(mediafmt, 760)) { + MD_E("media_format_set_video_width failed\n"); + ret = MD_ERROR; + goto ERROR; + } + if (media_format_set_video_height(mediafmt, 480)) { + MD_E("media_format_set_video_height failed\n"); + ret = MD_ERROR; + goto ERROR; + } + + if (media_packet_create_alloc(mediafmt, NULL, NULL, &mediabuf)) { + MD_E("media_packet_create_alloc failed\n"); + ret = MD_ERROR; + goto ERROR; + } + } + else { + MD_E("Invalid track format\n"); + goto ERROR; + } + if (indx != track_indx) { + MD_E("Invalid track Index\n"); + ret = MD_ERROR_INVALID_ARGUMENT; + goto ERROR; + } + GstElement *sink = atrack->appsink; + GstSample *sample = NULL; + if (gst_app_sink_is_eos((GstAppSink *) sink)) { + MD_W("End of stream reached\n"); + ret = MD_EOS; + goto ERROR; + } + + sample = gst_app_sink_pull_sample((GstAppSink *) sink); + if (sample == NULL) { + MD_E("gst_demuxer_read_sample failed\n"); + ret = MD_ERROR_UNKNOWN; + } + + GstBuffer *buffer = gst_sample_get_buffer(sample); + if (buffer == NULL) { + MD_E("gst_sample_get_buffer returned NULL pointer\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } + + /* Fill the media_packet with proper information */ + ret = _gst_copy_buf_to_media_packet(mediabuf, buffer); + gst_sample_unref(sample); + *outbuf = mediabuf; + + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int gst_demuxer_seek(MMHandleType pHandle, gint64 pos1) +{ + MEDIADEMUXER_FENTER(); + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) pHandle; + + gint64 pos, len; + gdouble rate = 1; + if (gst_element_query_position(gst_handle->pipeline, GST_FORMAT_TIME, &pos) && + gst_element_query_duration(gst_handle->pipeline, GST_FORMAT_TIME, &len)) { + MD_I("Time: %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\r", + GST_TIME_ARGS(pos), + GST_TIME_ARGS(len)); + } + pos1 = pos + (pos1 * GST_SECOND); + + MD_I("\n\n"); + MD_I("NEW Time: %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\r", + GST_TIME_ARGS(pos1), GST_TIME_ARGS(len)); + + track_info *head_track = &(gst_handle->info); + track *temp = head_track->head; + int indx = 0; + while (temp) { + MD_I("Got one element %p\n", temp->appsink); + if (gst_handle->selected_tracks[indx] == true) { + if (!gst_element_seek(temp->appsink, rate, GST_FORMAT_TIME, + GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, pos1, + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { + g_print("Seek failed!\n"); + } else { + MD_I("Seek success\n"); + } + } + indx++; + if (temp->next) { + track *next = temp->next; + temp = next; + } else { + temp = NULL; + } + } + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +ERROR: + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +int _gst_unset_appsink(track *temp, int index, int loop) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + int count = 0; + if (index >= loop && index < 0) + goto ERROR; + while (count != index) { + temp = temp->next; + count++; + } + gst_app_sink_set_max_buffers((GstAppSink *)(temp->appsink), (guint) 0); + gst_app_sink_set_drop((GstAppSink *)(temp->appsink), true); + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +static int gst_demuxer_unset_track(MMHandleType pHandle, int track) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_INVALID_ARG; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; + + if (track >= new_mediademuxer->total_tracks || track < 0) { + goto ERROR; + } + new_mediademuxer->selected_tracks[track] = false; + _gst_unset_appsink((((mdgst_handle_t *) pHandle)->info).head, track, + new_mediademuxer->total_tracks); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int gst_demuxer_stop(MMHandleType pHandle) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) pHandle; + + MD_I("gst_demuxer_stop pipeine %p", gst_handle); + if (gst_element_set_state(gst_handle->pipeline, GST_STATE_PAUSED) == + GST_STATE_CHANGE_FAILURE) { + MD_E("Failed to set into PAUSE state"); + ret = MD_ERROR_UNKNOWN; + } + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +void _gst_clear_struct(mdgst_handle_t *gst_handle) +{ + MEDIADEMUXER_FENTER(); + if (gst_handle->selected_tracks) { + MD_I("Deallocating gst_handle->selected_tracks %p\n", + gst_handle->selected_tracks); + g_free(gst_handle->selected_tracks); + gst_handle->selected_tracks = NULL; + } + if ((gst_handle->info).head) { + __gst_free_stuct(&(gst_handle->info).head); + } + MEDIADEMUXER_FLEAVE(); +} + +int _md_gst_destroy_pipeline(GstElement *pipeline) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + if (pipeline) + MEDIADEMUXER_SET_STATE(pipeline, GST_STATE_NULL, ERROR); + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + if (pipeline) + gst_object_unref(GST_OBJECT(pipeline)); + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + +static int gst_demuxer_unprepare(MMHandleType pHandle) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) pHandle; + + _gst_clear_struct(gst_handle); + MD_I("gst_demuxer_stop pipeine %p\n", gst_handle->pipeline); + if (_md_gst_destroy_pipeline(gst_handle->pipeline) != MD_ERROR_NONE) { + ret = MD_ERROR; + goto ERROR; + } + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int gst_demuxer_destroy(MMHandleType pHandle) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; + + MD_I("gst_demuxer_destroy deallocating new_mediademuxer:%p\n", + new_mediademuxer); + g_free(new_mediademuxer); + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +int gst_set_error_cb(MMHandleType pHandle, + gst_error_cb callback, void *user_data) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) pHandle; + + if (!gst_handle) { + MD_E("fail invaild param\n"); + ret = MD_INVALID_ARG; + goto ERROR; + } + + if(gst_handle->user_cb[_GST_EVENT_TYPE_ERROR]) { + MD_E("Already set mediademuxer_error_cb\n"); + ret = MD_ERROR_INVALID_ARGUMENT; + goto ERROR; + } + else { + if (!callback) { + ret = MD_ERROR_INVALID_ARGUMENT; + goto ERROR; + } + } + + MD_I("Set event handler callback(cb = %p, data = %p)\n", callback, user_data); + + gst_handle->user_cb[_GST_EVENT_TYPE_ERROR] = (gst_error_cb) callback; + gst_handle->user_data[_GST_EVENT_TYPE_ERROR] = user_data; + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..d5feaa9 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,23 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_test "${fw_name}-test") + +INCLUDE_DIRECTORIES(../include) +INCLUDE_DIRECTORIES(../include/headers) +link_directories(${CMAKE_SOURCE_DIR}/../) + +INCLUDE(FindPkgConfig) +FOREACH(flag ${${fw_test}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +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} capi-mediademuxer ${${fw_test}_LDFLAGS}) +ENDFOREACH() + diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c new file mode 100755 index 0000000..963f369 --- /dev/null +++ b/test/mediademuxer_test.c @@ -0,0 +1,661 @@ +/* + * Copyright (c) 2015 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 FILES | +========================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------- +| GLOBAL VARIABLE DEFINITIONS: | +-----------------------------------------------------------------------*/ +#define MAX_STRING_LEN 100 +#define PACKAGE "mediademuxer_test" + +/*----------------------------------------------------------------------- +| GLOBAL CONSTANT DEFINITIONS: | +-----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------- +| IMPORTED VARIABLE DECLARATIONS: | +-----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------- +| IMPORTED FUNCTION DECLARATIONS: | +-----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------- +| LOCAL #defines: | +-----------------------------------------------------------------------*/ +/* + * D E B U G M E S S A G E + */ +#define MMF_DEBUG "** (demuxer testsuite) DEBUG: " +#define MMF_ERR "** (demuxer testsuite) ERROR: " +#define MMF_INFO "** (demuxer testsuite) INFO: " +#define MMF_WARN "** (demuxer testsuite) WARNING: " + +#define CHECK_MM_ERROR(expr) \ + do {\ + int ret = 0; \ + ret = expr; \ + if (ret != MD_ERROR_NONE) {\ + printf("[%s:%d] error code : %x \n", __func__, __LINE__, ret); \ + return; \ + }\ + } while(0) + +#define debug_msg_t(fmt,arg...)\ + do { \ + fprintf(stderr, MMF_DEBUG"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ + } while(0) + +#define err_msg_t(fmt,arg...)\ + do { \ + fprintf(stderr, MMF_ERR"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ + } while(0) + +#define info_msg_t(fmt,arg...)\ + do { \ + fprintf(stderr, MMF_INFO"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ + } while(0) + +#define warn_msg_t(fmt,arg...)\ + do { \ + fprintf(stderr, MMF_WARN"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ + } while(0) + +/*----------------------------------------------------------------------- +| LOCAL CONSTANT DEFINITIONS: | +-----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------- +| LOCAL DATA TYPE DEFINITIONS: | +-----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------- +| LOCAL VARIABLE DEFINITIONS: | +-----------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------- +| LOCAL FUNCTION PROTOTYPES: | +-----------------------------------------------------------------------*/ +#if 0 +int test_mediademuxer_create(); +int test_mediademuxer_destroy(); +int test_mediademuxer_prepare(); +int test_mediademuxer_unprepare(); +int test_mediademuxer_set_data_source(); +int test_mediademuxer_get_track_count(); +int test_mediademuxer_get_track_info(); +int test_mediademuxer_select_track(); +int test_mediademuxer_unselect_track(); +int test_mediademuxer_seek_to(); +int test_mediademuxer_read_sample(); +int test_mediademuxer_get_sample_track_index(); +int test_mediademuxer_get_sample_track_time(); +int test_mediademuxer_advance(); +int test_mediademuxer_is_key_frame(); +int test_mediademuxer_is_encrypted(); +int test_mediademuxe_audio_only(); +int test_mediademuxe_video_only(); +int test_mediademuxe_audio_video_only(); +#endif +int aud_track=-1; +int vid_track=-1; +mediademuxer_h demuxer = NULL; +int num_tracks = 0; +media_format_h *g_media_format = NULL; + +int test_mediademuxer_get_track_info() +{ + int ret = 0; + int track = 0; + int w; + int h; + int channel; + int samplerate; + media_format_mimetype_e mime; + g_print("test_mediademuxer_get_track_info\n"); + g_media_format = + (media_format_h *) g_malloc(sizeof(media_format_h) * num_tracks); + g_print("allocated %p memory for g_media_format\n", g_media_format); + if (g_media_format) { + for (; track < num_tracks; track++) { + if (ret == 0) { + g_print + ("g_media_format[%d] is created successfully! \n", + track); + ret = + mediademuxer_get_track_info(demuxer, track, + &g_media_format[track]); + if (ret == 0) { + if (media_format_get_video_info + (g_media_format[track], &mime, &w, + &h, NULL, + NULL) == MEDIA_FORMAT_ERROR_NONE) { + g_print + ("media_format_get_video_info is sucess!\n"); + g_print + ("\t\t[media_format_get_video]mime:%x, width :%d, height :%d\n", + mime, w, h); + vid_track = track; + } else if (media_format_get_audio_info + (g_media_format[track], &mime, + &channel, &samplerate, NULL, + NULL) == + MEDIA_FORMAT_ERROR_NONE) { + g_print + ("media_format_get_audio_info is sucess!\n"); + g_print + ("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d\n", + mime, channel, samplerate); + aud_track = track; + } else { + g_print("Not Supported YET"); + } + } else { + g_print + ("Error while getting mediademuxer_get_track_info\n"); + } + media_format_unref(g_media_format[track]); + g_media_format[track] = NULL; + } else { + g_print + ("Error while creating media_format_create\n"); + } + } + g_free(g_media_format); + g_media_format = NULL; + } else { + g_print("Error while allocating memory\n"); + } + + return ret; +} + +int test_mediademuxer_create() +{ + int ret = 0; + g_print("test_mediademuxer_create\n"); + ret = mediademuxer_create(&demuxer); + return ret; +} + +int test_mediademuxer_destroy() +{ + int ret = 0; + g_print("test_mediademuxer_destroy\n"); + ret = mediademuxer_destroy(demuxer); + demuxer = NULL; + return ret; +} + +int test_mediademuxer_prepare() +{ + int ret = 0; + g_print("test_mediademuxer_prepare\n"); + ret = mediademuxer_prepare(demuxer); + return ret; +} + +int test_mediademuxer_start() +{ + int ret = 0; + g_print("test_mediademuxer_start\n"); + ret = mediademuxer_start(demuxer); + return ret; +} + +int test_mediademuxer_get_state() +{ + g_print("test_mediademuxer_get_state\n"); + mediademuxer_state state; + if(mediademuxer_get_state(demuxer, &state) == MEDIADEMUXER_ERROR_NONE) { + g_print("\nMediademuxer_state=%d",state); + } + else { + g_print("\nMediademuxer_state call failed\n"); + } + return 0; +} + +int test_mediademuxer_stop() +{ + int ret = 0; + g_print("test_mediademuxer_stop\n"); + ret = mediademuxer_stop(demuxer); + return ret; +} + +int test_mediademuxer_unprepare() +{ + int ret = 0; + g_print("test_mediademuxer_unprepare\n"); + ret = mediademuxer_unprepare(demuxer); + return ret; +} + +int test_mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) +{ + int ret = 0; + g_print("test_mediademuxer_set_data_source\n"); + ret = mediademuxer_set_data_source(demuxer, path); + return ret; +} + +int test_mediademuxer_get_track_count() +{ + g_print("test_mediademuxer_get_track_count\n"); + mediademuxer_get_track_count(demuxer, &num_tracks); + g_print("Number of tracks [%d]", num_tracks); + return 0; +} + +int test_mediademuxer_select_track() +{ + g_print("test_mediademuxer_select_track\n"); + if (mediademuxer_select_track(demuxer, 0)) { + g_print("mediademuxer_select track 0 failed\n"); + return -1; + } + if (mediademuxer_select_track(demuxer, 1)) { + g_print("mediademuxer_select track 1 failed\n"); + return -1; + } + + return 0; +} + +int test_mediademuxer_unselect_track() +{ + g_print("test_mediademuxer_select_track\n"); + if (mediademuxer_unselect_track(demuxer, 0)) { + g_print("mediademuxer_select track 0 failed\n"); + return -1; + } + + return 0; +} + +int test_mediademuxer_seek_to() +{ + g_print("test_mediademuxer_seek_to\n"); + int64_t pos = 1; + mediademuxer_seek(demuxer, pos); + g_print("Number of tracks [%d]", num_tracks); + return 0; +} + +void app_err_cb(mediademuxer_error_e error, void *user_data) +{ + printf("Got Error %d from Mediademuxer\n",error); +} + +int test_mediademuxer_set_error_cb() +{ + int ret = 0; + g_print("test_mediademuxer_set_error_cb\n"); + ret = mediademuxer_set_error_cb(demuxer,app_err_cb,demuxer); + return ret; +} + +void *_fetch_audio_data(void *ptr) +{ + int *status = (int *)g_malloc(sizeof(int) * 1); + *status = -1; + g_print("Audio Data function\n"); + media_packet_h audbuf; + int count = 0; + + while (1) { + int EOS = mediademuxer_read_sample(demuxer, aud_track, &audbuf); + if (EOS == MD_EOS || EOS != MD_ERROR_NONE) + pthread_exit(NULL); + count++; + g_print("Read::[%d] audio sample\n", count); + media_packet_destroy(audbuf); + } + + *status = 0; + + return (void *)status; +} + +void *_fetch_video_data(void *ptr) +{ + int *status = (int *)g_malloc(sizeof(int) * 1); + media_packet_h vidbuf; + *status = -1; + g_print("Video Data function\n"); + int count = 0; + while (1) { + int EOS = mediademuxer_read_sample(demuxer, vid_track, &vidbuf); + if (EOS == MD_EOS || EOS != MD_ERROR_NONE) + pthread_exit(NULL); + count++; + g_print("Read::[%d] video sample\n", count); + media_packet_destroy(vidbuf); + } + *status = 0; + return (void *)status; +} + +int test_mediademuxer_read_sample() +{ + pthread_t thread[2]; + pthread_attr_t attr; + /* Initialize and set thread detached attribute */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if(vid_track != -1){ + g_print("In main: creating thread for video\n"); + pthread_create(&thread[0], &attr, _fetch_video_data, NULL); + } + if(aud_track != -1){ + g_print("In main: creating thread for audio\n"); + pthread_create(&thread[1], &attr, _fetch_audio_data, NULL); + } + pthread_attr_destroy(&attr); + return 0; +} + +int test_mediademuxer_get_sample_track_index() +{ + g_print("test_mediademuxer_get_sample_track_index\n"); + return 0; +} + +int test_mediademuxer_get_sample_track_time() +{ + g_print("test_mediademuxer_get_sample_track_time\n"); + return 0; +} + +int test_mediademuxer_advance() +{ + g_print("test_mediademuxer_advance\n"); + return 0; +} + +int test_mediademuxer_is_key_frame() +{ + g_print("test_mediademuxer_is_key_frame\n"); + return 0; +} + +int test_mediademuxer_is_encrypted() +{ + g_print("test_mediademuxer_is_encrypted\n"); + return 0; +} + +int test_mediademuxer_audio_only() +{ + g_print("AUDIO ONLY\n"); + return 0; +} + +int test_mediademuxer_video_only() +{ + g_print("VIDEO ONLY\n"); + return 0; +} + +int test_mediademuxer_audio_video_only() +{ + g_print("AUDIO & VIDEO ONLY\n"); + return 0; +} + +enum { + CURRENT_STATUS_MAINMENU, + CURRENT_STATUS_FILENAME, + CURRENT_STATUS_SET_DATA +}; + +int g_menu_state = CURRENT_STATUS_MAINMENU; + +static void display_sub_basic(); + +void reset_menu_state() +{ + g_menu_state = CURRENT_STATUS_MAINMENU; + return; +} + +void _interpret_main_menu(char *cmd) +{ + int len = strlen(cmd); + if (len == 1) { + if (strncmp(cmd, "a", 1) == 0) { + test_mediademuxer_create(); + } else if (strncmp(cmd, "d", 1) == 0) { + test_mediademuxer_unprepare(); + test_mediademuxer_destroy(); + } else if (strncmp(cmd, "s", 1) == 0) { + g_menu_state = CURRENT_STATUS_FILENAME; + } else if (strncmp(cmd, "q", 1) == 0) { + exit(0); + } else if (strncmp(cmd, "c", 1) == 0) { + test_mediademuxer_set_error_cb(); + } else { + g_print("unknown menu \n"); + } + } + + return; +} + +static void displaymenu(void) +{ + if (g_menu_state == CURRENT_STATUS_MAINMENU) { + display_sub_basic(); + } else if (g_menu_state == CURRENT_STATUS_FILENAME) { + g_print("*** input mediapath.\n"); + } else if (g_menu_state == CURRENT_STATUS_SET_DATA) { + g_print("\n"); + g_print + ("=========================================================================================\n"); + g_print + (" media demuxer submenu\n"); + g_print + ("-----------------------------------------------------------------------------------------\n"); + g_print("1.Get Track\t"); + g_print("2.Get Info\t"); + g_print("3.Select Track\t"); + g_print("4.Uselect Track\n"); + g_print("5.Seek\t"); + g_print("6.Read Sample\t"); + g_print("7.Get Sample Track Index\t"); + g_print("8.Get Sample Track Time\n"); + g_print("9.Advance\t"); + g_print("10.Is Key Frame\t"); + g_print("11.Is Key encrypted\t"); + g_print("a. start\n"); + g_print("b. stop\n"); + g_print("u. unprepare\n"); + g_print("s. get state\n"); + g_print("12.Go Back to main menu\n"); + g_print + ("-----------------------------------------------------------------------------------------\n"); + } else { + g_print("*** unknown status.\n"); + /* exit(0); */ + } + g_print(" >>> "); +} + +gboolean timeout_menu_display(void *data) +{ + displaymenu(); + return FALSE; +} + +static void interpret(char *cmd) +{ + switch (g_menu_state) { + case CURRENT_STATUS_MAINMENU: { + _interpret_main_menu(cmd); + break; + } + case CURRENT_STATUS_FILENAME: { + int ret = 0; + ret = test_mediademuxer_set_data_source(demuxer, cmd); + if (ret != MD_ERROR_INVALID_ARGUMENT) { + ret = test_mediademuxer_prepare(); + if (ret != MD_ERROR_INVALID_ARGUMENT) { + g_menu_state = CURRENT_STATUS_SET_DATA; + } else { + g_print + ("test_mediademuxer_prepare failed \n"); + g_menu_state = CURRENT_STATUS_FILENAME; + } + } else { + g_menu_state = CURRENT_STATUS_FILENAME; + } + break; + } + case CURRENT_STATUS_SET_DATA: { + int len = strlen(cmd); + + if (len == 1) { + if (strncmp(cmd, "1", len) == 0) { + test_mediademuxer_get_track_count(); + } else if (strncmp(cmd, "2", len) == 0) { + test_mediademuxer_get_track_info(); + } else if (strncmp(cmd, "3", len) == 0) { + test_mediademuxer_select_track(); + } else if (strncmp(cmd, "4", len) == 0) { + test_mediademuxer_unselect_track(); + } else if (strncmp(cmd, "5", len) == 0) { + test_mediademuxer_seek_to(); + } else if (strncmp(cmd, "6", len) == 0) { + test_mediademuxer_read_sample(); + } else if (strncmp(cmd, "7", len) == 0) { + test_mediademuxer_get_sample_track_index + (); + } else if (strncmp(cmd, "8", len) == 0) { + test_mediademuxer_get_sample_track_time + (); + } else if (strncmp(cmd, "9", len) == 0) { + test_mediademuxer_advance(); + } else if (strncmp(cmd, "a", len) == 0) { + test_mediademuxer_start(); + } else if (strncmp(cmd, "b", len) == 0) { + test_mediademuxer_stop(); + } else if (strncmp(cmd, "u", len) == 0) { + test_mediademuxer_unprepare(); + } else if (strncmp(cmd, "s", len) == 0) { + test_mediademuxer_get_state(); + } + } else if (len == 2) { + if (strncmp(cmd, "10", len) == 0) { + test_mediademuxer_is_key_frame(); + } else if (strncmp(cmd, "11", len) == 0) { + test_mediademuxer_is_encrypted(); + } else if (strncmp(cmd, "12", len) == 0) { + reset_menu_state(); + } else { + g_print("UNKNOW COMMAND\n"); + } + } else { + g_print("UNKNOW COMMAND\n"); + } + break; + } + default: + break; + } + g_timeout_add(100, timeout_menu_display, 0); +} + +static void display_sub_basic() +{ + g_print("\n"); + g_print + ("=========================================================================================\n"); + g_print(" media demuxer test\n"); + g_print + ("-----------------------------------------------------------------------------------------\n"); + g_print("a. Create \t"); + g_print("c. Set error_call_back\t"); + g_print("s. Setdata \t\t"); + g_print("d. Destroy \t\t"); + g_print("q. exit \t\t"); + g_print("\n"); + g_print + ("=========================================================================================\n"); +} + +/** + * This function is to execute command. + * + * @param channel [in] 1st parameter + * + * @return This function returns TRUE/FALSE + * @remark + * @see + */ +gboolean input(GIOChannel *channel) +{ + gchar buf[MAX_STRING_LEN]; + gsize read; + GError *error = NULL; + g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error); + buf[read] = '\0'; + g_strstrip(buf); + interpret(buf); + return TRUE; +} + +/** + * This function is the example main function for mediademuxer API. + * + * @param + * + * @return This function returns 0. + * @remark + * @see other functions + */ +int main(int argc, char *argv[]) +{ + GIOChannel *stdin_channel; + GMainLoop *loop = g_main_loop_new(NULL, 0); + stdin_channel = g_io_channel_unix_new(0); + g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL); + g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL); + + displaymenu(); + + g_print("RUN main loop\n"); + g_main_loop_run(loop); + g_print("STOP main loop\n"); + + g_main_loop_unref(loop); + return 0; +} -- 2.7.4 From d4c9b342b285b797a04460d0c3ab70ff8ab887ce Mon Sep 17 00:00:00 2001 From: Joungkook Seo Date: Mon, 10 Aug 2015 10:11:18 +0900 Subject: [PATCH 3/8] Update the code for sync with SPIN 2.4 (Demuxer) Change-Id: I4b8f58bc2117dc9c9b49f49af839d9abfbaa3460 Signed-off-by: Joungkook Seo --- src/port_gst/mediademuxer_port_gst.c | 36 +- test/mediademuxer_test.c | 666 ++++++++++++++++++++--------------- 2 files changed, 402 insertions(+), 300 deletions(-) diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 1ed26b9..3bd57dd 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -623,20 +623,15 @@ int _gst_set_appsink(track *temp, int index, int loop) MEDIADEMUXER_FENTER(); int ret = MD_ERROR_NONE; int count = 0; - if (index >= loop && index < 0) - goto ERROR; + while (count != index) { temp = temp->next; count++; } gst_app_sink_set_max_buffers((GstAppSink *)(temp->appsink), (guint) MAX_APP_BUFFER); gst_app_sink_set_drop((GstAppSink *)(temp->appsink), false); - MEDIADEMUXER_FLEAVE(); return ret; -ERROR: - MEDIADEMUXER_FLEAVE(); - return MD_ERROR; } static int gst_demuxer_set_track(MMHandleType pHandle, int track) @@ -646,7 +641,9 @@ static int gst_demuxer_set_track(MMHandleType pHandle, int track) MEDIADEMUXER_CHECK_NULL(pHandle); mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; + MD_I("total_tracks (%d) :: selected track (%d)", new_mediademuxer->total_tracks, track); if (track >= new_mediademuxer->total_tracks || track < 0) { + MD_E("total_tracks is less then selected track, So not support this track"); goto ERROR; } new_mediademuxer->selected_tracks[track] = true; @@ -721,8 +718,7 @@ int _set_mime_video(media_format_h format, track *head) goto ERROR; } if (gst_structure_has_name(struc, "video/x-h264")) { - const gchar *version = - gst_structure_get_string(struc, "stream-format"); + const gchar *version = gst_structure_get_string(struc, "stream-format"); if (strncmp(version, "avc", 3) == 0) { gst_structure_get_int(struc, "width", &src_width); gst_structure_get_int(struc, "height", &src_height); @@ -752,6 +748,8 @@ int _set_mime_audio(media_format_h format, track *head) int rate = 0; int channels = 0; int id3_flag = 0; + const gchar *stream_format; + struc = gst_caps_get_structure(head->caps, 0); if (!struc) { MD_E("cannot get structure from caps.\n"); @@ -768,6 +766,7 @@ int _set_mime_audio(media_format_h format, track *head) if (mpegversion == 4 || mpegversion == 2 ) { gst_structure_get_int(struc, "channels", &channels); gst_structure_get_int(struc, "rate", &rate); + stream_format = gst_structure_get_string(struc, "stream-format"); if (media_format_set_audio_mime(format, MEDIA_FORMAT_AAC_LC)) goto ERROR; if(channels == 0) @@ -780,6 +779,10 @@ int _set_mime_audio(media_format_h format, track *head) goto ERROR; if (media_format_set_audio_bit(format, 0)) goto ERROR; + if (strncmp(stream_format, "adts", 4) == 0) + media_format_set_audio_aac_type(format, 1); + else + media_format_set_audio_aac_type(format, 0); } if (mpegversion == 1 || id3_flag ) { gst_structure_get_int(struc, "layer", &layer); @@ -855,8 +858,10 @@ static int gst_demuxer_get_track_info(MMHandleType pHandle, (new_mediademuxer->info).num_audio_track + (new_mediademuxer->info).num_subtitle_track + (new_mediademuxer->info).num_other_track; - if (index >= loop && index < 0) + if (index >= loop || index < 0) { + MD_E("total tracks(loop) is less then selected track(index), So not support this track"); goto ERROR; + } ret = media_format_create(format); if(ret != MEDIA_FORMAT_ERROR_NONE){ @@ -985,11 +990,13 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, ret = MD_ERROR; goto ERROR; } + if (media_format_set_audio_mime(mediafmt, MEDIA_FORMAT_AAC)) { MD_E("media_format_set_audio_mime failed\n"); ret = MD_ERROR; goto ERROR; } + if (media_packet_create_alloc(mediafmt, NULL, NULL, &mediabuf)) { MD_E("media_packet_create_alloc failed\n"); ret = MD_ERROR; @@ -1002,6 +1009,7 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, ret = MD_ERROR; goto ERROR; } + if (media_format_set_video_mime(mediafmt, MEDIA_FORMAT_H264_SP)) { MD_E("media_format_set_ivideo_mime failed\n"); ret = MD_ERROR; @@ -1120,8 +1128,7 @@ int _gst_unset_appsink(track *temp, int index, int loop) MEDIADEMUXER_FENTER(); int ret = MD_ERROR_NONE; int count = 0; - if (index >= loop && index < 0) - goto ERROR; + while (count != index) { temp = temp->next; count++; @@ -1130,9 +1137,6 @@ int _gst_unset_appsink(track *temp, int index, int loop) gst_app_sink_set_drop((GstAppSink *)(temp->appsink), true); MEDIADEMUXER_FLEAVE(); return ret; -ERROR: - MEDIADEMUXER_FLEAVE(); - return MD_ERROR; } static int gst_demuxer_unset_track(MMHandleType pHandle, int track) @@ -1143,6 +1147,7 @@ static int gst_demuxer_unset_track(MMHandleType pHandle, int track) mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; if (track >= new_mediademuxer->total_tracks || track < 0) { + MD_E("total tracks is less then unselected track, So not support this track"); goto ERROR; } new_mediademuxer->selected_tracks[track] = false; @@ -1251,7 +1256,7 @@ int gst_set_error_cb(MMHandleType pHandle, mdgst_handle_t *gst_handle = (mdgst_handle_t *) pHandle; if (!gst_handle) { - MD_E("fail invaild param\n"); + MD_E("fail invaild param (gst_handle)\n"); ret = MD_INVALID_ARG; goto ERROR; } @@ -1263,6 +1268,7 @@ int gst_set_error_cb(MMHandleType pHandle, } else { if (!callback) { + MD_E("fail invaild argument (callback)\n"); ret = MD_ERROR_INVALID_ARGUMENT; goto ERROR; } diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index 963f369..4157563 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -31,25 +31,36 @@ #include /*----------------------------------------------------------------------- -| GLOBAL VARIABLE DEFINITIONS: | +| GLOBAL CONSTANT DEFINITIONS: | -----------------------------------------------------------------------*/ #define MAX_STRING_LEN 100 #define PACKAGE "mediademuxer_test" -/*----------------------------------------------------------------------- -| GLOBAL CONSTANT DEFINITIONS: | ------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------- -| IMPORTED VARIABLE DECLARATIONS: | ------------------------------------------------------------------------*/ +enum { + CURRENT_STATUS_MAINMENU, + CURRENT_STATUS_FILENAME, + CURRENT_STATUS_SET_DATA +}; /*----------------------------------------------------------------------- -| IMPORTED FUNCTION DECLARATIONS: | +| GLOBAL VARIABLE DEFINITIONS: | -----------------------------------------------------------------------*/ +mediademuxer_h demuxer = NULL; +media_format_h *g_media_format = NULL; +media_format_mimetype_e v_mime; +media_format_mimetype_e a_mime; +int g_menu_state = CURRENT_STATUS_MAINMENU; +int num_tracks = 0; +int aud_track =-1; +int vid_track =-1; +int w; +int h; +int channel = 0; +int samplerate = 0; +bool is_adts = 0; /*----------------------------------------------------------------------- -| LOCAL #defines: | +| DEBUG DEFINITIONS | -----------------------------------------------------------------------*/ /* * D E B U G M E S S A G E @@ -89,114 +100,75 @@ fprintf(stderr, MMF_WARN"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ } while(0) -/*----------------------------------------------------------------------- -| LOCAL CONSTANT DEFINITIONS: | ------------------------------------------------------------------------*/ /*----------------------------------------------------------------------- -| LOCAL DATA TYPE DEFINITIONS: | +| TEST VARIABLE DEFINITIONS: | -----------------------------------------------------------------------*/ +#define DEMUXER_OUTPUT_DUMP 1 -/*----------------------------------------------------------------------- -| LOCAL VARIABLE DEFINITIONS: | ------------------------------------------------------------------------*/ +#if DEMUXER_OUTPUT_DUMP +FILE *fp_audio_out = NULL; +FILE *fp_video_out = NULL; + +#define ADTS_HEADER_SIZE 7 +unsigned char buf_adts[ADTS_HEADER_SIZE]; + +#define AMR_NB_MIME_HDR_SIZE 6 +#define AMR_WB_MIME_HDR_SIZE 9 +static const char AMRNB_HDR [] = "#!AMR\n"; +static const char AMRWB_HDR [] = "#!AMR-WB\n"; +int write_amrnb_header = 0; /* write magic number for AMR-NB Header at one time */ +int write_amrwb_header = 0; /* write magic number for AMR-WB Header at one time */ +#endif /*----------------------------------------------------------------------- -| LOCAL FUNCTION PROTOTYPES: | +| HELPER FUNCTION | -----------------------------------------------------------------------*/ -#if 0 -int test_mediademuxer_create(); -int test_mediademuxer_destroy(); -int test_mediademuxer_prepare(); -int test_mediademuxer_unprepare(); -int test_mediademuxer_set_data_source(); -int test_mediademuxer_get_track_count(); -int test_mediademuxer_get_track_info(); -int test_mediademuxer_select_track(); -int test_mediademuxer_unselect_track(); -int test_mediademuxer_seek_to(); -int test_mediademuxer_read_sample(); -int test_mediademuxer_get_sample_track_index(); -int test_mediademuxer_get_sample_track_time(); -int test_mediademuxer_advance(); -int test_mediademuxer_is_key_frame(); -int test_mediademuxer_is_encrypted(); -int test_mediademuxe_audio_only(); -int test_mediademuxe_video_only(); -int test_mediademuxe_audio_video_only(); + +#if DEMUXER_OUTPUT_DUMP +/** + * Add ADTS header at the beginning of each and every AAC packet. + * This is needed as MediaCodec encoder generates a packet of raw AAC data. + * Note the packetLen must count in the ADTS header itself. + **/ +void generate_header_aac_adts(unsigned char *buffer, int packetLen) +{ + int profile = 2; //AAC LC (0x01) + int freqIdx = 4; //44KHz (0x04) + int chanCfg = 1; //CPE (0x01) + + if (samplerate == 96000) freqIdx = 0; + else if (samplerate == 88200) freqIdx = 1; + else if (samplerate == 64000) freqIdx = 2; + else if (samplerate == 48000) freqIdx = 3; + else if (samplerate == 44100) freqIdx = 4; + else if (samplerate == 32000) freqIdx = 5; + else if (samplerate == 24000) freqIdx = 6; + else if (samplerate == 22050) freqIdx = 7; + else if (samplerate == 16000) freqIdx = 8; + else if (samplerate == 12000) freqIdx = 9; + else if (samplerate == 11025) freqIdx = 10; + else if (samplerate == 8000) freqIdx = 11; + + if ((channel == 1) || (channel == 2)) + chanCfg = channel; + + /* Make ADTS header */ + buffer[0] = (char)0xFF; + buffer[1] = (char)0xF1; + buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2)); + buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11)); + buffer[4] = (char)((packetLen&0x7FF) >> 3); + buffer[5] = (char)(((packetLen&7)<<5) + 0x1F); + buffer[6] = (char)0xFC; +} #endif -int aud_track=-1; -int vid_track=-1; -mediademuxer_h demuxer = NULL; -int num_tracks = 0; -media_format_h *g_media_format = NULL; -int test_mediademuxer_get_track_info() -{ - int ret = 0; - int track = 0; - int w; - int h; - int channel; - int samplerate; - media_format_mimetype_e mime; - g_print("test_mediademuxer_get_track_info\n"); - g_media_format = - (media_format_h *) g_malloc(sizeof(media_format_h) * num_tracks); - g_print("allocated %p memory for g_media_format\n", g_media_format); - if (g_media_format) { - for (; track < num_tracks; track++) { - if (ret == 0) { - g_print - ("g_media_format[%d] is created successfully! \n", - track); - ret = - mediademuxer_get_track_info(demuxer, track, - &g_media_format[track]); - if (ret == 0) { - if (media_format_get_video_info - (g_media_format[track], &mime, &w, - &h, NULL, - NULL) == MEDIA_FORMAT_ERROR_NONE) { - g_print - ("media_format_get_video_info is sucess!\n"); - g_print - ("\t\t[media_format_get_video]mime:%x, width :%d, height :%d\n", - mime, w, h); - vid_track = track; - } else if (media_format_get_audio_info - (g_media_format[track], &mime, - &channel, &samplerate, NULL, - NULL) == - MEDIA_FORMAT_ERROR_NONE) { - g_print - ("media_format_get_audio_info is sucess!\n"); - g_print - ("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d\n", - mime, channel, samplerate); - aud_track = track; - } else { - g_print("Not Supported YET"); - } - } else { - g_print - ("Error while getting mediademuxer_get_track_info\n"); - } - media_format_unref(g_media_format[track]); - g_media_format[track] = NULL; - } else { - g_print - ("Error while creating media_format_create\n"); - } - } - g_free(g_media_format); - g_media_format = NULL; - } else { - g_print("Error while allocating memory\n"); - } - return ret; -} + +/*----------------------------------------------------------------------- +| LOCAL FUNCTION | +-----------------------------------------------------------------------*/ int test_mediademuxer_create() { @@ -206,12 +178,17 @@ int test_mediademuxer_create() return ret; } -int test_mediademuxer_destroy() +int test_mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) { int ret = 0; - g_print("test_mediademuxer_destroy\n"); - ret = mediademuxer_destroy(demuxer); - demuxer = NULL; + g_print("test_mediademuxer_set_data_source\n"); + +#if DEMUXER_OUTPUT_DUMP + fp_audio_out = fopen("/opt/usr/media/dump_audio.out", "wb"); + fp_video_out = fopen("/opt/usr/media/dump_video.out", "wb"); +#endif + + ret = mediademuxer_set_data_source(demuxer, path); return ret; } @@ -223,142 +200,184 @@ int test_mediademuxer_prepare() return ret; } -int test_mediademuxer_start() -{ - int ret = 0; - g_print("test_mediademuxer_start\n"); - ret = mediademuxer_start(demuxer); - return ret; -} - -int test_mediademuxer_get_state() -{ - g_print("test_mediademuxer_get_state\n"); - mediademuxer_state state; - if(mediademuxer_get_state(demuxer, &state) == MEDIADEMUXER_ERROR_NONE) { - g_print("\nMediademuxer_state=%d",state); - } - else { - g_print("\nMediademuxer_state call failed\n"); - } - return 0; -} - -int test_mediademuxer_stop() -{ - int ret = 0; - g_print("test_mediademuxer_stop\n"); - ret = mediademuxer_stop(demuxer); - return ret; -} - -int test_mediademuxer_unprepare() -{ - int ret = 0; - g_print("test_mediademuxer_unprepare\n"); - ret = mediademuxer_unprepare(demuxer); - return ret; -} - -int test_mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) -{ - int ret = 0; - g_print("test_mediademuxer_set_data_source\n"); - ret = mediademuxer_set_data_source(demuxer, path); - return ret; -} - int test_mediademuxer_get_track_count() { g_print("test_mediademuxer_get_track_count\n"); mediademuxer_get_track_count(demuxer, &num_tracks); - g_print("Number of tracks [%d]", num_tracks); + g_print("Number of total tracks [%d]\n", num_tracks); return 0; } int test_mediademuxer_select_track() { + int track = 0; g_print("test_mediademuxer_select_track\n"); - if (mediademuxer_select_track(demuxer, 0)) { - g_print("mediademuxer_select track 0 failed\n"); - return -1; - } - if (mediademuxer_select_track(demuxer, 1)) { - g_print("mediademuxer_select track 1 failed\n"); - return -1; + for (track = 0; track < num_tracks; track++) { + if (mediademuxer_select_track(demuxer, track)) { + g_print("mediademuxer_select_track index [%d] failed\n", track); + return -1; + } + g_print("select track index is [%d] of the total track [%d]\n", track, num_tracks); } - return 0; } -int test_mediademuxer_unselect_track() +int test_mediademuxer_start() { - g_print("test_mediademuxer_select_track\n"); - if (mediademuxer_unselect_track(demuxer, 0)) { - g_print("mediademuxer_select track 0 failed\n"); - return -1; - } - - return 0; + int ret = 0; + g_print("test_mediademuxer_start\n"); + ret = mediademuxer_start(demuxer); + return ret; } -int test_mediademuxer_seek_to() +int test_mediademuxer_get_track_info() { - g_print("test_mediademuxer_seek_to\n"); - int64_t pos = 1; - mediademuxer_seek(demuxer, pos); - g_print("Number of tracks [%d]", num_tracks); - return 0; -} + int ret = 0; + int track = 0; -void app_err_cb(mediademuxer_error_e error, void *user_data) -{ - printf("Got Error %d from Mediademuxer\n",error); -} + g_print("test_mediademuxer_get_track_info\n"); + g_media_format = + (media_format_h *) g_malloc(sizeof(media_format_h) * num_tracks); + g_print("allocated %p memory for g_media_format\n", g_media_format); + if (g_media_format) { + for (; track < num_tracks; track++) { + if (ret == 0) { + g_print("g_media_format[%d] is created successfully! \n", track); + ret = mediademuxer_get_track_info(demuxer, track, + &g_media_format[track]); + if (ret == 0) { + if (media_format_get_video_info(g_media_format[track], &v_mime, + &w, &h, NULL, NULL) == MEDIA_FORMAT_ERROR_NONE) { + g_print("media_format_get_video_info is sucess!\n"); + g_print("\t\t[media_format_get_video]mime:%x, width :%d, height :%d\n", + v_mime, w, h); + vid_track = track; + } else if (media_format_get_audio_info(g_media_format[track], &a_mime, + &channel, &samplerate, NULL, NULL) == MEDIA_FORMAT_ERROR_NONE) { + g_print("media_format_get_audio_info is sucess!\n"); + g_print("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d\n", + a_mime, channel, samplerate); + media_format_get_audio_aac_type(g_media_format[track], &is_adts); + aud_track = track; + } else { + g_print("Not Supported YET"); + } + } else { + g_print("Error while getting mediademuxer_get_track_info\n"); + } + media_format_unref(g_media_format[track]); + g_media_format[track] = NULL; + } else { + g_print("Error while creating media_format_create\n"); + } + } + g_free(g_media_format); + g_media_format = NULL; + } else { + g_print("Error while allocating memory\n"); + } + +#if DEMUXER_OUTPUT_DUMP + if ((a_mime == MEDIA_FORMAT_AAC_LC) && (is_adts == 0)) { + g_print("MIME : MEDIA_FORMAT_AAC_LC ------Need to add header for dump test \n"); + } else if (a_mime == MEDIA_FORMAT_AMR_NB) { + g_print("MIME : MEDIA_FORMAT_AMR_NB ------Need to add header for dump test \n"); + write_amrnb_header = 1; + } else if (a_mime == MEDIA_FORMAT_AMR_WB) { + g_print("MIME : MEDIA_FORMAT_AMR_WB ------Need to add header for dump test \n"); + write_amrwb_header = 1; + } else + g_print("--------------------------- Don't Need to add header for dump test\n"); +#endif -int test_mediademuxer_set_error_cb() -{ - int ret = 0; - g_print("test_mediademuxer_set_error_cb\n"); - ret = mediademuxer_set_error_cb(demuxer,app_err_cb,demuxer); return ret; } void *_fetch_audio_data(void *ptr) { + int ret = MD_ERROR_NONE; int *status = (int *)g_malloc(sizeof(int) * 1); - *status = -1; - g_print("Audio Data function\n"); media_packet_h audbuf; int count = 0; + uint64_t buf_size = 0; + void *data = NULL; + *status = -1; + g_print("Audio Data function\n"); while (1) { - int EOS = mediademuxer_read_sample(demuxer, aud_track, &audbuf); - if (EOS == MD_EOS || EOS != MD_ERROR_NONE) + ret = mediademuxer_read_sample(demuxer, aud_track, &audbuf); + if (ret == MD_EOS) { + g_print("EOS return of mediademuxer_read_sample()\n"); pthread_exit(NULL); + } else if (ret != MD_ERROR_NONE) { + g_print("Error (%d) return of mediademuxer_read_sample()\n", ret); + pthread_exit(NULL); + } count++; - g_print("Read::[%d] audio sample\n", count); + media_packet_get_buffer_size(audbuf, &buf_size); + media_packet_get_buffer_data_ptr(audbuf, &data); + g_print("Audio Read Count::[%4d] frame - get_buffer_size = %lld\n", count, buf_size); + +#if DEMUXER_OUTPUT_DUMP + if ((a_mime == MEDIA_FORMAT_AAC_LC) && (is_adts == 0)) { + /* This is used only AAC raw case for adding each ADTS frame header */ + generate_header_aac_adts(buf_adts, (buf_size+ADTS_HEADER_SIZE)); + fwrite(&buf_adts[0], 1, ADTS_HEADER_SIZE, fp_audio_out); + } else if ((a_mime == MEDIA_FORMAT_AMR_NB) && (write_amrnb_header == 1)) { + /* This is used only AMR-NB case for adding magic header in only first frame */ + g_print("%s - AMRNB_HDR write in first frame\n",__func__); + fwrite(&AMRNB_HDR[0], 1, sizeof(AMRNB_HDR) - 1, fp_audio_out); + write_amrnb_header = 0; + } else if ((a_mime == MEDIA_FORMAT_AMR_WB) && (write_amrwb_header == 1)) { + /* This is used only AMR-WB case for adding magic header in only first frame */ + g_print("%s - AMRWB_HDR write in first frame\n",__func__); + fwrite(&AMRWB_HDR[0], 1, sizeof(AMRWB_HDR) - 1, fp_audio_out); + write_amrwb_header = 0; + } + + if (data != NULL) + fwrite(data, 1, buf_size, fp_audio_out); + else + g_print("DUMP : write(audio data) fail for NULL\n"); +#endif media_packet_destroy(audbuf); } *status = 0; - return (void *)status; } void *_fetch_video_data(void *ptr) { + int ret = MD_ERROR_NONE; int *status = (int *)g_malloc(sizeof(int) * 1); media_packet_h vidbuf; + int count = 0; + uint64_t buf_size = 0; + void *data = NULL; + *status = -1; g_print("Video Data function\n"); - int count = 0; while (1) { - int EOS = mediademuxer_read_sample(demuxer, vid_track, &vidbuf); - if (EOS == MD_EOS || EOS != MD_ERROR_NONE) + ret = mediademuxer_read_sample(demuxer, vid_track, &vidbuf); + if (ret == MD_EOS) { + g_print("EOS return of mediademuxer_read_sample()\n"); + pthread_exit(NULL); + } else if (ret != MD_ERROR_NONE) { + g_print("Error (%d) return of mediademuxer_read_sample()\n", ret); pthread_exit(NULL); + } count++; - g_print("Read::[%d] video sample\n", count); + media_packet_get_buffer_size(vidbuf, &buf_size); + media_packet_get_buffer_data_ptr(vidbuf, &data); + g_print("Video Read Count::[%4d] frame - get_buffer_size = %lld\n", count, buf_size); + +#if DEMUXER_OUTPUT_DUMP + if (data != NULL) + fwrite(data, 1, buf_size, fp_video_out); + else + g_print("DUMP : write(video data) fail for NULL\n"); +#endif media_packet_destroy(vidbuf); } *status = 0; @@ -384,6 +403,96 @@ int test_mediademuxer_read_sample() return 0; } +int test_mediademuxer_seek_to() +{ + g_print("test_mediademuxer_seek_to\n"); + int64_t pos = 1; + mediademuxer_seek(demuxer, pos); + g_print("Number of tracks [%d]\n", num_tracks); + return 0; +} + +int test_mediademuxer_unselect_track() +{ + g_print("test_mediademuxer_select_track\n"); + if (mediademuxer_unselect_track(demuxer, 0)) { + g_print("mediademuxer_select track 0 failed\n"); + return -1; + } + return 0; +} + +int test_mediademuxer_stop() +{ + int ret = 0; + g_print("test_mediademuxer_stop\n"); + ret = mediademuxer_stop(demuxer); + return ret; +} + +int test_mediademuxer_unprepare() +{ + int ret = 0; + g_print("test_mediademuxer_unprepare\n"); + ret = mediademuxer_unprepare(demuxer); + return ret; +} + +int test_mediademuxer_destroy() +{ + int ret = 0; + g_print("test_mediademuxer_destroy\n"); + ret = mediademuxer_destroy(demuxer); + demuxer = NULL; + +#if DEMUXER_OUTPUT_DUMP + if (fp_audio_out) + fclose(fp_audio_out); + if (fp_video_out) + fclose(fp_video_out); +#endif + return ret; +} + +int test_mediademuxer_get_state() +{ + g_print("test_mediademuxer_get_state\n"); + mediademuxer_state state; + if(mediademuxer_get_state(demuxer, &state) == MEDIADEMUXER_ERROR_NONE) { + if (state == MEDIADEMUXER_NONE) + g_print("Mediademuxer_state = NONE\n"); + else if (state == MEDIADEMUXER_IDLE) + g_print("Mediademuxer_state = IDLE\n"); + else if (state == MEDIADEMUXER_READY) + g_print("Mediademuxer_state = READY\n"); + else if (state == MEDIADEMUXER_DEMUXING) + g_print("Mediademuxer_state = DEMUXING\n"); + else + g_print("Mediademuxer_state = NOT SUPPORT STATE\n"); + } + else { + g_print("Mediademuxer_state call failed\n"); + } + return 0; +} + +void app_err_cb(mediademuxer_error_e error, void *user_data) +{ + printf("Got Error %d from Mediademuxer\n",error); +} + +int test_mediademuxer_set_error_cb() +{ + int ret = 0; + g_print("test_mediademuxer_set_error_cb\n"); + ret = mediademuxer_set_error_cb(demuxer,app_err_cb,demuxer); + return ret; +} + + +/*----------------------------------------------------------------------- +| EXTRA FUNCTION | +-----------------------------------------------------------------------*/ int test_mediademuxer_get_sample_track_index() { g_print("test_mediademuxer_get_sample_track_index\n"); @@ -432,42 +541,43 @@ int test_mediademuxer_audio_video_only() return 0; } -enum { - CURRENT_STATUS_MAINMENU, - CURRENT_STATUS_FILENAME, - CURRENT_STATUS_SET_DATA -}; - -int g_menu_state = CURRENT_STATUS_MAINMENU; - -static void display_sub_basic(); - -void reset_menu_state() +/*----------------------------------------------------------------------- +| TEST FUNCTION | +-----------------------------------------------------------------------*/ +static void display_sub_basic() { - g_menu_state = CURRENT_STATUS_MAINMENU; - return; + g_print("\n"); + g_print("===========================================================================\n"); + g_print(" media demuxer test\n"); + g_print(" SELECT : c -> (s) -> p -> (goto submenu) -> d -> q \n"); + g_print("---------------------------------------------------------------------------\n"); + g_print("c. Create \t"); + g_print("s. Set callback \t"); + g_print("p. Path \t"); + g_print("d. Destroy \t"); + g_print("q. Quit \n"); + g_print("---------------------------------------------------------------------------\n"); } void _interpret_main_menu(char *cmd) { int len = strlen(cmd); if (len == 1) { - if (strncmp(cmd, "a", 1) == 0) { + if (strncmp(cmd, "c", 1) == 0) { test_mediademuxer_create(); + } else if (strncmp(cmd, "s", 1) == 0) { + test_mediademuxer_set_error_cb(); + } else if (strncmp(cmd, "p", 1) == 0) { + g_menu_state = CURRENT_STATUS_FILENAME; } else if (strncmp(cmd, "d", 1) == 0) { test_mediademuxer_unprepare(); test_mediademuxer_destroy(); - } else if (strncmp(cmd, "s", 1) == 0) { - g_menu_state = CURRENT_STATUS_FILENAME; } else if (strncmp(cmd, "q", 1) == 0) { exit(0); - } else if (strncmp(cmd, "c", 1) == 0) { - test_mediademuxer_set_error_cb(); } else { g_print("unknown menu \n"); } } - return; } @@ -476,33 +586,30 @@ static void displaymenu(void) if (g_menu_state == CURRENT_STATUS_MAINMENU) { display_sub_basic(); } else if (g_menu_state == CURRENT_STATUS_FILENAME) { - g_print("*** input mediapath.\n"); + g_print("*** input media path.\n"); } else if (g_menu_state == CURRENT_STATUS_SET_DATA) { g_print("\n"); - g_print - ("=========================================================================================\n"); - g_print - (" media demuxer submenu\n"); - g_print - ("-----------------------------------------------------------------------------------------\n"); - g_print("1.Get Track\t"); - g_print("2.Get Info\t"); - g_print("3.Select Track\t"); - g_print("4.Uselect Track\n"); - g_print("5.Seek\t"); - g_print("6.Read Sample\t"); - g_print("7.Get Sample Track Index\t"); - g_print("8.Get Sample Track Time\n"); - g_print("9.Advance\t"); - g_print("10.Is Key Frame\t"); - g_print("11.Is Key encrypted\t"); - g_print("a. start\n"); - g_print("b. stop\n"); - g_print("u. unprepare\n"); - g_print("s. get state\n"); - g_print("12.Go Back to main menu\n"); - g_print - ("-----------------------------------------------------------------------------------------\n"); + g_print("=============================================================\n"); + g_print(" media demuxer submenu\n"); + g_print(" SELECT from 1 to 9, others are option \n"); + g_print("-------------------------------------------------------------\n"); + g_print(" 1. Get Track\t"); + g_print(" 2. Select Track\n"); + g_print(" 3. Start\t"); + g_print(" 4. Get Info\n"); + g_print(" 5. Read Sample\n"); + g_print(" 6. Stop\t"); + g_print(" 7. Unprepare\t"); + g_print(" 8. Get state\n"); + g_print(" 9. Go Back to main menu\n"); + g_print(" a. Seek\t"); + g_print(" b. Uselect Track\n"); + g_print(" c. Get Sample Track Index\t"); + g_print(" d. Get Sample Track Time\n"); + g_print(" e. Advance\t"); + g_print(" f. Is Key Frame\t"); + g_print(" g. Is Key encrypted\n"); + g_print("-------------------------------------------------------------\n"); } else { g_print("*** unknown status.\n"); /* exit(0); */ @@ -510,6 +617,12 @@ static void displaymenu(void) g_print(" >>> "); } +void reset_menu_state() +{ + g_menu_state = CURRENT_STATUS_MAINMENU; + return; +} + gboolean timeout_menu_display(void *data) { displaymenu(); @@ -531,8 +644,7 @@ static void interpret(char *cmd) if (ret != MD_ERROR_INVALID_ARGUMENT) { g_menu_state = CURRENT_STATUS_SET_DATA; } else { - g_print - ("test_mediademuxer_prepare failed \n"); + g_print("test_mediademuxer_prepare failed \n"); g_menu_state = CURRENT_STATUS_FILENAME; } } else { @@ -547,39 +659,41 @@ static void interpret(char *cmd) if (strncmp(cmd, "1", len) == 0) { test_mediademuxer_get_track_count(); } else if (strncmp(cmd, "2", len) == 0) { - test_mediademuxer_get_track_info(); - } else if (strncmp(cmd, "3", len) == 0) { test_mediademuxer_select_track(); + } else if (strncmp(cmd, "3", len) == 0) { + test_mediademuxer_start(); } else if (strncmp(cmd, "4", len) == 0) { - test_mediademuxer_unselect_track(); + test_mediademuxer_get_track_info(); } else if (strncmp(cmd, "5", len) == 0) { - test_mediademuxer_seek_to(); - } else if (strncmp(cmd, "6", len) == 0) { test_mediademuxer_read_sample(); + } else if (strncmp(cmd, "6", len) == 0) { + test_mediademuxer_stop(); } else if (strncmp(cmd, "7", len) == 0) { - test_mediademuxer_get_sample_track_index - (); + test_mediademuxer_unprepare(); } else if (strncmp(cmd, "8", len) == 0) { - test_mediademuxer_get_sample_track_time - (); + test_mediademuxer_get_state(); } else if (strncmp(cmd, "9", len) == 0) { - test_mediademuxer_advance(); + reset_menu_state(); } else if (strncmp(cmd, "a", len) == 0) { - test_mediademuxer_start(); + test_mediademuxer_seek_to(); } else if (strncmp(cmd, "b", len) == 0) { - test_mediademuxer_stop(); - } else if (strncmp(cmd, "u", len) == 0) { - test_mediademuxer_unprepare(); - } else if (strncmp(cmd, "s", len) == 0) { - test_mediademuxer_get_state(); + test_mediademuxer_unselect_track(); + } else if (strncmp(cmd, "c", len) == 0) { + test_mediademuxer_get_sample_track_index(); + } else if (strncmp(cmd, "d", len) == 0) { + test_mediademuxer_get_sample_track_time(); + } else if (strncmp(cmd, "e", len) == 0) { + test_mediademuxer_advance(); + } else if (strncmp(cmd, "f", len) == 0) { + test_mediademuxer_is_key_frame(); + } else if (strncmp(cmd, "g", len) == 0) { + test_mediademuxer_is_encrypted(); + } else { + g_print("UNKNOW COMMAND\n"); } } else if (len == 2) { if (strncmp(cmd, "10", len) == 0) { - test_mediademuxer_is_key_frame(); - } else if (strncmp(cmd, "11", len) == 0) { - test_mediademuxer_is_encrypted(); - } else if (strncmp(cmd, "12", len) == 0) { - reset_menu_state(); + g_print("UNKNOW COMMAND\n"); } else { g_print("UNKNOW COMMAND\n"); } @@ -594,24 +708,6 @@ static void interpret(char *cmd) g_timeout_add(100, timeout_menu_display, 0); } -static void display_sub_basic() -{ - g_print("\n"); - g_print - ("=========================================================================================\n"); - g_print(" media demuxer test\n"); - g_print - ("-----------------------------------------------------------------------------------------\n"); - g_print("a. Create \t"); - g_print("c. Set error_call_back\t"); - g_print("s. Setdata \t\t"); - g_print("d. Destroy \t\t"); - g_print("q. exit \t\t"); - g_print("\n"); - g_print - ("=========================================================================================\n"); -} - /** * This function is to execute command. * -- 2.7.4 From d70a50893d90d93dc8505aeba9fc67a2b5fc54ff Mon Sep 17 00:00:00 2001 From: Joungkook Seo Date: Tue, 11 Aug 2015 18:30:51 +0900 Subject: [PATCH 4/8] Fixed build error 64bits repos (Demuxer) Change-Id: I67e170e8eb09c498b776a6d55a8af2df591302a2 Signed-off-by: Joungkook Seo --- src/mediademuxer_port.c | 3 +-- test/mediademuxer_test.c | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index 346c99e..4bc955c 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -127,8 +127,7 @@ int __md_util_exist_file_path(const char *file_path) MEDIADEMUXER_FLEAVE(); return MD_ERROR_FILE_NOT_FOUND; } else { - MD_E("file size : %lld bytes\n", - (long long)stat_results.st_size); + MD_E("file size : %lld bytes\n", (long long)stat_results.st_size); } close(fd); MEDIADEMUXER_FLEAVE(); diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index 4157563..0b3e69b 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -316,7 +317,7 @@ void *_fetch_audio_data(void *ptr) count++; media_packet_get_buffer_size(audbuf, &buf_size); media_packet_get_buffer_data_ptr(audbuf, &data); - g_print("Audio Read Count::[%4d] frame - get_buffer_size = %lld\n", count, buf_size); + g_print("Audio Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size); #if DEMUXER_OUTPUT_DUMP if ((a_mime == MEDIA_FORMAT_AAC_LC) && (is_adts == 0)) { @@ -370,7 +371,7 @@ void *_fetch_video_data(void *ptr) count++; media_packet_get_buffer_size(vidbuf, &buf_size); media_packet_get_buffer_data_ptr(vidbuf, &data); - g_print("Video Read Count::[%4d] frame - get_buffer_size = %lld\n", count, buf_size); + g_print("Video Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size); #if DEMUXER_OUTPUT_DUMP if (data != NULL) -- 2.7.4 From ad8cc211493a80c3778641984ff811d19812a031 Mon Sep 17 00:00:00 2001 From: Joungkook Seo Date: Tue, 25 Aug 2015 19:43:42 +0900 Subject: [PATCH 5/8] Sync with 2.4 (Updated test application to validate h264 and AAC format with mediacodec) [1] Provided byte stream format for h264 video Change-Id: Ieeb822e99bc1d07fa217442281229fea9f5abaab Signed-off-by: Joungkook Seo --- CMakeLists.txt | 2 +- packaging/capi-mediademuxer.spec | 1 + src/port_gst/mediademuxer_port_gst.c | 79 ++++++++++- test/mediademuxer_test.c | 259 ++++++++++++++++++++++++++++++++++- 4 files changed, 328 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b064642..4c7acfa 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ SET(INC_PORT_CUSTOM_DIR include/port_custom) SET(INC_PORT_FFMPEG_DIR include/port_ffmpeg) INCLUDE_DIRECTORIES(${INC_DIR} ${INC_PORT_GST_DIR} ${INC_PORT_CUSTOM_DIR} ${INC_PORT_FFMPEG_DIR}) -SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0") +SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-media-codec") SET(pc_dependents "capi-base-common capi-media-tool") INCLUDE(FindPkgConfig) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index d25b022..73e5ae6 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -11,6 +11,7 @@ BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(mm-common) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-media-tool) +BuildRequires: pkgconfig(capi-media-codec) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(gstreamer-1.0) BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 3bd57dd..96944b5 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -25,6 +25,7 @@ #include #include #include +#include static int gst_demuxer_init(MMHandleType *pHandle); static int gst_demuxer_prepare(MMHandleType pHandle, char *uri); @@ -213,7 +214,11 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, { MEDIADEMUXER_FENTER(); GstPad *apppad = NULL; + GstCaps *outcaps = NULL; + GstPad *parse_sink_pad = NULL; + GstElement *parse_element = NULL; track *temp = NULL; + temp = (track *)(g_malloc(sizeof(track))); if (!temp) { MD_E("Not able to allocate memory"); @@ -241,7 +246,34 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, __gst_free_stuct(head); return MD_ERROR; } - MEDIADEMUXER_LINK_PAD(pad, apppad, ERROR); + /* Check for type video and it should be h264 */ + if (strstr(name, "video") && strstr(temp->caps_string, "h264")) { + parse_element = gst_element_factory_make("h264parse", NULL); + if (!parse_element) { + MD_E("factory not able to make h264parse"); + __gst_free_stuct(head); + gst_object_unref(apppad); + return MD_ERROR; + } + gst_bin_add_many(GST_BIN(pipeline),parse_element, NULL); + MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR); + + parse_sink_pad = gst_element_get_static_pad(parse_element, "sink"); + if (!parse_sink_pad) { + MD_E("sink pad of h264parse not available"); + __gst_free_stuct(head); + gst_object_unref(apppad); + return MD_ERROR; + } + + /* Link demuxer pad with sink pad of parse element*/ + MEDIADEMUXER_LINK_PAD(pad, parse_sink_pad, ERROR); + + outcaps = gst_caps_new_simple("video/x-h264", "stream-format",G_TYPE_STRING, "byte-stream", NULL); + gst_element_link_filtered(parse_element, temp->appsink, outcaps); + } else { + MEDIADEMUXER_LINK_PAD(pad, apppad, ERROR); + } /*gst_pad_link(pad, fpad) */ if (*head == NULL) { *head = temp; @@ -746,6 +778,7 @@ int _set_mime_audio(media_format_h format, track *head) int ret = MD_ERROR_NONE; GstStructure *struc = NULL; int rate = 0; + int bit = 0; int channels = 0; int id3_flag = 0; const gchar *stream_format; @@ -766,6 +799,7 @@ int _set_mime_audio(media_format_h format, track *head) if (mpegversion == 4 || mpegversion == 2 ) { gst_structure_get_int(struc, "channels", &channels); gst_structure_get_int(struc, "rate", &rate); + gst_structure_get_int(struc, "bit", &bit); stream_format = gst_structure_get_string(struc, "stream-format"); if (media_format_set_audio_mime(format, MEDIA_FORMAT_AAC_LC)) goto ERROR; @@ -777,8 +811,12 @@ int _set_mime_audio(media_format_h format, track *head) rate = 44100; /* default */ if (media_format_set_audio_samplerate(format, rate)) goto ERROR; - if (media_format_set_audio_bit(format, 0)) + if(bit == 0) { + bit = 16; /* default */ + } + if (media_format_set_audio_bit(format, bit)) { goto ERROR; + } if (strncmp(stream_format, "adts", 4) == 0) media_format_set_audio_aac_type(format, 1); else @@ -789,6 +827,7 @@ int _set_mime_audio(media_format_h format, track *head) if((layer == 3) || (id3_flag == 1)) { gst_structure_get_int(struc, "channels", &channels); gst_structure_get_int(struc, "rate", &rate); + gst_structure_get_int(struc, "bit", &bit); if (media_format_set_audio_mime(format, MEDIA_FORMAT_MP3)) goto ERROR; if(channels == 0) @@ -799,7 +838,7 @@ int _set_mime_audio(media_format_h format, track *head) rate = 44100; /* default */ if (media_format_set_audio_samplerate(format, rate)) goto ERROR; - if (media_format_set_audio_bit(format, 0)) + if (media_format_set_audio_bit(format, bit)) goto ERROR; } else { @@ -893,7 +932,7 @@ ERROR: } static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt, - GstBuffer *buffer) + GstBuffer *buffer, char *codec_data) { MEDIADEMUXER_FENTER(); int ret = MD_ERROR_NONE; @@ -948,6 +987,13 @@ static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt, ret = MD_ERROR_UNKNOWN; goto ERROR; } + if (codec_data) { + if (media_packet_set_codec_data(out_pkt, (void*) codec_data, strlen(codec_data))) { + MD_E("unable to set the codec data\n"); + ret = MD_ERROR_UNKNOWN; + goto ERROR; + } + } ERROR: gst_buffer_unmap(buffer, &map); MEDIADEMUXER_FLEAVE(); @@ -965,6 +1011,10 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, media_packet_h mediabuf = NULL; media_format_h mediafmt = NULL; int indx = 0; + char *codec_data = NULL; + char *temp_codec_data = NULL; + int index = 0; + track *atrack = demuxer->info.head; if ((demuxer->selected_tracks)[track_indx] == false) { MD_E("Track Not selected\n"); @@ -1062,10 +1112,29 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, goto ERROR; } + /* Create the codec data and pass to _gst_copy_buf_to_media_packet() to add into the media packet */ + temp_codec_data = strstr(atrack->caps_string, "codec_data"); + if (temp_codec_data != NULL) { + while (*temp_codec_data != ')') { + temp_codec_data++; + } + temp_codec_data++; /* to esacpe ')' */ + codec_data = (char*) malloc(sizeof(char)*strlen(temp_codec_data)); + if (codec_data != NULL) { + while (*temp_codec_data != ',') { + codec_data[index++] = *temp_codec_data; + temp_codec_data++; + } + codec_data[index] = '\0'; + } + } + /* Fill the media_packet with proper information */ - ret = _gst_copy_buf_to_media_packet(mediabuf, buffer); + ret = _gst_copy_buf_to_media_packet(mediabuf, buffer, codec_data); gst_sample_unref(sample); *outbuf = mediabuf; + if (codec_data) + free(codec_data); MEDIADEMUXER_FLEAVE(); return ret; diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index 0b3e69b..418bcf9 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -30,6 +30,7 @@ #include #include #include +#include /*----------------------------------------------------------------------- | GLOBAL CONSTANT DEFINITIONS: | @@ -58,6 +59,7 @@ int w; int h; int channel = 0; int samplerate = 0; +int bit = 0; bool is_adts = 0; /*----------------------------------------------------------------------- @@ -122,6 +124,12 @@ int write_amrnb_header = 0; /* write magic number for AMR-NB Header int write_amrwb_header = 0; /* write magic number for AMR-WB Header at one time */ #endif +bool validate_with_codec = false; +mediacodec_h g_media_codec = NULL; +FILE *fp_out_codec_audio = NULL; +mediacodec_h g_media_codec_1 = NULL; +FILE *fp_out_codec_video = NULL; + /*----------------------------------------------------------------------- | HELPER FUNCTION | -----------------------------------------------------------------------*/ @@ -254,14 +262,14 @@ int test_mediademuxer_get_track_info() v_mime, w, h); vid_track = track; } else if (media_format_get_audio_info(g_media_format[track], &a_mime, - &channel, &samplerate, NULL, NULL) == MEDIA_FORMAT_ERROR_NONE) { + &channel, &samplerate, &bit, NULL) == MEDIA_FORMAT_ERROR_NONE) { g_print("media_format_get_audio_info is sucess!\n"); - g_print("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d\n", - a_mime, channel, samplerate); + g_print("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d, bit :%d\n", + a_mime, channel, samplerate, bit); media_format_get_audio_aac_type(g_media_format[track], &is_adts); aud_track = track; } else { - g_print("Not Supported YET"); + g_print("Not Supported YET\n"); } } else { g_print("Error while getting mediademuxer_get_track_info\n"); @@ -294,6 +302,98 @@ int test_mediademuxer_get_track_info() return ret; } +static void mediacodec_finish(mediacodec_h handle, FILE *fp) +{ + int err = 0; + fclose(fp); + mediacodec_unset_output_buffer_available_cb(handle); + err = mediacodec_unprepare(handle); + if (err != MEDIACODEC_ERROR_NONE) { + g_print("mediacodec_unprepare failed error = %d \n", err); + return; + } + err = mediacodec_destroy(handle); + if (err != MEDIACODEC_ERROR_NONE) { + g_print("mediacodec_destory failed error = %d \n", err); + } + return; +} + +static void _mediacodec_fill_audio_buffer_cb(media_packet_h pkt, void *user_data) +{ + int err = 0; + uint64_t buf_size = 0; + void *data = NULL; + media_packet_h output_buf; + + if (pkt != NULL) { + err = mediacodec_get_output(g_media_codec, &output_buf, 0); + if (err == MEDIACODEC_ERROR_NONE) { + media_packet_get_buffer_size(output_buf, &buf_size); + media_packet_get_buffer_data_ptr(output_buf, &data); + if (data != NULL) { + fwrite(data, 1, buf_size, fp_out_codec_audio); + } else { + g_print("Data is null inside _mediacodec_fill_audio_buffer_cb\n"); + } + + media_packet_destroy(output_buf); + } else { + g_print("mediacodec_get_output failed inside _mediacodec_fill_audio_buffer_cb err = %d\n", err); + return; + } + } else { + g_print("audio pkt from mediacodec is null\n"); + } + return; +} + +static void mediacodec_init_audio(int codecid, int flag, int samplerate, int channel, int bit) +{ + /* This file will be used to dump the audio data coming out from mediacodec */ + fp_out_codec_audio = fopen("/opt/usr/media/codec_dump_audio.out", "wb"); + if (g_media_codec != NULL) { + mediacodec_unprepare(g_media_codec); + mediacodec_destroy(g_media_codec); + g_media_codec = NULL; + } + if (mediacodec_create(&g_media_codec) != MEDIACODEC_ERROR_NONE) { + g_print("mediacodec_create is failed\n"); + return; + } + /* Now set the code info */ + if ((mediacodec_set_codec(g_media_codec, (mediacodec_codec_type_e)codecid, + (mediacodec_support_type_e)flag) != MEDIACODEC_ERROR_NONE)) { + g_print("mediacodec_set_codec is failed\n"); + return; + } + /* set the audio dec info */ + if ((mediacodec_set_adec_info(g_media_codec, samplerate, channel, bit))!= MEDIACODEC_ERROR_NONE) { + g_print("mediacodec_set_adec is failed\n"); + return; + } + /* Set the callback for output data, which will be used to write the data to file */ + mediacodec_set_output_buffer_available_cb(g_media_codec, + _mediacodec_fill_audio_buffer_cb, + g_media_codec); + + if (MEDIACODEC_ERROR_NONE != mediacodec_prepare(g_media_codec)) { + g_print("mediacodec prepare is failed\n"); + return; + } +} + +static void mediacodec_process_audio_pkt(media_packet_h in_buf) +{ + if (g_media_codec != NULL) { + /* process the media packet */ + if (MEDIACODEC_ERROR_NONE != mediacodec_process_input (g_media_codec, in_buf, 0)) { + g_print("mediacodec_process_input is failed inside mediacodec_process_audio_pkt\n"); + return; + } + } +} + void *_fetch_audio_data(void *ptr) { int ret = MD_ERROR_NONE; @@ -305,6 +405,18 @@ void *_fetch_audio_data(void *ptr) *status = -1; g_print("Audio Data function\n"); + + if (validate_with_codec) { + int flag = 0; + if (a_mime == MEDIA_FORMAT_AAC_LC || a_mime == MEDIA_FORMAT_AAC_HE || + a_mime == MEDIA_FORMAT_AAC_HE_PS) { + flag = 10; + mediacodec_init_audio(MEDIACODEC_AAC, flag, samplerate, channel, bit); + } else { + g_print("Not Supported YET- Need to add mime for validating with audio codec\n"); + return (void *)status; + } + } while (1) { ret = mediademuxer_read_sample(demuxer, aud_track, &audbuf); if (ret == MD_EOS) { @@ -341,13 +453,115 @@ void *_fetch_audio_data(void *ptr) else g_print("DUMP : write(audio data) fail for NULL\n"); #endif - media_packet_destroy(audbuf); + + if (validate_with_codec) + mediacodec_process_audio_pkt(audbuf); + else + media_packet_destroy(audbuf); } *status = 0; + if (validate_with_codec) + mediacodec_finish(g_media_codec, fp_out_codec_audio); return (void *)status; } +static void _mediacodec_fill_video_buffer_cb(media_packet_h pkt, void *user_data) +{ + int err = 0; + uint64_t buf_size = 0; + void *data = NULL; + media_packet_h output_buf; + + if (pkt != NULL) { + err = mediacodec_get_output(g_media_codec_1, &output_buf, 0); + if (err == MEDIACODEC_ERROR_NONE) { + media_packet_get_buffer_size(output_buf, &buf_size); + //g_print("%s - output_buf size = %lld\n",__func__, buf_size); + media_packet_get_buffer_data_ptr(output_buf, &data); + if (data != NULL) { + fwrite(data, 1, buf_size, fp_out_codec_video); + } else { + g_print("Data is null inside _mediacodec_fill_video_buffer_cb\n"); + } + media_packet_destroy(output_buf); + } else { + g_print("mediacodec_get_output failed inside _mediacodec_fill_video_buffer_cb lerr = %d\n", err); + return; + } + } else { + g_print("video pkt from mediacodec is null\n"); + } + return; +} + +static void mediacodec_init_video(int codecid, int flag, int width, int height) +{ + /* This file will be used to dump the data */ + fp_out_codec_video = fopen("/opt/usr/media/codec_dump_video.out", "wb"); + if (g_media_codec_1 != NULL) { + mediacodec_unprepare(g_media_codec_1); + mediacodec_destroy(g_media_codec_1); + g_media_codec_1 = NULL; + } + if (mediacodec_create(&g_media_codec_1) != MEDIACODEC_ERROR_NONE) { + g_print("mediacodec_create is failed\n"); + return; + } + /* Now set the code info */ + if ((mediacodec_set_codec(g_media_codec_1, (mediacodec_codec_type_e)codecid, + (mediacodec_support_type_e)flag) != MEDIACODEC_ERROR_NONE)) { + g_print("mediacodec_set_codec is failed\n"); + return; + } + /* set the video dec info */ + if ((mediacodec_set_vdec_info(g_media_codec_1, width, height)) != MEDIACODEC_ERROR_NONE) { + g_print("mediacodec_set_vdec is failed\n"); + return; + } + /* Set the callback for output data, which will be used to write the data to file */ + mediacodec_set_output_buffer_available_cb(g_media_codec_1, + _mediacodec_fill_video_buffer_cb, + g_media_codec_1); + + if (MEDIACODEC_ERROR_NONE != mediacodec_prepare(g_media_codec_1)) { + g_print("mediacodec_prepare is failed\n"); + return; + } +} + +static void mediacodec_process_video_pkt(media_packet_h in_buf) +{ + if (g_media_codec_1 != NULL) { + /* process the media packet */ + if (MEDIACODEC_ERROR_NONE != mediacodec_process_input (g_media_codec_1, in_buf, 0)) { + g_print("mediacodec process input is failed inside mediacodec_process_video_pkt\n"); + return; + } + } else { + g_print("mediacodec handle is invalid inside mediacodec_process_video_pkt()\n"); + } +} + +#if 0 +static void _local_media_packet_get_codec_data(media_packet_h pkt) +{ + unsigned char* get_codec_data; + unsigned int get_codec_data_size; + + if (media_packet_get_codec_data(pkt,(void**) &get_codec_data, &get_codec_data_size) == MEDIA_PACKET_ERROR_NONE) { + g_print("media_packet_get_codec_data is sucess ... !\n"); + g_print("codec_data_size = %u\n", get_codec_data_size); + get_codec_data[get_codec_data_size] = '\0'; + if (get_codec_data_size == 0) + return; + g_print("media packet codec_data is [%s] \n", get_codec_data); + } else { + g_print("media_packet_get_codec_data is failed...\n"); + } +} +#endif + void *_fetch_video_data(void *ptr) { int ret = MD_ERROR_NONE; @@ -359,6 +573,18 @@ void *_fetch_video_data(void *ptr) *status = -1; g_print("Video Data function\n"); + + if (validate_with_codec) { + int flag = 0; + if (v_mime == MEDIA_FORMAT_H264_SP || v_mime == MEDIA_FORMAT_H264_MP || + v_mime == MEDIA_FORMAT_H264_HP) { + flag = 10; + mediacodec_init_video(MEDIACODEC_H264, flag, w, h); + } else { + g_print("Not Supported YET- Need to add mime for validating with video codec\n"); + return (void *)status; + } + } while (1) { ret = mediademuxer_read_sample(demuxer, vid_track, &vidbuf); if (ret == MD_EOS) { @@ -372,16 +598,26 @@ void *_fetch_video_data(void *ptr) media_packet_get_buffer_size(vidbuf, &buf_size); media_packet_get_buffer_data_ptr(vidbuf, &data); g_print("Video Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size); - +#if 0 + /* This is used for debugging purpose */ + _local_media_packet_get_codec_data(vidbuf); +#endif #if DEMUXER_OUTPUT_DUMP if (data != NULL) fwrite(data, 1, buf_size, fp_video_out); else g_print("DUMP : write(video data) fail for NULL\n"); #endif - media_packet_destroy(vidbuf); + + if (validate_with_codec) + mediacodec_process_video_pkt(vidbuf); + else + media_packet_destroy(vidbuf); } *status = 0; + if (validate_with_codec) + mediacodec_finish(g_media_codec_1, fp_out_codec_video); + return (void *)status; } @@ -558,6 +794,10 @@ static void display_sub_basic() g_print("d. Destroy \t"); g_print("q. Quit \n"); g_print("---------------------------------------------------------------------------\n"); + if (validate_with_codec) + g_print("[Validation with Media codec]\n"); + else + g_print("[validation as stand alone. To validate with media codec, run mediademuxertest with -c option]\n"); } void _interpret_main_menu(char *cmd) @@ -747,6 +987,11 @@ int main(int argc, char *argv[]) g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL); g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL); + if (argc > 1) { + /* Check whether validation with media codec is required */ + if (argv[1][0] == '-' && argv[1][1] == 'c') + validate_with_codec = true; + } displaymenu(); g_print("RUN main loop\n"); -- 2.7.4 From 96bd4eb02b111751f03f9fa7115722351a9d584e Mon Sep 17 00:00:00 2001 From: Joungkook Seo Date: Wed, 2 Sep 2015 14:41:06 +0900 Subject: [PATCH 6/8] Sync with 2.4 (Updated testsuit to validate MP3 and AMR-NB/WB, M4A format with mediacodec) [1] Fixed issue of Segmentation fault. [2] Fixed issue of wrong path to dump output file. Change-Id: Ie3dcc747efde9839ab19c5b174ae29e848b4a129 Signed-off-by: Joungkook Seo --- src/mediademuxer_port.c | 2 +- src/port_gst/mediademuxer_port_gst.c | 10 +++-- test/mediademuxer_test.c | 87 ++++++++++++++++++++++++------------ 3 files changed, 66 insertions(+), 33 deletions(-) diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index 4bc955c..d0a503c 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -401,12 +401,12 @@ int md_read_sample(MMHandleType demuxer, int track_indx, media_packet_h *outbuf) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->read_sample(md_handle->mdport_handle, outbuf, track_indx); if (result == MD_EOS || result == MD_ERROR_NONE) { + MEDIADEMUXER_FLEAVE(); return result; } else { MD_E("error while reading sample\n"); goto ERROR; } - MEDIADEMUXER_FLEAVE(); ERROR: result = MD_ERROR_INVALID_ARGUMENT; MEDIADEMUXER_FLEAVE(); diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 96944b5..c5c61fb 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -465,7 +465,7 @@ static void __gst_cb_typefind(GstElement *tf, guint probability, type = gst_caps_to_string(caps); if (type) { MD_I("Media type %s found, probability %d%%\n", type, probability); - if (strstr(type, "quicktime")) { + if (strstr(type, "quicktime") || (strstr(type, "audio/x-m4a"))) { gst_handle->is_valid_container = true; gst_handle->demux = gst_element_factory_make("qtdemux", NULL); if (!gst_handle->demux) { @@ -836,6 +836,8 @@ int _set_mime_audio(media_format_h format, track *head) goto ERROR; if(rate == 0) rate = 44100; /* default */ + if(bit == 0) + bit = 16; /* default */ if (media_format_set_audio_samplerate(format, rate)) goto ERROR; if (media_format_set_audio_bit(format, bit)) @@ -863,11 +865,13 @@ int _set_mime_audio(media_format_h format, track *head) goto ERROR; if(channels == 0) channels = 1; /* default */ + if(bit == 0) + bit = 16; /* default */ if (media_format_set_audio_channel(format, channels)) goto ERROR; if (media_format_set_audio_samplerate(format, rate)) goto ERROR; - if (media_format_set_audio_bit(format, 0)) + if (media_format_set_audio_bit(format, bit)) goto ERROR; } else { @@ -1094,7 +1098,7 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, GstElement *sink = atrack->appsink; GstSample *sample = NULL; if (gst_app_sink_is_eos((GstAppSink *) sink)) { - MD_W("End of stream reached\n"); + MD_W("End of stream (EOS) reached\n"); ret = MD_EOS; goto ERROR; } diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index 418bcf9..485056a 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -112,6 +112,7 @@ bool is_adts = 0; #if DEMUXER_OUTPUT_DUMP FILE *fp_audio_out = NULL; FILE *fp_video_out = NULL; +bool validate_dump = false; #define ADTS_HEADER_SIZE 7 unsigned char buf_adts[ADTS_HEADER_SIZE]; @@ -193,8 +194,13 @@ int test_mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) g_print("test_mediademuxer_set_data_source\n"); #if DEMUXER_OUTPUT_DUMP - fp_audio_out = fopen("/opt/usr/media/dump_audio.out", "wb"); - fp_video_out = fopen("/opt/usr/media/dump_video.out", "wb"); + fp_audio_out = fopen("/opt/usr/dump_audio.out", "wb"); + if (fp_audio_out != NULL) { + validate_dump = true; + fp_video_out = fopen("/opt/usr/dump_video.out", "wb"); + } else { + g_print("Error - Cannot open file for file dump, Please chek root\n"); + } #endif ret = mediademuxer_set_data_source(demuxer, path); @@ -350,14 +356,16 @@ static void _mediacodec_fill_audio_buffer_cb(media_packet_h pkt, void *user_data static void mediacodec_init_audio(int codecid, int flag, int samplerate, int channel, int bit) { - /* This file will be used to dump the audio data coming out from mediacodec */ - fp_out_codec_audio = fopen("/opt/usr/media/codec_dump_audio.out", "wb"); + /* This file will be used to dump the audio data coming out from mediacodec */ + fp_out_codec_audio = fopen("/opt/usr/codec_dump_audio.out", "wb"); + g_print("Create dumped file as codec_dump_audio.out\n"); + if (g_media_codec != NULL) { mediacodec_unprepare(g_media_codec); mediacodec_destroy(g_media_codec); g_media_codec = NULL; } - if (mediacodec_create(&g_media_codec) != MEDIACODEC_ERROR_NONE) { + if (mediacodec_create(&g_media_codec) != MEDIACODEC_ERROR_NONE) { g_print("mediacodec_create is failed\n"); return; } @@ -411,12 +419,26 @@ void *_fetch_audio_data(void *ptr) if (a_mime == MEDIA_FORMAT_AAC_LC || a_mime == MEDIA_FORMAT_AAC_HE || a_mime == MEDIA_FORMAT_AAC_HE_PS) { flag = 10; + g_print("mediacodec_init_audio() for MEDIACODEC_AAC\n"); mediacodec_init_audio(MEDIACODEC_AAC, flag, samplerate, channel, bit); + } else if (a_mime == MEDIA_FORMAT_MP3) { + flag = 10; + g_print("mediacodec_init_audio() for MEDIACODEC_MP3\n"); + mediacodec_init_audio(MEDIACODEC_MP3, flag, samplerate, channel, bit); + } else if (a_mime == MEDIA_FORMAT_AMR_NB) { + flag = 10; + g_print("mediacodec_init_audio() for MEDIACODEC_AMR_NB\n"); + mediacodec_init_audio(MEDIACODEC_AMR_NB, flag, samplerate, channel, bit); + } else if (a_mime == MEDIA_FORMAT_AMR_WB) { + flag = 10; + g_print("mediacodec_init_audio() for MEDIACODEC_AMR_WB\n"); + mediacodec_init_audio(MEDIACODEC_AMR_WB, flag, samplerate, channel, bit); } else { g_print("Not Supported YET- Need to add mime for validating with audio codec\n"); return (void *)status; } } + while (1) { ret = mediademuxer_read_sample(demuxer, aud_track, &audbuf); if (ret == MD_EOS) { @@ -432,26 +454,28 @@ void *_fetch_audio_data(void *ptr) g_print("Audio Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size); #if DEMUXER_OUTPUT_DUMP - if ((a_mime == MEDIA_FORMAT_AAC_LC) && (is_adts == 0)) { - /* This is used only AAC raw case for adding each ADTS frame header */ - generate_header_aac_adts(buf_adts, (buf_size+ADTS_HEADER_SIZE)); - fwrite(&buf_adts[0], 1, ADTS_HEADER_SIZE, fp_audio_out); - } else if ((a_mime == MEDIA_FORMAT_AMR_NB) && (write_amrnb_header == 1)) { - /* This is used only AMR-NB case for adding magic header in only first frame */ - g_print("%s - AMRNB_HDR write in first frame\n",__func__); - fwrite(&AMRNB_HDR[0], 1, sizeof(AMRNB_HDR) - 1, fp_audio_out); - write_amrnb_header = 0; - } else if ((a_mime == MEDIA_FORMAT_AMR_WB) && (write_amrwb_header == 1)) { - /* This is used only AMR-WB case for adding magic header in only first frame */ - g_print("%s - AMRWB_HDR write in first frame\n",__func__); - fwrite(&AMRWB_HDR[0], 1, sizeof(AMRWB_HDR) - 1, fp_audio_out); - write_amrwb_header = 0; - } + if (validate_dump) { + if ((a_mime == MEDIA_FORMAT_AAC_LC) && (is_adts == 0)) { + /* This is used only AAC raw case for adding each ADTS frame header */ + generate_header_aac_adts(buf_adts, (buf_size+ADTS_HEADER_SIZE)); + fwrite(&buf_adts[0], 1, ADTS_HEADER_SIZE, fp_audio_out); + } else if ((a_mime == MEDIA_FORMAT_AMR_NB) && (write_amrnb_header == 1)) { + /* This is used only AMR-NB case for adding magic header in only first frame */ + g_print("%s - AMRNB_HDR write in first frame\n",__func__); + fwrite(&AMRNB_HDR[0], 1, sizeof(AMRNB_HDR) - 1, fp_audio_out); + write_amrnb_header = 0; + } else if ((a_mime == MEDIA_FORMAT_AMR_WB) && (write_amrwb_header == 1)) { + /* This is used only AMR-WB case for adding magic header in only first frame */ + g_print("%s - AMRWB_HDR write in first frame\n",__func__); + fwrite(&AMRWB_HDR[0], 1, sizeof(AMRWB_HDR) - 1, fp_audio_out); + write_amrwb_header = 0; + } - if (data != NULL) - fwrite(data, 1, buf_size, fp_audio_out); - else - g_print("DUMP : write(audio data) fail for NULL\n"); + if (data != NULL) + fwrite(data, 1, buf_size, fp_audio_out); + else + g_print("DUMP : write(audio data) fail for NULL\n"); + } #endif if (validate_with_codec) @@ -498,7 +522,9 @@ static void _mediacodec_fill_video_buffer_cb(media_packet_h pkt, void *user_data static void mediacodec_init_video(int codecid, int flag, int width, int height) { /* This file will be used to dump the data */ - fp_out_codec_video = fopen("/opt/usr/media/codec_dump_video.out", "wb"); + fp_out_codec_video = fopen("/opt/usr/codec_dump_video.out", "wb"); + g_print("Create dumped file as codec_dump_video.out\n"); + if (g_media_codec_1 != NULL) { mediacodec_unprepare(g_media_codec_1); mediacodec_destroy(g_media_codec_1); @@ -579,6 +605,7 @@ void *_fetch_video_data(void *ptr) if (v_mime == MEDIA_FORMAT_H264_SP || v_mime == MEDIA_FORMAT_H264_MP || v_mime == MEDIA_FORMAT_H264_HP) { flag = 10; + g_print("mediacodec_init_audio() for MEDIACODEC_H264\n"); mediacodec_init_video(MEDIACODEC_H264, flag, w, h); } else { g_print("Not Supported YET- Need to add mime for validating with video codec\n"); @@ -603,10 +630,12 @@ void *_fetch_video_data(void *ptr) _local_media_packet_get_codec_data(vidbuf); #endif #if DEMUXER_OUTPUT_DUMP - if (data != NULL) - fwrite(data, 1, buf_size, fp_video_out); - else - g_print("DUMP : write(video data) fail for NULL\n"); + if (validate_dump) { + if (data != NULL) + fwrite(data, 1, buf_size, fp_video_out); + else + g_print("DUMP : write(video data) fail for NULL\n"); + } #endif if (validate_with_codec) -- 2.7.4 From c768420dbe391271b7be47f150ff9ec977c1927e Mon Sep 17 00:00:00 2001 From: Deepak Srivastava Date: Tue, 22 Sep 2015 14:45:07 +0530 Subject: [PATCH 7/8] Sync with 2.4 (Added demuxer support for 3gp(h263 and amr codec) file) Change-Id: I70d11cb3a693861de877b4e0b3ea048523de2d9d Signed-off-by: Deepak Srivastava --- src/port_gst/mediademuxer_port_gst.c | 46 +++++++++++++++++++++++++++++++++--- test/mediademuxer_test.c | 6 ++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index c5c61fb..a2c235d 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -465,7 +465,7 @@ static void __gst_cb_typefind(GstElement *tf, guint probability, type = gst_caps_to_string(caps); if (type) { MD_I("Media type %s found, probability %d%%\n", type, probability); - if (strstr(type, "quicktime") || (strstr(type, "audio/x-m4a"))) { + if (strstr(type, "quicktime") || (strstr(type, "audio/x-m4a")) || strstr(type, "x-3gp")) { gst_handle->is_valid_container = true; gst_handle->demux = gst_element_factory_make("qtdemux", NULL); if (!gst_handle->demux) { @@ -761,6 +761,15 @@ int _set_mime_video(media_format_h format, track *head) if (media_format_set_video_height(format, src_height)) goto ERROR; } + } else if (gst_structure_has_name(struc, "video/x-h263")) { + gst_structure_get_int(struc, "width", &src_width); + gst_structure_get_int(struc, "height", &src_height); + if (media_format_set_video_mime(format, MEDIA_FORMAT_H263)) + goto ERROR; + if (media_format_set_video_width(format, src_width)) + goto ERROR; + if (media_format_set_video_height(format, src_height)) + goto ERROR; } else { MD_I("Video mime not supported so far\n"); goto ERROR; @@ -873,8 +882,39 @@ int _set_mime_audio(media_format_h format, track *head) goto ERROR; if (media_format_set_audio_bit(format, bit)) goto ERROR; - } - else { + } else if (gst_structure_has_name(struc, "audio/AMR")) { + gst_structure_get_int(struc, "channels", &channels); + gst_structure_get_int(struc, "rate", &rate); + gst_structure_get_int(struc, "bit", &bit); + if (media_format_set_audio_mime(format, MEDIA_FORMAT_AMR_NB)) + goto ERROR; + if(channels == 0) + channels = 1; /* default */ + if (media_format_set_audio_channel(format, channels)) + goto ERROR; + if (media_format_set_audio_samplerate(format, rate)) + goto ERROR; + if (bit == 0) + bit = 16; /* default */ + if (media_format_set_audio_bit(format, bit)) + goto ERROR; + } else if (gst_structure_has_name(struc, "audio/AMR-WB")) { + gst_structure_get_int(struc, "channels", &channels); + gst_structure_get_int(struc, "rate", &rate); + gst_structure_get_int(struc, "bit", &bit); + if (media_format_set_audio_mime(format, MEDIA_FORMAT_AMR_WB)) + goto ERROR; + if(channels == 0) + channels = 1; /* default */ + if (media_format_set_audio_channel(format, channels)) + goto ERROR; + if (media_format_set_audio_samplerate(format, rate)) + goto ERROR; + if (bit == 0) + bit = 16; /* default */ + if (media_format_set_audio_bit(format, bit)) + goto ERROR; + } else { MD_I("Audio mime not supported so far\n"); goto ERROR; } diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index 485056a..f460329 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -605,8 +605,12 @@ void *_fetch_video_data(void *ptr) if (v_mime == MEDIA_FORMAT_H264_SP || v_mime == MEDIA_FORMAT_H264_MP || v_mime == MEDIA_FORMAT_H264_HP) { flag = 10; - g_print("mediacodec_init_audio() for MEDIACODEC_H264\n"); + g_print("mediacodec_init_video() for MEDIACODEC_H264\n"); mediacodec_init_video(MEDIACODEC_H264, flag, w, h); + } else if (v_mime == MEDIA_FORMAT_H263) { + g_print("mediacodec_init_video() for MEDIACODEC_H263\n"); + flag = 10; + mediacodec_init_video(MEDIACODEC_H263, flag, w, h); } else { g_print("Not Supported YET- Need to add mime for validating with video codec\n"); return (void *)status; -- 2.7.4 From 45b6c8ac5c57581b7bc750e6f87da29273d70efd Mon Sep 17 00:00:00 2001 From: Deepak Srivastava Date: Wed, 4 Nov 2015 12:18:40 +0530 Subject: [PATCH 8/8] Applied coding rule. Change-Id: Ie9a31e5eb62c6c0a7e044d015056aa54fe704209 Signed-off-by: Deepak Srivastava --- doc/mediademuxer_doc.h | 10 +- include/mediademuxer.h | 39 ++--- include/mediademuxer_error.h | 67 ++++---- include/mediademuxer_ini.h | 2 +- include/mediademuxer_port.h | 3 +- include/mediademuxer_private.h | 34 ++-- include/mediademuxer_util.h | 42 +++-- include/port_custom/mediademuxer_port_custom.h | 4 +- include/port_ffmpeg/mediademuxer_port_ffmpeg.h | 4 +- include/port_gst/mediademuxer_port_gst.h | 30 ++-- src/mediademuxer.c | 71 ++++---- src/mediademuxer_ini.c | 101 +++++------ src/mediademuxer_port.c | 48 +++--- src/port_custom/mediademuxer_port_custom.c | 13 +- src/port_ffmpeg/mediademuxer_port_ffmpeg.c | 12 +- src/port_gst/mediademuxer_port_gst.c | 224 ++++++++++++------------ test/mediademuxer_test.c | 229 ++++++++++++------------- 17 files changed, 429 insertions(+), 504 deletions(-) diff --git a/doc/mediademuxer_doc.h b/doc/mediademuxer_doc.h index 4e3c55f..6f2f63f 100644 --- a/doc/mediademuxer_doc.h +++ b/doc/mediademuxer_doc.h @@ -56,14 +56,14 @@ * while(EOS) { * if(track1 is set) { * mediademuxer_read_sample(); - * if(seek_request) + * if(seek_request) * mediademuxer_seek(); - * } + * } * else if(track2 is set) { * mediademuxer_read_sample(); - * } - * if(track2_not_needed) - * mediademuxer_unselect_track(track2); + * } + * if(track2_not_needed) + * mediademuxer_unselect_track(track2); * } * * mediademuxer_stop()
diff --git a/include/mediademuxer.h b/include/mediademuxer.h index 2c6eb80..f43515f 100644 --- a/include/mediademuxer.h +++ b/include/mediademuxer.h @@ -24,7 +24,7 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ #ifndef TIZEN_ERROR_MEDIA_DEMUXER #define TIZEN_ERROR_MEDIA_DEMUXER -0x04000000 @@ -54,7 +54,7 @@ typedef enum { MEDIADEMUXER_NONE, /**< The mediademuxer is not created */ MEDIADEMUXER_IDLE, /**< The mediademuxer is created, but not prepared */ MEDIADEMUXER_READY, /**< The mediademuxer is ready to demux media */ - MEDIADEMUXER_DEMUXING /**< The mediademuxer is demuxing media */ + MEDIADEMUXER_DEMUXING /**< The mediademuxer is demuxing media */ } mediademuxer_state; /** @@ -62,17 +62,17 @@ typedef enum { * @since_tizen 3.0 */ typedef enum { - MEDIADEMUXER_ERROR_NONE = TIZEN_ERROR_NONE, /*< Successful */ - MEDIADEMUXER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - MEDIADEMUXER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - MEDIADEMUXER_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ - MEDIADEMUXER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ - MEDIADEMUXER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ - MEDIADEMUXER_ERROR_INVALID_STATE = TIZEN_ERROR_MEDIA_DEMUXER | 0x01, /**< Invalid state */ - MEDIADEMUXER_ERROR_INVALID_PATH = TIZEN_ERROR_MEDIA_DEMUXER | 0x02, /**< Invalid path */ - MEDIADEMUXER_ERROR_RESOURCE_LIMIT = TIZEN_ERROR_MEDIA_DEMUXER | 0x03, /**< Resource limit */ - MEDIADEMUXER_ERROR_SEEK_FAILED = TIZEN_ERROR_MEDIA_DEMUXER | 0x04, /**< Seek operation failure */ - MEDIADEMUXER_ERROR_DRM_NOT_PERMITTED = TIZEN_ERROR_MEDIA_DEMUXER | 0x05 /**< Not permitted format */ + MEDIADEMUXER_ERROR_NONE = TIZEN_ERROR_NONE, /*< Successful */ + MEDIADEMUXER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + MEDIADEMUXER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + MEDIADEMUXER_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ + MEDIADEMUXER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ + MEDIADEMUXER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + MEDIADEMUXER_ERROR_INVALID_STATE = TIZEN_ERROR_MEDIA_DEMUXER | 0x01, /**< Invalid state */ + MEDIADEMUXER_ERROR_INVALID_PATH = TIZEN_ERROR_MEDIA_DEMUXER | 0x02, /**< Invalid path */ + MEDIADEMUXER_ERROR_RESOURCE_LIMIT = TIZEN_ERROR_MEDIA_DEMUXER | 0x03, /**< Resource limit */ + MEDIADEMUXER_ERROR_SEEK_FAILED = TIZEN_ERROR_MEDIA_DEMUXER | 0x04, /**< Seek operation failure */ + MEDIADEMUXER_ERROR_DRM_NOT_PERMITTED = TIZEN_ERROR_MEDIA_DEMUXER | 0x05 /**< Not permitted format */ } mediademuxer_error_e; /** @@ -93,7 +93,7 @@ typedef enum { * @see mediademuxer_set_error_cb() * @see mediademuxer_unset_error_cb() */ -typedef void (*mediademuxer_error_cb)(mediademuxer_error_e error, void *user_data); +typedef void (*mediademuxer_error_cb) (mediademuxer_error_e error, void *user_data); /** * @brief Creates a media demuxer handle for demuxing. @@ -207,8 +207,7 @@ int mediademuxer_start(mediademuxer_h demuxer); * @see media_format_unref() * @see #media_format_h * */ -int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, - media_format_h *format); +int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, media_format_h *format); /** * @brief Reads a frame(sample) of one single track. @@ -232,8 +231,7 @@ int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, * @see media_packet_destroy() * @see #media_packet_h * */ -int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index, - media_packet_h *outbuf); +int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index, media_packet_h *outbuf); /** * @brief Seeks to a particular instance of time (in micro seconds). @@ -348,8 +346,7 @@ int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state); * @see mediademuxer_unset_error_cb() * @see mediademuxer_error_cb() * */ -int mediademuxer_set_error_cb(mediademuxer_h demuxer, - mediademuxer_error_cb callback, void *user_data); +int mediademuxer_set_error_cb(mediademuxer_h demuxer, mediademuxer_error_cb callback, void *user_data); /** * @brief Unregisters the error callback function. @@ -369,4 +366,4 @@ int mediademuxer_unset_error_cb(mediademuxer_h demuxer); #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIADEMUXER_H__ */ +#endif /* __TIZEN_MEDIADEMUXER_H__ */ diff --git a/include/mediademuxer_error.h b/include/mediademuxer_error.h index 413f448..86a46da 100755 --- a/include/mediademuxer_error.h +++ b/include/mediademuxer_error.h @@ -20,68 +20,67 @@ #ifdef __cplusplus extern "C" { #endif - typedef enum { MD_ERROR_NONE = 0, - MD_ERROR = -1, /**< codec happens error */ - MD_MEMORY_ERROR = -2, /**< codec memory is not enough */ - MD_PARAM_ERROR = -3, /**< codec parameter is error */ - MD_INVALID_ARG = -4, /** < codec has invalid arguments */ + MD_ERROR = -1, /**< codec happens error */ + MD_MEMORY_ERROR = -2, /**< codec memory is not enough */ + MD_PARAM_ERROR = -3, /**< codec parameter is error */ + MD_INVALID_ARG = -4, /** < codec has invalid arguments */ MD_PERMISSION_DENIED = -5, - MD_INVALID_STATUS = -6, /**< codec works at invalid status */ - MD_NOT_SUPPORTED = -7, /**< codec can't support this specific video format */ + MD_INVALID_STATUS = -6, /**< codec works at invalid status */ + MD_NOT_SUPPORTED = -7, /**< codec can't support this specific video format */ MD_INVALID_IN_BUF = -8, MD_INVALID_OUT_BUF = -9, MD_INTERNAL_ERROR = -10, - MD_HW_ERROR = -11, /**< codec happens hardware error */ + MD_HW_ERROR = -11, /**< codec happens hardware error */ MD_NOT_INITIALIZED = -12, MD_INVALID_STREAM = -13, MD_OUTPUT_BUFFER_EMPTY = -14, - MD_OUTPUT_BUFFER_OVERFLOW = -15, /**< codec output buffer is overflow */ - MD_MEMORY_ALLOCED = -16, /**< codec has got memory and can decode one frame */ - MD_COURRPTED_INI = -17, /**< value in the ini file is not valid */ + MD_OUTPUT_BUFFER_OVERFLOW = -15, /**< codec output buffer is overflow */ + MD_MEMORY_ALLOCED = -16, /**< codec has got memory and can decode one frame */ + MD_COURRPTED_INI = -17, /**< value in the ini file is not valid */ MD_ERROR_FILE_NOT_FOUND = -18, - MD_EOS, /** read sample reached end of stream */ + MD_EOS, /** read sample reached end of stream */ } md_ret_e; -#define MD_ERROR_CLASS 0x80000000 /**< Definition of number describing error group */ -#define MD_ERROR_COMMON_CLASS 0x80000100 /**< Category for describing common error group */ -#define MD_ERROR_GST_PORT_CLASS 0x80000200 /**< Category for describing gst_port error group */ -#define MD_ERROR_FFMPEG_PORT_CLASS 0x80000300 /**< Category for describing ffmpeg port error group */ +#define MD_ERROR_CLASS 0x80000000 /**< Definition of number describing error group */ +#define MD_ERROR_COMMON_CLASS 0x80000100 /**< Category for describing common error group */ +#define MD_ERROR_GST_PORT_CLASS 0x80000200 /**< Category for describing gst_port error group */ +#define MD_ERROR_FFMPEG_PORT_CLASS 0x80000300 /**< Category for describing ffmpeg port error group */ #define MD_ERROR_CUSTOM_PORT_CLASS 0x80000400 /**< Category for describing custom error group */ /* MD_ERROR_CLASS */ #define MD_ERROR_UNKNOWN (MD_ERROR_CLASS | 0x00) /**< Unclassified error */ -#define MD_ERROR_INVALID_ARGUMENT (MD_ERROR_CLASS | 0x01) /**< Invalid argument */ -#define MD_ERROR_OUT_OF_MEMORY (MD_ERROR_CLASS | 0x02) /**< Out of memory */ -#define MD_ERROR_OUT_OF_STORAGE (MD_ERROR_CLASS | 0x03) /**< Out of storage */ -#define MD_ERROR_INVALID_HANDLE (MD_ERROR_CLASS | 0x04) /**< Invalid handle */ -#define MD_ERROR_FILE_NOT_FOUND (MD_ERROR_CLASS | 0x05) /**< Cannot find file */ +#define MD_ERROR_INVALID_ARGUMENT (MD_ERROR_CLASS | 0x01) /**< Invalid argument */ +#define MD_ERROR_OUT_OF_MEMORY (MD_ERROR_CLASS | 0x02) /**< Out of memory */ +#define MD_ERROR_OUT_OF_STORAGE (MD_ERROR_CLASS | 0x03) /**< Out of storage */ +#define MD_ERROR_INVALID_HANDLE (MD_ERROR_CLASS | 0x04) /**< Invalid handle */ +#define MD_ERROR_FILE_NOT_FOUND (MD_ERROR_CLASS | 0x05) /**< Cannot find file */ #define MD_ERROR_FILE_READ (MD_ERROR_CLASS | 0x06) /**< Fail to read data from file */ #define MD_ERROR_FILE_WRITE (MD_ERROR_CLASS | 0x07) /**< Fail to write data to file */ #define MD_ERROR_END_OF_FILE (MD_ERROR_CLASS | 0x08) /**< End of file */ -#define MD_ERROR_NOT_SUPPORT_API (MD_ERROR_CLASS | 0x09) /**< Not supported API*/ -#define MD_ERROR_PORT_REG_FAILED (MD_ERROR_CLASS | 0x0a) /**< port regitstration failed error */ +#define MD_ERROR_NOT_SUPPORT_API (MD_ERROR_CLASS | 0x09) /**< Not supported API */ +#define MD_ERROR_PORT_REG_FAILED (MD_ERROR_CLASS | 0x0a) /**< port regitstration failed error */ /* MD_ERROR_COMMON_CLASS */ -#define MD_ERROR_COMMON_INVALID_ARGUMENT (MD_ERROR_COMMON_CLASS | 1) /**< Invalid argument */ -#define MD_ERROR_COMMON_NO_FREE_SPACE (MD_ERROR_COMMON_CLASS | 2) /**< Out of storage */ -#define MD_ERROR_COMMON_OUT_OF_MEMORY (MD_ERROR_COMMON_CLASS | 3) /**< Out of memory */ -#define MD_ERROR_COMMON_UNKNOWN (MD_ERROR_COMMON_CLASS | 4) /**< Unknown error */ -#define MD_ERROR_COMMON_INVALID_ATTRTYPE (MD_ERROR_COMMON_CLASS | 5) /**< Invalid argument */ -#define MD_ERROR_COMMON_INVALID_PERMISSION (MD_ERROR_COMMON_CLASS | 6) /**< Invalid permission */ -#define MD_ERROR_COMMON_OUT_OF_ARRAY (MD_ERROR_COMMON_CLASS | 7) /**< Out of array */ -#define MD_ERROR_COMMON_OUT_OF_RANGE (MD_ERROR_COMMON_CLASS | 8) /**< Out of value range*/ -#define MD_ERROR_COMMON_ATTR_NOT_EXIST (MD_ERROR_COMMON_CLASS | 9) /**< Attribute doesn't exist. */ +#define MD_ERROR_COMMON_INVALID_ARGUMENT (MD_ERROR_COMMON_CLASS | 1) /**< Invalid argument */ +#define MD_ERROR_COMMON_NO_FREE_SPACE (MD_ERROR_COMMON_CLASS | 2) /**< Out of storage */ +#define MD_ERROR_COMMON_OUT_OF_MEMORY (MD_ERROR_COMMON_CLASS | 3) /**< Out of memory */ +#define MD_ERROR_COMMON_UNKNOWN (MD_ERROR_COMMON_CLASS | 4) /**< Unknown error */ +#define MD_ERROR_COMMON_INVALID_ATTRTYPE (MD_ERROR_COMMON_CLASS | 5) /**< Invalid argument */ +#define MD_ERROR_COMMON_INVALID_PERMISSION (MD_ERROR_COMMON_CLASS | 6) /**< Invalid permission */ +#define MD_ERROR_COMMON_OUT_OF_ARRAY (MD_ERROR_COMMON_CLASS | 7) /**< Out of array */ +#define MD_ERROR_COMMON_OUT_OF_RANGE (MD_ERROR_COMMON_CLASS | 8) /**< Out of value range*/ +#define MD_ERROR_COMMON_ATTR_NOT_EXIST (MD_ERROR_COMMON_CLASS | 9) /**< Attribute doesn't exist. */ /* * MD_ERROR_GST_PORT_CLASS */ -#define MD_ERROR_GST_PORT_NOT_INITIALIZED (MD_ERROR_GST_PORT_CLASS | 0x01) /**< GST Port instance is not initialized */ +#define MD_ERROR_GST_PORT_NOT_INITIALIZED (MD_ERROR_GST_PORT_CLASS | 0x01) /**< GST Port instance is not initialized */ /* MD_ERROR_FFMPEG_PORT_CLASS @@ -100,4 +99,4 @@ typedef enum { #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIADEMUXER_ERROR_H__ */ +#endif /* __TIZEN_MEDIADEMUXER_ERROR_H__ */ diff --git a/include/mediademuxer_ini.h b/include/mediademuxer_ini.h index e563c08..a8bb3bd 100755 --- a/include/mediademuxer_ini.h +++ b/include/mediademuxer_ini.h @@ -87,4 +87,4 @@ int md_ini_load(md_ini_t *ini); #ifdef __cplusplus } #endif -#endif /*__TIZEN_MEDIADEMUXER_INI_H__*/ +#endif /* __TIZEN_MEDIADEMUXER_INI_H__ */ diff --git a/include/mediademuxer_port.h b/include/mediademuxer_port.h index 86f1552..9b53291 100755 --- a/include/mediademuxer_port.h +++ b/include/mediademuxer_port.h @@ -503,7 +503,6 @@ int md_read_sample(MMHandleType demuxer, int track_indx, media_packet_h *outbuf) */ int md_stop(MMHandleType demuxer); - /** * This function destroy the pipeline * @@ -561,4 +560,4 @@ int md_set_error_cb(MMHandleType demuxer, md_error_cb callback, void *user_data) #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIADEMUXER_PORT_H__ */ +#endif /* __TIZEN_MEDIADEMUXER_PORT_H__ */ diff --git a/include/mediademuxer_private.h b/include/mediademuxer_private.h index a6beedf..9a70511 100755 --- a/include/mediademuxer_private.h +++ b/include/mediademuxer_private.h @@ -35,18 +35,18 @@ extern "C" { #endif #define LOG_TAG "TIZEN_N_MEDIADEMUXER" -#define DEMUXER_CHECK_CONDITION(condition,error,msg) \ - if(condition) {} else \ - { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \ +#define DEMUXER_CHECK_CONDITION(condition, error, msg) \ + if (condition) {} else \ + { LOGE("[%s] %s(0x%08x)", __FUNCTION__, msg, error); return error; }; \ #define DEMUXER_INSTANCE_CHECK(demuxer) \ - DEMUXER_CHECK_CONDITION(demuxer != NULL, MEDIADEMUXER_ERROR_INVALID_PARAMETER,"DEMUXER_ERROR_INVALID_PARAMETER") + DEMUXER_CHECK_CONDITION(demuxer != NULL, MEDIADEMUXER_ERROR_INVALID_PARAMETER, "DEMUXER_ERROR_INVALID_PARAMETER") -#define DEMUXER_STATE_CHECK(demuxer,expected_state) \ - DEMUXER_CHECK_CONDITION(demuxer->state == expected_state,MEDIADEMUXER_ERROR_INVALID_STATE,"DEMUXER_ERROR_INVALID_STATE") +#define DEMUXER_STATE_CHECK(demuxer, expected_state) \ + DEMUXER_CHECK_CONDITION(demuxer->state == expected_state, MEDIADEMUXER_ERROR_INVALID_STATE, "DEMUXER_ERROR_INVALID_STATE") #define DEMUXER_NULL_ARG_CHECK(arg) \ - DEMUXER_CHECK_CONDITION(arg != NULL,MEDIADEMUXER_ERROR_INVALID_PARAMETER,"DEMUXER_ERROR_INVALID_PARAMETER") + DEMUXER_CHECK_CONDITION(arg != NULL, MEDIADEMUXER_ERROR_INVALID_PARAMETER, "DEMUXER_ERROR_INVALID_PARAMETER") /** * @brief Enumeration for media demuxer source type @@ -54,14 +54,14 @@ extern "C" { */ typedef enum { MEDIADEMUXER_SRC_NONE = 0, /**< Not defined src type */ - MEDIADEMUXER_SRC_FILE, /**< Local file src type */ - MEDIADEMUXER_SRC_RTP, /**< Rtp src type */ - MEDIADEMUXER_SRC_WFD, /**< Wfd src type */ - MEDIADEMUXER_SRC_HTTP, /**< Http src type */ - MEDIADEMUXER_SRC_SS, /**< Smooth streaming src type */ - MEDIADEMUXER_SRC_RTSP, /**< Rtsp src type */ - MEDIADEMUXER_SRC_UNKNOWN, /**< Unknown src type */ - MEDIADEMUXER_SRC_INVALID /**< Invalid src type */ + MEDIADEMUXER_SRC_FILE, /**< Local file src type */ + MEDIADEMUXER_SRC_RTP, /**< Rtp src type */ + MEDIADEMUXER_SRC_WFD, /**< Wfd src type */ + MEDIADEMUXER_SRC_HTTP, /**< Http src type */ + MEDIADEMUXER_SRC_SS, /**< Smooth streaming src type */ + MEDIADEMUXER_SRC_RTSP, /**< Rtsp src type */ + MEDIADEMUXER_SRC_UNKNOWN, /**< Unknown src type */ + MEDIADEMUXER_SRC_INVALID /**< Invalid src type */ } mediademuxer_src_type; typedef struct _mediademuxer_s { @@ -80,7 +80,7 @@ typedef struct { /* initialize values */ md_ini_t ini; /* port specific handle */ - /*Source information */ + /* Source information */ char *uri_src; mediademuxer_src_type uri_src_media_type; MMHandleType mdport_handle; @@ -91,4 +91,4 @@ int __convert_error_code(int code, char *func_name); #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIADEMUXER_PRIVATE_H__ */ +#endif /* __TIZEN_MEDIADEMUXER_PRIVATE_H__ */ diff --git a/include/mediademuxer_util.h b/include/mediademuxer_util.h index ed99709..5cfa0e8 100755 --- a/include/mediademuxer_util.h +++ b/include/mediademuxer_util.h @@ -34,13 +34,13 @@ extern "C" { #endif -//#define PRINT_ON_CONSOLE +/* #define PRINT_ON_CONSOLE */ #ifdef PRINT_ON_CONSOLE #include #include #define PRINT_F g_print -#define MD_FENTER(); PRINT_F("function:[%s] ENTER\n",__func__); -#define MD_FLEAVE(); PRINT_F("function [%s] LEAVE\n",__func__); +#define MD_FENTER(); PRINT_F("function:[%s] ENTER\n", __func__); +#define MD_FLEAVE(); PRINT_F("function [%s] LEAVE\n", __func__); #define MD_C PRINT_F #define MD_E PRINT_F #define MD_W PRINT_F @@ -51,21 +51,21 @@ extern "C" { #else #include #include -#define MD_FENTER(); LOGI("function:[%s] ENTER\n",__func__); -#define MD_FLEAVE(); LOGI("function [%s] LEAVE\n",__func__); -#define MD_C LOGE /*MMF_DEBUG_LEVEL_0 */ -#define MD_E LOGE /*MMF_DEBUG_LEVEL_1 */ -#define MD_W LOGW /*MMF_DEBUG_LEVEL_2 */ -#define MD_I LOGI /*MMF_DEBUG_LEVEL_3 */ -#define MD_L LOGI /*MMF_DEBUG_LEVEL_4 */ -#define MD_V LOGV /*MMF_DEBUG_LEVEL_5 */ -#define MD_F LOGF /*MMF_DEBUG_LEVEL_6 - indicate that something in the executed code path is not fully implemented or handled yet */ +#define MD_FENTER(); LOGI("function:[%s] ENTER\n", __func__); +#define MD_FLEAVE(); LOGI("function [%s] LEAVE\n", __func__); +#define MD_C LOGE /* MMF_DEBUG_LEVEL_0 */ +#define MD_E LOGE /* MMF_DEBUG_LEVEL_1 */ +#define MD_W LOGW /* MMF_DEBUG_LEVEL_2 */ +#define MD_I LOGI /* MMF_DEBUG_LEVEL_3 */ +#define MD_L LOGI /* MMF_DEBUG_LEVEL_4 */ +#define MD_V LOGV /* MMF_DEBUG_LEVEL_5 */ +#define MD_F LOGF /* MMF_DEBUG_LEVEL_6 - indicate that something in the executed code path is not fully implemented or handled yet */ #endif /* general */ #define MEDIADEMUXER_FREEIF(x) \ - if ( x ) \ - g_free( x ); \ + if (x) \ + g_free(x); \ x = NULL; #if 1 @@ -76,18 +76,16 @@ extern "C" { #define MEDIADEMUXER_FLEAVE(); #endif -#define MEDIADEMUXER_CHECK_NULL( x_var ) \ - if ( ! x_var ) \ - { \ - MD_E("[%s] is NULL\n", #x_var ); \ +#define MEDIADEMUXER_CHECK_NULL(x_var) \ + if (!x_var) { \ + MD_E("[%s] is NULL\n", #x_var); \ goto ERROR; \ } -#define MEDIADEMUXER_CHECK_SET_AND_PRINT( x_var, x_cond, ret, ret_val, err_text ) \ - if ( x_var != x_cond ) \ - { \ +#define MEDIADEMUXER_CHECK_SET_AND_PRINT(x_var, x_cond, ret, ret_val, err_text) \ + if (x_var != x_cond) { \ ret = ret_val; \ - MD_E("%s\n", #err_text ); \ + MD_E("%s\n", #err_text); \ goto ERROR; \ } diff --git a/include/port_custom/mediademuxer_port_custom.h b/include/port_custom/mediademuxer_port_custom.h index 38ab5c3..ff9b39a 100755 --- a/include/port_custom/mediademuxer_port_custom.h +++ b/include/port_custom/mediademuxer_port_custom.h @@ -28,9 +28,9 @@ extern "C" { #endif -/*Place holder*/ +/* Place holder */ #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIADEMUXER_PORT_CUSTOM_H__ */ +#endif /* __TIZEN_MEDIADEMUXER_PORT_CUSTOM_H__ */ diff --git a/include/port_ffmpeg/mediademuxer_port_ffmpeg.h b/include/port_ffmpeg/mediademuxer_port_ffmpeg.h index e86ca06..816a9ed 100755 --- a/include/port_ffmpeg/mediademuxer_port_ffmpeg.h +++ b/include/port_ffmpeg/mediademuxer_port_ffmpeg.h @@ -28,9 +28,9 @@ extern "C" { #endif -/*Place holder*/ +/* Place holder */ #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIADEMUXER_PORT_FFMPEG_H__ */ +#endif /* __TIZEN_MEDIADEMUXER_PORT_FFMPEG_H__ */ diff --git a/include/port_gst/mediademuxer_port_gst.h b/include/port_gst/mediademuxer_port_gst.h index b02cce9..908e6b1 100755 --- a/include/port_gst/mediademuxer_port_gst.h +++ b/include/port_gst/mediademuxer_port_gst.h @@ -33,26 +33,22 @@ extern "C" { #define POLLING_INTERVAL 1000 #define MAX_APP_BUFFER 100 -#define MEDIADEMUXER_SET_STATE( x_element, x_state, error ) \ - do \ - { \ - MD_I("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME( x_element ) ); \ - if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state ( x_element, x_state) ) \ - { \ - MD_E("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME( x_element )); \ +#define MEDIADEMUXER_SET_STATE(x_element, x_state, error) \ + do { \ + MD_I("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME(x_element)); \ + if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(x_element, x_state)) { \ + MD_E("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME(x_element)); \ goto error; \ } \ - }while(0) + } while (0) -#define MEDIADEMUXER_LINK_PAD( srcpad, sinkpad, error ) \ - do \ - { \ - if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad) ) \ - { \ +#define MEDIADEMUXER_LINK_PAD(srcpad, sinkpad, error) \ + do { \ + if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) { \ MD_E("failed to linkpad\n"); \ goto error; \ } \ - }while(0) + } while (0) typedef enum { _GST_EVENT_TYPE_COMPLETE, @@ -99,8 +95,8 @@ typedef struct _mdgst_handle_t { int total_tracks; GMutex *mutex; /* for user cb */ - void* user_cb[_GST_EVENT_TYPE_NUM]; - void* user_data[_GST_EVENT_TYPE_NUM]; + void *user_cb[_GST_EVENT_TYPE_NUM]; + void *user_data[_GST_EVENT_TYPE_NUM]; } mdgst_handle_t; @@ -119,4 +115,4 @@ typedef void (*gst_error_cb)(mediademuxer_error_e error, void *user_data); #ifdef __cplusplus } #endif -#endif /* __TIZEN_MEDIADEMUXER_PORT_GST_H__ */ +#endif /* __TIZEN_MEDIADEMUXER_PORT_GST_H__ */ diff --git a/src/mediademuxer.c b/src/mediademuxer.c index 79e538a..5788249 100755 --- a/src/mediademuxer.c +++ b/src/mediademuxer.c @@ -48,7 +48,7 @@ int mediademuxer_create(mediademuxer_h *demuxer) handle->demux_state = MEDIADEMUXER_NONE; } else { MD_E("[CoreAPI][%s] DEMUXER_ERROR_OUT_OF_MEMORY(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_OUT_OF_MEMORY); + __FUNCTION__, MEDIADEMUXER_ERROR_OUT_OF_MEMORY); return MEDIADEMUXER_ERROR_OUT_OF_MEMORY; } } else { @@ -89,13 +89,13 @@ int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) } else { if (!path) { MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_PATH); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_PATH); return MEDIADEMUXER_ERROR_INVALID_PATH; } else { - if(handle->demux_state != MEDIADEMUXER_IDLE) + if (handle->demux_state != MEDIADEMUXER_IDLE) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } } @@ -114,10 +114,10 @@ int mediademuxer_prepare(mediademuxer_h demuxer) if (ret == MEDIADEMUXER_ERROR_NONE) handle->demux_state = MEDIADEMUXER_READY; } else { - if(handle->demux_state != MEDIADEMUXER_IDLE) + if (handle->demux_state != MEDIADEMUXER_IDLE) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; @@ -133,10 +133,10 @@ int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count) if (handle && handle->demux_state == MEDIADEMUXER_READY) { ret = md_get_track_count((MMHandleType) (handle->md_handle), count); } else { - if(handle->demux_state != MEDIADEMUXER_READY) + if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; @@ -152,10 +152,10 @@ int mediademuxer_select_track(mediademuxer_h demuxer, int track_index) if (handle && handle->demux_state == MEDIADEMUXER_READY) { ret = md_select_track((MMHandleType) (handle->md_handle), track_index); } else { - if(handle->demux_state != MEDIADEMUXER_READY) + if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; @@ -173,17 +173,17 @@ int mediademuxer_start(mediademuxer_h demuxer) if (ret == MEDIADEMUXER_ERROR_NONE) handle->demux_state = MEDIADEMUXER_DEMUXING; } else { - if(handle->demux_state != MEDIADEMUXER_READY) + if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; } int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, - media_format_h *format) + media_format_h *format) { MD_I("mediademuxer_get_track_info\n"); mediademuxer_error_e ret; @@ -198,33 +198,32 @@ int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, || handle->demux_state == MEDIADEMUXER_DEMUXING)) { ret = md_get_track_info((MMHandleType) (handle->md_handle), track_index, format); } else { - if(handle->demux_state != MEDIADEMUXER_READY) + if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; } int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index, - media_packet_h *outbuf) + media_packet_h *outbuf) { MD_I("mediademuxer_read_sample\n"); mediademuxer_error_e ret; DEMUXER_INSTANCE_CHECK(demuxer); mediademuxer_s *handle; handle = (mediademuxer_s *)(demuxer); - if (outbuf == NULL || track_index < 0) { + if (outbuf == NULL || track_index < 0) return MEDIADEMUXER_ERROR_INVALID_PARAMETER; - } if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) { ret = md_read_sample((MMHandleType) (handle->md_handle), track_index, outbuf); } else { - if(handle->demux_state != MEDIADEMUXER_DEMUXING) + if (handle->demux_state != MEDIADEMUXER_DEMUXING) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; @@ -240,10 +239,10 @@ int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos) if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) { ret = md_seek((MMHandleType) (handle->md_handle), pos); } else { - if(handle->demux_state != MEDIADEMUXER_DEMUXING) + if (handle->demux_state != MEDIADEMUXER_DEMUXING) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; @@ -260,10 +259,10 @@ int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index) || handle->demux_state == MEDIADEMUXER_DEMUXING)) { ret = md_unselect_track((MMHandleType) (handle->md_handle), track_index); } else { - if(handle->demux_state != MEDIADEMUXER_READY) + if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; @@ -281,10 +280,10 @@ int mediademuxer_stop(mediademuxer_h demuxer) if (ret == MEDIADEMUXER_ERROR_NONE) handle->demux_state = MEDIADEMUXER_READY; } else { - if(handle->demux_state != MEDIADEMUXER_DEMUXING) + if (handle->demux_state != MEDIADEMUXER_DEMUXING) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } return ret; @@ -302,7 +301,7 @@ int mediademuxer_unprepare(mediademuxer_h demuxer) if (ret == MEDIADEMUXER_ERROR_NONE) handle->demux_state = MEDIADEMUXER_IDLE; } else { - if(handle->demux_state != MEDIADEMUXER_READY) + if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); @@ -322,7 +321,7 @@ int mediademuxer_destroy(mediademuxer_h demuxer) ret = md_destroy(handle->md_handle); if (ret != MEDIADEMUXER_ERROR_NONE) { MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } else { MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__, @@ -330,7 +329,7 @@ int mediademuxer_destroy(mediademuxer_h demuxer) } } else { MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", - __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } handle->demux_state = MEDIADEMUXER_NONE; @@ -382,18 +381,16 @@ int mediademuxer_unset_error_cb(mediademuxer_h demuxer) static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data) { - if(user_data == NULL){ - MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n",error); + if (user_data == NULL) { + MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error); return 0; } mediademuxer_s * handle = (mediademuxer_s *) user_data; - if(handle->demux_state != MEDIADEMUXER_IDLE) + if (handle->demux_state != MEDIADEMUXER_IDLE) return MEDIADEMUXER_ERROR_INVALID_STATE; - if ( handle->error_cb ) { + if (handle->error_cb) ((mediademuxer_error_cb)handle->error_cb)(error, handle->error_cb_userdata); - } - else { - MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n",error); - } + else + MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error); return 0; } diff --git a/src/mediademuxer_ini.c b/src/mediademuxer_ini.c index 07213d1..5619ced 100755 --- a/src/mediademuxer_ini.c +++ b/src/mediademuxer_ini.c @@ -41,70 +41,56 @@ static gboolean _generate_default_ini(void); static void _md_ini_check_ini_status(void); /* macro */ -#define MEDIADEMUXER_INI_GET_STRING( x_dict, x_item, x_ini, x_default ) \ - do \ - { \ +#define MEDIADEMUXER_INI_GET_STRING(x_dict, x_item, x_ini, x_default) \ + do { \ gchar* str = iniparser_getstring(x_dict, x_ini, x_default); \ \ - if ( str && \ - ( strlen( str ) > 0 ) && \ - ( strlen( str ) < MEDIADEMUXER_INI_MAX_STRLEN ) ) \ - { \ - strcpy ( x_item, str ); \ + if (str && \ + (strlen(str) > 0) && \ + (strlen(str) < MEDIADEMUXER_INI_MAX_STRLEN)) { \ + strcpy(x_item, str); \ + } else { \ + strcpy(x_item, x_default); \ } \ - else \ - { \ - strcpy ( x_item, x_default ); \ - } \ - }while(0) + } while (0) -#define MEDIADEMUXER_INI_GET_COLOR( x_dict, x_item, x_ini, x_default ) \ - do \ - { \ +#define MEDIADEMUXER_INI_GET_COLOR(x_dict, x_item, x_ini, x_default) \ + do { \ gchar* str = iniparser_getstring(x_dict, x_ini, x_default); \ \ - if ( str && \ - ( strlen( str ) > 0 ) && \ - ( strlen( str ) < MEDIADEMUXER_INI_MAX_STRLEN ) ) \ - { \ + if (str && \ + (strlen(str) > 0) && \ + (strlen(str) < MEDIADEMUXER_INI_MAX_STRLEN)) { \ x_item = (guint) strtoul(str, NULL, 16); \ - } \ - else \ - { \ + } else { \ x_item = (guint) strtoul(x_default, NULL, 16); \ } \ - }while(0) + } while (0) /* x_ini is the list of index to set TRUE at x_list[index] */ -#define MEDIADEMUXER_INI_GET_BOOLEAN_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \ - do \ - { \ +#define MEDIADEMUXER_INI_GET_BOOLEAN_FROM_LIST(x_dict, x_list, x_list_max, x_ini, x_default) \ + do { \ int index = 0; \ const char *delimiters = " ,"; \ char *usr_ptr = NULL; \ char *token = NULL; \ gchar temp_arr[MEDIADEMUXER_INI_MAX_STRLEN] = {0}; \ - MMMEDIADEMUXER_INI_GET_STRING( x_dict, temp_arr, x_ini, x_default); \ - token = strtok_r( temp_arr, delimiters, &usr_ptr ); \ - while (token) \ - { \ + MMMEDIADEMUXER_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \ + token = strtok_r(temp_arr, delimiters, &usr_ptr); \ + while (token) { \ index = atoi(token); \ - if (index < 0 || index > x_list_max -1) \ - { \ + if (index < 0 || index > x_list_max -1) { \ MD_W("%d is not valid index\n", index); \ - } \ - else \ - { \ + } else { \ x_list[index] = TRUE; \ } \ - token = strtok_r( NULL, delimiters, &usr_ptr ); \ + token = strtok_r(NULL, delimiters, &usr_ptr); \ } \ - }while(0) + } while (0) /* x_ini is the list of value to be set at x_list[index] */ -#define MEDIADEMUXER_INI_GET_INT_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \ - do \ - { \ +#define MEDIADEMUXER_INI_GET_INT_FROM_LIST(x_dict, x_list, x_list_max, x_ini, x_default) \ + do { \ int index = 0; \ int value = 0; \ const char *delimiters = " ,"; \ @@ -112,23 +98,19 @@ static void _md_ini_check_ini_status(void); char *token = NULL; \ gchar temp_arr[MEDIADEMUXER_INI_MAX_STRLEN] = {0}; \ MMMEDIADEMUXER_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \ - token = strtok_r( temp_arr, delimiters, &usr_ptr ); \ - while (token) \ - { \ - if ( index > x_list_max -1) \ - { \ + token = strtok_r(temp_arr, delimiters, &usr_ptr); \ + while (token) { \ + if (index > x_list_max -1) { \ MD_E("%d is not valid index\n", index); \ break; \ - } \ - else \ - { \ + } else { \ value = atoi(token); \ x_list[index] = value; \ index++; \ } \ - token = strtok_r( NULL, delimiters, &usr_ptr ); \ + token = strtok_r(NULL, delimiters, &usr_ptr); \ } \ - }while(0) + } while (0) int md_ini_load(md_ini_t *ini) { @@ -159,14 +141,11 @@ int md_ini_load(md_ini_t *ini) if (dict) { /* if dict is available */ /* general */ - MEDIADEMUXER_INI_GET_STRING(dict, ini->port_name, - "port_in_use:mediademuxer_port", - DEFAULT_PORT); + MEDIADEMUXER_INI_GET_STRING(dict, ini->port_name, "port_in_use:mediademuxer_port", DEFAULT_PORT); } else { /* if dict is not available just fill the structure with default value */ MD_W("failed to load ini. using hardcoded default\n"); - strncpy(ini->port_name, DEFAULT_PORT, - MEDIADEMUXER_INI_MAX_STRLEN - 1); + strncpy(ini->port_name, DEFAULT_PORT, MEDIADEMUXER_INI_MAX_STRLEN - 1); } if (0 == strcmp(ini->port_name, "GST_PORT")) @@ -208,9 +187,8 @@ static void _md_ini_check_ini_status(void) if (ini_buff.st_size < 5) { MD_W("demuxer.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size); - if (g_remove(MEDIADEMUXER_INI_DEFAULT_PATH) == -1) { + if (g_remove(MEDIADEMUXER_INI_DEFAULT_PATH) == -1) MD_E("failed to delete corrupted ini"); - } } } } @@ -224,13 +202,12 @@ static gboolean _generate_default_ini(void) /* create new file */ fp = fopen(MEDIADEMUXER_INI_DEFAULT_PATH, "wt"); - if (!fp) { + if (!fp) return FALSE; - } /* writing default ini file */ if (strlen(default_ini) != - fwrite(default_ini, 1, strlen(default_ini), fp)) { + fwrite(default_ini, 1, strlen(default_ini), fp)) { fclose(fp); return FALSE; } @@ -240,4 +217,4 @@ static gboolean _generate_default_ini(void) } #endif -#endif /* #ifdef _MEDIADEMUXER_INI_C_ */ +#endif /* #ifdef _MEDIADEMUXER_INI_C_ */ diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index d0a503c..ed3d43a 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -78,13 +78,12 @@ int md_create(MMHandleType *demuxer) /* load ini files */ result = md_ini_load(&new_demuxer->ini); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_COURRPTED_INI, "can't load ini"); + MD_COURRPTED_INI, "can't load ini"); register_port_func[new_demuxer->ini.port_type](pOps); result = pOps->init(&new_demuxer->mdport_handle); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_NOT_INITIALIZED, - "md_create failed"); + MD_NOT_INITIALIZED, "md_create failed"); *demuxer = (MMHandleType) new_demuxer; MEDIADEMUXER_FLEAVE(); return result; @@ -141,9 +140,8 @@ bool __md_util_is_sdp_file(const char *path) MEDIADEMUXER_FENTER(); return_val_if_fail(path, FALSE); uri = g_ascii_strdown(path, -1); - if (uri == NULL) { + if (uri == NULL) return FALSE; - } /* trimming */ g_strstrip(uri); /* strlen(".sdp") == 4 */ @@ -154,9 +152,8 @@ bool __md_util_is_sdp_file(const char *path) /* first, check extension name */ ret = g_str_has_suffix(uri, "sdp"); /* second, if no suffix is there, check it's contents */ - if (!ret) { + if (!ret) /* FIXIT : do it soon */ - } g_free(uri); uri = NULL; MEDIADEMUXER_FLEAVE(); @@ -185,11 +182,10 @@ mediademuxer_src_type __md_util_media_type(char **uri) } } else if ((path = strstr(*uri, "rtsp://"))) { if (strlen(path)) { - if ((path = strstr(*uri, "/wfd1.0/"))) { + if ((path = strstr(*uri, "/wfd1.0/"))) return (MEDIADEMUXER_SRC_WFD); - } else { + else return (MEDIADEMUXER_SRC_RTSP); - } } } else if ((path = strstr(*uri, "http://"))) { if (strlen(path)) { @@ -284,8 +280,8 @@ int md_set_data_source(MMHandleType demuxer, const char *uri) MEDIADEMUXER_CHECK_NULL(demuxer); result = _md_util_parse(demuxer, (const char *)uri); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR_INVALID_ARGUMENT, - "error while parsing the file"); + MD_ERROR_INVALID_ARGUMENT, + "error while parsing the file"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -304,7 +300,7 @@ int md_prepare(MMHandleType demuxer) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->prepare(md_handle->mdport_handle, md_handle->uri_src); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR, "error while doing prepare"); + MD_ERROR, "error while doing prepare"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -323,8 +319,8 @@ int md_get_track_count(MMHandleType demuxer, int *count) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->get_track_count(md_handle->mdport_handle, count); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, - result, MD_ERROR, - "error while getting track count"); + result, MD_ERROR, + "error while getting track count"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -343,7 +339,7 @@ int md_select_track(MMHandleType demuxer, int track) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->set_track(md_handle->mdport_handle, track); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR, "error select track"); + MD_ERROR, "error select track"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -362,7 +358,7 @@ int md_start(MMHandleType demuxer) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->start(md_handle->mdport_handle); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR, "error while doing start"); + MD_ERROR, "error while doing start"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -381,8 +377,8 @@ int md_get_track_info(MMHandleType demuxer, int track, media_format_h *format) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->get_track_info(md_handle->mdport_handle, format, track); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, - result, MD_ERROR, - "error while getting track count"); + result, MD_ERROR, + "error while getting track count"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -423,7 +419,7 @@ int md_seek(MMHandleType demuxer, int64_t pos) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->seek(md_handle->mdport_handle, pos); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR, "error while doing seek"); + MD_ERROR, "error while doing seek"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -442,7 +438,7 @@ int md_unselect_track(MMHandleType demuxer, int track) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->unset_track(md_handle->mdport_handle, track); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR, "error unselect track"); + MD_ERROR, "error unselect track"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -461,7 +457,7 @@ int md_stop(MMHandleType demuxer) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->stop(md_handle->mdport_handle); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR, "error while doing stop"); + MD_ERROR, "error while doing stop"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -480,7 +476,7 @@ int md_unprepare(MMHandleType demuxer) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->unprepare(md_handle->mdport_handle); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR, "error while doing stop"); + MD_ERROR, "error while doing stop"); MEDIADEMUXER_FLEAVE(); return result; ERROR: @@ -499,7 +495,7 @@ int md_destroy(MMHandleType demuxer) MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->destroy(md_handle->mdport_handle); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, - MD_ERROR, "error while doing destroy"); + MD_ERROR, "error while doing destroy"); /* free mediademuxer structure */ if (md_handle) { @@ -509,7 +505,7 @@ int md_destroy(MMHandleType demuxer) } if (md_handle->uri_src) { MD_I("md_destroy deallocating md_handle->uri_src %p:\n", - md_handle->uri_src); + md_handle->uri_src); g_free((void *)(md_handle->uri_src)); } MD_I("md_destroy deallocating md_handle %p:\n", md_handle); @@ -532,7 +528,7 @@ int md_set_error_cb(MMHandleType demuxer, MEDIADEMUXER_CHECK_NULL(md_handle); media_port_demuxer_ops *pOps = md_handle->demuxer_ops; MEDIADEMUXER_CHECK_NULL(pOps); - result = pOps->set_error_cb(md_handle->mdport_handle, callback,user_data); + result = pOps->set_error_cb(md_handle->mdport_handle, callback, user_data); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, MD_ERROR, "error while setting error call back"); MEDIADEMUXER_FLEAVE(); diff --git a/src/port_custom/mediademuxer_port_custom.c b/src/port_custom/mediademuxer_port_custom.c index 15c7bfc..6224014 100755 --- a/src/port_custom/mediademuxer_port_custom.c +++ b/src/port_custom/mediademuxer_port_custom.c @@ -28,12 +28,11 @@ static int custom_demuxer_init(MMHandleType *pHandle); static int custom_demuxer_prepare(MMHandleType pHandle, char *uri); static int custom_demuxer_get_data_count(MMHandleType pHandle, int *count); -static int custom_demuxer_get_track_info(MMHandleType pHandle, - media_format_h *format, int track); +static int custom_demuxer_get_track_info(MMHandleType pHandle, media_format_h *format, int track); static int custom_demuxer_set_track(MMHandleType pHandle, int track); static int custom_demuxer_get_data(MMHandleType pHandle, char *buffer); -/*Media Demuxer API common*/ +/* Media Demuxer API common */ static media_port_demuxer_ops def_demux_ops = { .n_size = 0, .init = custom_demuxer_init, @@ -52,9 +51,7 @@ int custom_port_register(media_port_demuxer_ops *pOps) def_demux_ops.n_size = sizeof(def_demux_ops); - memcpy((char *)pOps + sizeof(pOps->n_size), - (char *)&def_demux_ops + sizeof(def_demux_ops.n_size), - pOps->n_size - sizeof(pOps->n_size)); + memcpy((char *)pOps + sizeof(pOps->n_size), (char *)&def_demux_ops + sizeof(def_demux_ops.n_size), pOps->n_size - sizeof(pOps->n_size)); MEDIADEMUXER_FLEAVE(); return ret; @@ -80,7 +77,6 @@ static int custom_demuxer_prepare(MMHandleType pHandle, char *uri) return 0; } - static int custom_demuxer_get_data_count(MMHandleType pHandle, int *count) { MEDIADEMUXER_FENTER(); @@ -89,8 +85,7 @@ static int custom_demuxer_get_data_count(MMHandleType pHandle, int *count) return 0; } -static int custom_demuxer_get_track_info(MMHandleType pHandle, - media_format_h *format, int track) +static int custom_demuxer_get_track_info(MMHandleType pHandle, media_format_h *format, int track) { MEDIADEMUXER_FENTER(); MD_E("%s:exit: Not implemented\n", __func__); diff --git a/src/port_ffmpeg/mediademuxer_port_ffmpeg.c b/src/port_ffmpeg/mediademuxer_port_ffmpeg.c index 7e55d4e..a49b8a8 100755 --- a/src/port_ffmpeg/mediademuxer_port_ffmpeg.c +++ b/src/port_ffmpeg/mediademuxer_port_ffmpeg.c @@ -28,12 +28,11 @@ static int ffmpeg_demuxer_init(MMHandleType *pHandle); static int ffmpeg_demuxer_prepare(MMHandleType pHandle, char *uri); static int ffmpeg_demuxer_get_data_count(MMHandleType pHandle, int *count); -static int ffmpeg_demuxer_get_track_info(MMHandleType pHandle, - media_format_h *format, int track); +static int ffmpeg_demuxer_get_track_info(MMHandleType pHandle, media_format_h *format, int track); static int ffmpeg_demuxer_set_track(MMHandleType pHandle, int track); static int ffmpeg_demuxer_get_data(MMHandleType pHandle, char *buffer); -/*Media Demuxer API common*/ +/* Media Demuxer API common */ static media_port_demuxer_ops def_demux_ops = { .n_size = 0, .init = ffmpeg_demuxer_init, @@ -52,9 +51,7 @@ int ffmpeg_port_register(media_port_demuxer_ops *pOps) def_demux_ops.n_size = sizeof(def_demux_ops); - memcpy((char *)pOps + sizeof(pOps->n_size), - (char *)&def_demux_ops + sizeof(def_demux_ops.n_size), - pOps->n_size - sizeof(pOps->n_size)); + memcpy((char *)pOps + sizeof(pOps->n_size), (char *)&def_demux_ops + sizeof(def_demux_ops.n_size), pOps->n_size - sizeof(pOps->n_size)); MEDIADEMUXER_FLEAVE(); return ret; @@ -90,8 +87,7 @@ static int ffmpeg_demuxer_get_data_count(MMHandleType pHandle, int *count) return ret; } -static int ffmpeg_demuxer_get_track_info(MMHandleType pHandle, - media_format_h *format, int track) +static int ffmpeg_demuxer_get_track_info(MMHandleType pHandle, media_format_h *format, int track) { int ret = MD_ERROR_NONE; MEDIADEMUXER_FENTER(); diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index a2c235d..6cee35e 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -44,7 +44,7 @@ static int gst_demuxer_destroy(MMHandleType pHandle); static int gst_set_error_cb(MMHandleType pHandle, gst_error_cb callback, void* user_data); -/*Media Demuxer API common*/ +/* Media Demuxer API common */ static media_port_demuxer_ops def_demux_ops = { .n_size = 0, .init = gst_demuxer_init, @@ -114,23 +114,23 @@ gboolean __gst_bus_call(GstBus *bus, GstMessage *msg, gpointer data) MEDIADEMUXER_FENTER(); int ret = MD_ERROR_NONE; switch (GST_MESSAGE_TYPE(msg)) { - case GST_MESSAGE_EOS: { - MD_I("EOS Reached"); - } - break; - case GST_MESSAGE_ERROR: { - GError *error = NULL; - gst_message_parse_error(msg, &error, NULL); - if (!error) { - MD_I("GST error message parsing failed"); - break; - } - MD_E("Error: %s\n", error->message); - g_error_free(error); + case GST_MESSAGE_EOS: { + MD_I("EOS Reached"); + } + break; + case GST_MESSAGE_ERROR: { + GError *error = NULL; + gst_message_parse_error(msg, &error, NULL); + if (!error) { + MD_I("GST error message parsing failed"); + break; } - break; - default: - break; + MD_E("Error: %s\n", error->message); + g_error_free(error); + } + break; + default: + break; } MEDIADEMUXER_FLEAVE(); return ret; @@ -177,8 +177,8 @@ void __gst_free_stuct(track **head) while (temp) { /* if (temp->pad) { - MD_I("deallocate GST_PAD %p\n", temp->pad); - gst_object_unref(temp->pad); + MD_I("deallocate GST_PAD %p\n", temp->pad); + gst_object_unref(temp->pad); } */ if (temp->name) { MD_I("deallocate GST_PAD name %p\n", temp->name); @@ -210,7 +210,7 @@ void __gst_free_stuct(track **head) } int __gst_add_track_info(GstPad *pad, gchar *name, track **head, - GstElement *pipeline) + GstElement *pipeline) { MEDIADEMUXER_FENTER(); GstPad *apppad = NULL; @@ -255,7 +255,7 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, gst_object_unref(apppad); return MD_ERROR; } - gst_bin_add_many(GST_BIN(pipeline),parse_element, NULL); + gst_bin_add_many(GST_BIN(pipeline), parse_element, NULL); MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR); parse_sink_pad = gst_element_get_static_pad(parse_element, "sink"); @@ -266,22 +266,21 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, return MD_ERROR; } - /* Link demuxer pad with sink pad of parse element*/ + /* Link demuxer pad with sink pad of parse element */ MEDIADEMUXER_LINK_PAD(pad, parse_sink_pad, ERROR); - outcaps = gst_caps_new_simple("video/x-h264", "stream-format",G_TYPE_STRING, "byte-stream", NULL); + outcaps = gst_caps_new_simple("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", NULL); gst_element_link_filtered(parse_element, temp->appsink, outcaps); } else { MEDIADEMUXER_LINK_PAD(pad, apppad, ERROR); } - /*gst_pad_link(pad, fpad) */ + /* gst_pad_link(pad, fpad) */ if (*head == NULL) { *head = temp; } else { track *prev = *head; - while (prev->next) { + while (prev->next) prev = prev->next; - } prev->next = temp; } gst_object_unref(apppad); @@ -368,11 +367,10 @@ static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) MD_E("fail to get typefind src pad.\n"); goto ERROR; } - if (!id3tag) { + if (!id3tag) aud_pad = gst_element_get_static_pad(gst_handle->demux, "sink"); - } else { + else aud_pad = gst_element_get_static_pad(id3tag, "sink"); - } if (!aud_pad) { MD_E("fail to get audio parse sink pad.\n"); goto ERROR; @@ -401,7 +399,7 @@ static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) gst_object_unref(fake_pad); } - /* calling "on_pad_added" function to set the caps*/ + /* calling "on_pad_added" function to set the caps */ aud_srcpad = gst_element_get_static_pad(gst_handle->demux, "src"); if (!aud_srcpad) { MD_E("fail to get audioparse source pad.\n"); @@ -423,14 +421,13 @@ static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) gst_object_unref(aud_srcpad); trck = head_track->head; - while (aud_srcpad != trck->pad && trck != NULL) { + while (aud_srcpad != trck->pad && trck != NULL) trck = trck->next; - } if (trck != NULL) { trck->caps = caps; trck->caps_string = gst_caps_to_string(trck->caps); - MD_I("caps set to %s\n",trck->caps_string); - g_strlcpy(name,"audio",strlen(name)); + MD_I("caps set to %s\n", trck->caps_string); + g_strlcpy(name, "audio", strlen(name)); trck->name = name; } (head_track->num_audio_track)++; @@ -454,7 +451,7 @@ ERROR: } static void __gst_cb_typefind(GstElement *tf, guint probability, - GstCaps *caps, gpointer data) + GstCaps *caps, gpointer data) { MEDIADEMUXER_FENTER(); mdgst_handle_t *gst_handle = (mdgst_handle_t *) data; @@ -474,11 +471,11 @@ static void __gst_cb_typefind(GstElement *tf, guint probability, goto ERROR; } else { g_signal_connect(gst_handle->demux, "pad-added", - G_CALLBACK(__gst_on_pad_added), gst_handle); + G_CALLBACK(__gst_on_pad_added), gst_handle); g_signal_connect(gst_handle->demux, "no-more-pads", - G_CALLBACK(__gst_no_more_pad), gst_handle); + G_CALLBACK(__gst_no_more_pad), gst_handle); gst_bin_add_many(GST_BIN(gst_handle->pipeline), - gst_handle->demux, NULL); + gst_handle->demux, NULL); pad = gst_element_get_static_pad(gst_handle->typefind, "src"); if (!pad) { MD_E("fail to get typefind src pad.\n"); @@ -497,7 +494,7 @@ static void __gst_cb_typefind(GstElement *tf, guint probability, gst_pad_unlink(pad, fake_pad); MEDIADEMUXER_LINK_PAD(pad, qt_pad, ERROR); MEDIADEMUXER_SET_STATE(gst_handle->demux, - GST_STATE_PAUSED, ERROR); + GST_STATE_PAUSED, ERROR); if (pad) gst_object_unref(pad); if (qt_pad) @@ -571,7 +568,7 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) goto ERROR; } g_signal_connect(gst_handle->typefind, "have-type", - G_CALLBACK(__gst_cb_typefind), gst_handle); + G_CALLBACK(__gst_cb_typefind), gst_handle); gst_handle->fakesink = gst_element_factory_make("fakesink", NULL); if (!gst_handle->fakesink) { MD_E("fakesink creation failed"); @@ -581,14 +578,14 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) /* Build the pipeline */ gst_bin_add_many(GST_BIN(gst_handle->pipeline), - gst_handle->filesrc, - gst_handle->typefind, - gst_handle->fakesink, - NULL); + gst_handle->filesrc, + gst_handle->typefind, + gst_handle->fakesink, + NULL); gst_element_link_many(gst_handle->filesrc, - gst_handle->typefind, - gst_handle->fakesink, - NULL); + gst_handle->typefind, + gst_handle->fakesink, + NULL); /* connect signals, bus watcher */ bus = gst_pipeline_get_bus(GST_PIPELINE(gst_handle->pipeline)); @@ -640,9 +637,9 @@ static int gst_demuxer_get_data_count(MMHandleType pHandle, int *count) mdgst_handle_t *new_mediademuxer = (mdgst_handle_t *) pHandle; *count = (new_mediademuxer->info).num_video_track + - (new_mediademuxer->info).num_audio_track + - (new_mediademuxer->info).num_subtitle_track + - (new_mediademuxer->info).num_other_track; + (new_mediademuxer->info).num_audio_track + + (new_mediademuxer->info).num_subtitle_track + + (new_mediademuxer->info).num_other_track; MEDIADEMUXER_FLEAVE(); return ret; ERROR: @@ -680,7 +677,7 @@ static int gst_demuxer_set_track(MMHandleType pHandle, int track) } new_mediademuxer->selected_tracks[track] = true; _gst_set_appsink((((mdgst_handle_t *) pHandle)->info).head, track, - new_mediademuxer->total_tracks); + new_mediademuxer->total_tracks); MEDIADEMUXER_FLEAVE(); return MD_ERROR_NONE; ERROR: @@ -698,7 +695,7 @@ static int gst_demuxer_start(MMHandleType pHandle) int indx; for (indx = 0; indx < gst_handle->total_tracks; indx++) { MD_I("track indx[%d] is marked as [%d]. (0- not selected, 1= selected)\n", - indx, gst_handle->selected_tracks[indx]); + indx, gst_handle->selected_tracks[indx]); /* if (gst_handle->selected_tracks[indx] == false) _gst_demuxer_unset(pHandle, indx); @@ -707,15 +704,15 @@ static int gst_demuxer_start(MMHandleType pHandle) track_info *head_track = &(gst_handle->info); MD_I("Total Audio track=%d, Video track=%d, text track=%d\n", - head_track->num_audio_track, head_track->num_video_track, - head_track->num_subtitle_track); + head_track->num_audio_track, head_track->num_video_track, + head_track->num_subtitle_track); track *temp = head_track->head; indx = 0; while (temp) { MD_I("Got one element %p\n", temp->appsink); if (gst_element_set_state(temp->appsink, GST_STATE_PLAYING) == - GST_STATE_CHANGE_FAILURE) { + GST_STATE_CHANGE_FAILURE) { MD_E("Failed to set into PLAYING state"); ret = MD_ERROR_UNKNOWN; } @@ -798,84 +795,79 @@ int _set_mime_audio(media_format_h format, track *head) goto ERROR; } - if (gst_structure_has_name(struc, "application/x-id3")) { + if (gst_structure_has_name(struc, "application/x-id3")) id3_flag = 1; - } if (gst_structure_has_name(struc, "audio/mpeg") || id3_flag) { gint mpegversion; int layer; gst_structure_get_int(struc, "mpegversion", &mpegversion); - if (mpegversion == 4 || mpegversion == 2 ) { + if (mpegversion == 4 || mpegversion == 2) { gst_structure_get_int(struc, "channels", &channels); gst_structure_get_int(struc, "rate", &rate); gst_structure_get_int(struc, "bit", &bit); stream_format = gst_structure_get_string(struc, "stream-format"); if (media_format_set_audio_mime(format, MEDIA_FORMAT_AAC_LC)) goto ERROR; - if(channels == 0) - channels = 2; /* default */ + if (channels == 0) + channels = 2; /* default */ if (media_format_set_audio_channel(format, channels)) goto ERROR; - if(rate == 0) - rate = 44100; /* default */ + if (rate == 0) + rate = 44100; /* default */ if (media_format_set_audio_samplerate(format, rate)) goto ERROR; - if(bit == 0) { - bit = 16; /* default */ - } - if (media_format_set_audio_bit(format, bit)) { + if (bit == 0) + bit = 16; /* default */ + if (media_format_set_audio_bit(format, bit)) goto ERROR; - } if (strncmp(stream_format, "adts", 4) == 0) media_format_set_audio_aac_type(format, 1); else media_format_set_audio_aac_type(format, 0); } - if (mpegversion == 1 || id3_flag ) { + if (mpegversion == 1 || id3_flag) { gst_structure_get_int(struc, "layer", &layer); - if((layer == 3) || (id3_flag == 1)) { + if ((layer == 3) || (id3_flag == 1)) { gst_structure_get_int(struc, "channels", &channels); gst_structure_get_int(struc, "rate", &rate); gst_structure_get_int(struc, "bit", &bit); if (media_format_set_audio_mime(format, MEDIA_FORMAT_MP3)) goto ERROR; - if(channels == 0) - channels = 2; /* default */ + if (channels == 0) + channels = 2; /* default */ if (media_format_set_audio_channel(format, channels)) goto ERROR; - if(rate == 0) - rate = 44100; /* default */ - if(bit == 0) - bit = 16; /* default */ + if (rate == 0) + rate = 44100; /* default */ + if (bit == 0) + bit = 16; /* default */ if (media_format_set_audio_samplerate(format, rate)) goto ERROR; if (media_format_set_audio_bit(format, bit)) goto ERROR; - } - else { - MD_I("No Support for MPEG%d Layer %d media\n",mpegversion,layer); + } else { + MD_I("No Support for MPEG%d Layer %d media\n", mpegversion, layer); goto ERROR; } } - }else if (gst_structure_has_name(struc, "audio/x-amr-nb-sh") || + } else if (gst_structure_has_name(struc, "audio/x-amr-nb-sh") || gst_structure_has_name(struc, "audio/x-amr-wb-sh")) { media_format_mimetype_e mime_type; gst_structure_get_int(struc, "channels", &channels); gst_structure_get_int(struc, "rate", &rate); if (gst_structure_has_name(struc, "audio/x-amr-nb-sh")) { - mime_type= MEDIA_FORMAT_AMR_NB; + mime_type = MEDIA_FORMAT_AMR_NB; rate = 8000; - } - else { + } else { mime_type = MEDIA_FORMAT_AMR_WB; rate = 16000; } - if (media_format_set_audio_mime(format,mime_type)) + if (media_format_set_audio_mime(format, mime_type)) goto ERROR; - if(channels == 0) - channels = 1; /* default */ - if(bit == 0) - bit = 16; /* default */ + if (channels == 0) + channels = 1; /* default */ + if (bit == 0) + bit = 16; /* default */ if (media_format_set_audio_channel(format, channels)) goto ERROR; if (media_format_set_audio_samplerate(format, rate)) @@ -888,14 +880,14 @@ int _set_mime_audio(media_format_h format, track *head) gst_structure_get_int(struc, "bit", &bit); if (media_format_set_audio_mime(format, MEDIA_FORMAT_AMR_NB)) goto ERROR; - if(channels == 0) - channels = 1; /* default */ + if (channels == 0) + channels = 1; /* default */ if (media_format_set_audio_channel(format, channels)) goto ERROR; if (media_format_set_audio_samplerate(format, rate)) goto ERROR; if (bit == 0) - bit = 16; /* default */ + bit = 16; /* default */ if (media_format_set_audio_bit(format, bit)) goto ERROR; } else if (gst_structure_has_name(struc, "audio/AMR-WB")) { @@ -904,14 +896,14 @@ int _set_mime_audio(media_format_h format, track *head) gst_structure_get_int(struc, "bit", &bit); if (media_format_set_audio_mime(format, MEDIA_FORMAT_AMR_WB)) goto ERROR; - if(channels == 0) - channels = 1; /* default */ + if (channels == 0) + channels = 1; /* default */ if (media_format_set_audio_channel(format, channels)) goto ERROR; if (media_format_set_audio_samplerate(format, rate)) goto ERROR; if (bit == 0) - bit = 16; /* default */ + bit = 16; /* default */ if (media_format_set_audio_bit(format, bit)) goto ERROR; } else { @@ -926,7 +918,7 @@ ERROR: } static int gst_demuxer_get_track_info(MMHandleType pHandle, - media_format_h *format, int index) + media_format_h *format, int index) { MEDIADEMUXER_FENTER(); int ret = MD_ERROR_NONE; @@ -938,17 +930,17 @@ static int gst_demuxer_get_track_info(MMHandleType pHandle, int count = 0; temp = (new_mediademuxer->info).head; loop = (new_mediademuxer->info).num_video_track + - (new_mediademuxer->info).num_audio_track + - (new_mediademuxer->info).num_subtitle_track + - (new_mediademuxer->info).num_other_track; + (new_mediademuxer->info).num_audio_track + + (new_mediademuxer->info).num_subtitle_track + + (new_mediademuxer->info).num_other_track; if (index >= loop || index < 0) { MD_E("total tracks(loop) is less then selected track(index), So not support this track"); goto ERROR; } ret = media_format_create(format); - if(ret != MEDIA_FORMAT_ERROR_NONE){ - MD_E("Mediaformat creation failed. returned %d\n",ret); + if (ret != MEDIA_FORMAT_ERROR_NONE) { + MD_E("Mediaformat creation failed. returned %d\n", ret); ret = MD_INTERNAL_ERROR; goto ERROR; } @@ -965,9 +957,8 @@ static int gst_demuxer_get_track_info(MMHandleType pHandle, } else if (temp->name[0] == 'v') { MD_I("Setting for Video \n"); _set_mime_video(*format, temp); - } else { + } else MD_I("Not supported so far (except audio and video)\n"); - } MEDIADEMUXER_FLEAVE(); return ret; ERROR: @@ -976,7 +967,7 @@ ERROR: } static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt, - GstBuffer *buffer, char *codec_data) + GstBuffer *buffer, char *codec_data) { MEDIADEMUXER_FENTER(); int ret = MD_ERROR_NONE; @@ -990,7 +981,7 @@ static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt, ret = MD_ERROR_UNKNOWN; goto ERROR; } - /* copy data*/ + /* copy data */ media_packet_get_buffer_size(out_pkt, &size); MD_I("Media packet Buffer capacity: %llu GST Buffer size = %d\n", size, map.size); if (size < (uint64_t)map.size) { @@ -1021,12 +1012,12 @@ static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt, ret = MD_ERROR_UNKNOWN; goto ERROR; } - if (media_packet_set_buffer_size(out_pkt, gst_buffer_get_size(buffer))) { + if (media_packet_set_buffer_size(out_pkt, gst_buffer_get_size(buffer))) { MD_E("unable to set the buffer size\n"); ret = MD_ERROR_UNKNOWN; goto ERROR; } - if (media_packet_set_flags(out_pkt, GST_BUFFER_FLAGS(buffer))) { + if (media_packet_set_flags(out_pkt, GST_BUFFER_FLAGS(buffer))) { MD_E("unable to set the buffer size\n"); ret = MD_ERROR_UNKNOWN; goto ERROR; @@ -1045,7 +1036,7 @@ ERROR: } static int gst_demuxer_read_sample(MMHandleType pHandle, - media_packet_h *outbuf, int track_indx) + media_packet_h *outbuf, int track_indx) { MEDIADEMUXER_FENTER(); int ret = MD_ERROR_NONE; @@ -1066,7 +1057,7 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, goto ERROR; } while (atrack) { - if (indx == track_indx) /*Got the requird track details*/ + if (indx == track_indx) /* Got the requird track details */ break; if (atrack->next) { track *next = atrack->next; @@ -1096,8 +1087,7 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, ret = MD_ERROR; goto ERROR; } - } - else if (atrack->name[0] == 'v'){ + } else if (atrack->name[0] == 'v') { if (media_format_create(&mediafmt)) { MD_E("media_format_create failed\n"); ret = MD_ERROR; @@ -1125,8 +1115,7 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, ret = MD_ERROR; goto ERROR; } - } - else { + } else { MD_E("Invalid track format\n"); goto ERROR; } @@ -1159,9 +1148,8 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, /* Create the codec data and pass to _gst_copy_buf_to_media_packet() to add into the media packet */ temp_codec_data = strstr(atrack->caps_string, "codec_data"); if (temp_codec_data != NULL) { - while (*temp_codec_data != ')') { + while (*temp_codec_data != ')') temp_codec_data++; - } temp_codec_data++; /* to esacpe ')' */ codec_data = (char*) malloc(sizeof(char)*strlen(temp_codec_data)); if (codec_data != NULL) { @@ -1265,7 +1253,7 @@ static int gst_demuxer_unset_track(MMHandleType pHandle, int track) } new_mediademuxer->selected_tracks[track] = false; _gst_unset_appsink((((mdgst_handle_t *) pHandle)->info).head, track, - new_mediademuxer->total_tracks); + new_mediademuxer->total_tracks); MEDIADEMUXER_FLEAVE(); return MD_ERROR_NONE; ERROR: @@ -1302,9 +1290,8 @@ void _gst_clear_struct(mdgst_handle_t *gst_handle) g_free(gst_handle->selected_tracks); gst_handle->selected_tracks = NULL; } - if ((gst_handle->info).head) { + if ((gst_handle->info).head) __gst_free_stuct(&(gst_handle->info).head); - } MEDIADEMUXER_FLEAVE(); } @@ -1374,12 +1361,11 @@ int gst_set_error_cb(MMHandleType pHandle, goto ERROR; } - if(gst_handle->user_cb[_GST_EVENT_TYPE_ERROR]) { + if (gst_handle->user_cb[_GST_EVENT_TYPE_ERROR]) { MD_E("Already set mediademuxer_error_cb\n"); ret = MD_ERROR_INVALID_ARGUMENT; goto ERROR; - } - else { + } else { if (!callback) { MD_E("fail invaild argument (callback)\n"); ret = MD_ERROR_INVALID_ARGUMENT; diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index f460329..ff1534d 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -53,8 +53,8 @@ media_format_mimetype_e v_mime; media_format_mimetype_e a_mime; int g_menu_state = CURRENT_STATUS_MAINMENU; int num_tracks = 0; -int aud_track =-1; -int vid_track =-1; +int aud_track = -1; +int vid_track = -1; int w; int h; int channel = 0; @@ -80,28 +80,28 @@ bool is_adts = 0; if (ret != MD_ERROR_NONE) {\ printf("[%s:%d] error code : %x \n", __func__, __LINE__, ret); \ return; \ - }\ - } while(0) + } \ + } while (0) -#define debug_msg_t(fmt,arg...)\ +#define debug_msg_t(fmt, arg...)\ do { \ - fprintf(stderr, MMF_DEBUG"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ - } while(0) + fprintf(stderr, MMF_DEBUG"[%s:%05d] " fmt "\n", __func__, __LINE__, ##arg); \ + } while (0) -#define err_msg_t(fmt,arg...)\ +#define err_msg_t(fmt, arg...)\ do { \ - fprintf(stderr, MMF_ERR"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ - } while(0) + fprintf(stderr, MMF_ERR"[%s:%05d] " fmt "\n", __func__, __LINE__, ##arg); \ + } while (0) -#define info_msg_t(fmt,arg...)\ +#define info_msg_t(fmt, arg...)\ do { \ - fprintf(stderr, MMF_INFO"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ - } while(0) + fprintf(stderr, MMF_INFO"[%s:%05d] " fmt "\n", __func__, __LINE__, ##arg); \ + } while (0) -#define warn_msg_t(fmt,arg...)\ +#define warn_msg_t(fmt, arg...)\ do { \ - fprintf(stderr, MMF_WARN"[%s:%05d] " fmt "\n",__func__, __LINE__, ##arg); \ - } while(0) + fprintf(stderr, MMF_WARN"[%s:%05d] " fmt "\n", __func__, __LINE__, ##arg); \ + } while (0) /*----------------------------------------------------------------------- @@ -119,10 +119,10 @@ unsigned char buf_adts[ADTS_HEADER_SIZE]; #define AMR_NB_MIME_HDR_SIZE 6 #define AMR_WB_MIME_HDR_SIZE 9 -static const char AMRNB_HDR [] = "#!AMR\n"; -static const char AMRWB_HDR [] = "#!AMR-WB\n"; -int write_amrnb_header = 0; /* write magic number for AMR-NB Header at one time */ -int write_amrwb_header = 0; /* write magic number for AMR-WB Header at one time */ +static const char AMRNB_HDR[] = "#!AMR\n"; +static const char AMRWB_HDR[] = "#!AMR-WB\n"; +int write_amrnb_header = 0; /* write magic number for AMR-NB Header at one time */ +int write_amrwb_header = 0; /* write magic number for AMR-WB Header at one time */ #endif bool validate_with_codec = false; @@ -143,9 +143,9 @@ FILE *fp_out_codec_video = NULL; **/ void generate_header_aac_adts(unsigned char *buffer, int packetLen) { - int profile = 2; //AAC LC (0x01) - int freqIdx = 4; //44KHz (0x04) - int chanCfg = 1; //CPE (0x01) + int profile = 2; /* AAC LC (0x01) */ + int freqIdx = 4; /* 44KHz (0x04) */ + int chanCfg = 1; /* CPE (0x01) */ if (samplerate == 96000) freqIdx = 0; else if (samplerate == 88200) freqIdx = 1; @@ -198,9 +198,8 @@ int test_mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) if (fp_audio_out != NULL) { validate_dump = true; fp_video_out = fopen("/opt/usr/dump_video.out", "wb"); - } else { + } else g_print("Error - Cannot open file for file dump, Please chek root\n"); - } #endif ret = mediademuxer_set_data_source(demuxer, path); @@ -225,7 +224,7 @@ int test_mediademuxer_get_track_count() int test_mediademuxer_select_track() { - int track = 0; + int track = 0; g_print("test_mediademuxer_select_track\n"); for (track = 0; track < num_tracks; track++) { if (mediademuxer_select_track(demuxer, track)) { @@ -258,20 +257,19 @@ int test_mediademuxer_get_track_info() for (; track < num_tracks; track++) { if (ret == 0) { g_print("g_media_format[%d] is created successfully! \n", track); - ret = mediademuxer_get_track_info(demuxer, track, - &g_media_format[track]); + ret = mediademuxer_get_track_info(demuxer, track, &g_media_format[track]); if (ret == 0) { if (media_format_get_video_info(g_media_format[track], &v_mime, - &w, &h, NULL, NULL) == MEDIA_FORMAT_ERROR_NONE) { + &w, &h, NULL, NULL) == MEDIA_FORMAT_ERROR_NONE) { g_print("media_format_get_video_info is sucess!\n"); g_print("\t\t[media_format_get_video]mime:%x, width :%d, height :%d\n", - v_mime, w, h); + v_mime, w, h); vid_track = track; } else if (media_format_get_audio_info(g_media_format[track], &a_mime, - &channel, &samplerate, &bit, NULL) == MEDIA_FORMAT_ERROR_NONE) { + &channel, &samplerate, &bit, NULL) == MEDIA_FORMAT_ERROR_NONE) { g_print("media_format_get_audio_info is sucess!\n"); g_print("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d, bit :%d\n", - a_mime, channel, samplerate, bit); + a_mime, channel, samplerate, bit); media_format_get_audio_aac_type(g_media_format[track], &is_adts); aud_track = track; } else { @@ -319,9 +317,8 @@ static void mediacodec_finish(mediacodec_h handle, FILE *fp) return; } err = mediacodec_destroy(handle); - if (err != MEDIACODEC_ERROR_NONE) { + if (err != MEDIACODEC_ERROR_NONE) g_print("mediacodec_destory failed error = %d \n", err); - } return; } @@ -337,11 +334,10 @@ static void _mediacodec_fill_audio_buffer_cb(media_packet_h pkt, void *user_data if (err == MEDIACODEC_ERROR_NONE) { media_packet_get_buffer_size(output_buf, &buf_size); media_packet_get_buffer_data_ptr(output_buf, &data); - if (data != NULL) { + if (data != NULL) fwrite(data, 1, buf_size, fp_out_codec_audio); - } else { + else g_print("Data is null inside _mediacodec_fill_audio_buffer_cb\n"); - } media_packet_destroy(output_buf); } else { @@ -376,7 +372,7 @@ static void mediacodec_init_audio(int codecid, int flag, int samplerate, int cha return; } /* set the audio dec info */ - if ((mediacodec_set_adec_info(g_media_codec, samplerate, channel, bit))!= MEDIACODEC_ERROR_NONE) { + if ((mediacodec_set_adec_info(g_media_codec, samplerate, channel, bit)) != MEDIACODEC_ERROR_NONE) { g_print("mediacodec_set_adec is failed\n"); return; } @@ -395,7 +391,7 @@ static void mediacodec_process_audio_pkt(media_packet_h in_buf) { if (g_media_codec != NULL) { /* process the media packet */ - if (MEDIACODEC_ERROR_NONE != mediacodec_process_input (g_media_codec, in_buf, 0)) { + if (MEDIACODEC_ERROR_NONE != mediacodec_process_input(g_media_codec, in_buf, 0)) { g_print("mediacodec_process_input is failed inside mediacodec_process_audio_pkt\n"); return; } @@ -461,12 +457,12 @@ void *_fetch_audio_data(void *ptr) fwrite(&buf_adts[0], 1, ADTS_HEADER_SIZE, fp_audio_out); } else if ((a_mime == MEDIA_FORMAT_AMR_NB) && (write_amrnb_header == 1)) { /* This is used only AMR-NB case for adding magic header in only first frame */ - g_print("%s - AMRNB_HDR write in first frame\n",__func__); + g_print("%s - AMRNB_HDR write in first frame\n", __func__); fwrite(&AMRNB_HDR[0], 1, sizeof(AMRNB_HDR) - 1, fp_audio_out); write_amrnb_header = 0; } else if ((a_mime == MEDIA_FORMAT_AMR_WB) && (write_amrwb_header == 1)) { /* This is used only AMR-WB case for adding magic header in only first frame */ - g_print("%s - AMRWB_HDR write in first frame\n",__func__); + g_print("%s - AMRWB_HDR write in first frame\n", __func__); fwrite(&AMRWB_HDR[0], 1, sizeof(AMRWB_HDR) - 1, fp_audio_out); write_amrwb_header = 0; } @@ -501,13 +497,12 @@ static void _mediacodec_fill_video_buffer_cb(media_packet_h pkt, void *user_data err = mediacodec_get_output(g_media_codec_1, &output_buf, 0); if (err == MEDIACODEC_ERROR_NONE) { media_packet_get_buffer_size(output_buf, &buf_size); - //g_print("%s - output_buf size = %lld\n",__func__, buf_size); + /* g_print("%s - output_buf size = %lld\n", __func__, buf_size); */ media_packet_get_buffer_data_ptr(output_buf, &data); - if (data != NULL) { + if (data != NULL) fwrite(data, 1, buf_size, fp_out_codec_video); - } else { + else g_print("Data is null inside _mediacodec_fill_video_buffer_cb\n"); - } media_packet_destroy(output_buf); } else { g_print("mediacodec_get_output failed inside _mediacodec_fill_video_buffer_cb lerr = %d\n", err); @@ -560,7 +555,7 @@ static void mediacodec_process_video_pkt(media_packet_h in_buf) { if (g_media_codec_1 != NULL) { /* process the media packet */ - if (MEDIACODEC_ERROR_NONE != mediacodec_process_input (g_media_codec_1, in_buf, 0)) { + if (MEDIACODEC_ERROR_NONE != mediacodec_process_input(g_media_codec_1, in_buf, 0)) { g_print("mediacodec process input is failed inside mediacodec_process_video_pkt\n"); return; } @@ -575,7 +570,7 @@ static void _local_media_packet_get_codec_data(media_packet_h pkt) unsigned char* get_codec_data; unsigned int get_codec_data_size; - if (media_packet_get_codec_data(pkt,(void**) &get_codec_data, &get_codec_data_size) == MEDIA_PACKET_ERROR_NONE) { + if (media_packet_get_codec_data(pkt, (void**) &get_codec_data, &get_codec_data_size) == MEDIA_PACKET_ERROR_NONE) { g_print("media_packet_get_codec_data is sucess ... !\n"); g_print("codec_data_size = %u\n", get_codec_data_size); get_codec_data[get_codec_data_size] = '\0'; @@ -661,11 +656,11 @@ int test_mediademuxer_read_sample() /* Initialize and set thread detached attribute */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if(vid_track != -1){ + if (vid_track != -1) { g_print("In main: creating thread for video\n"); pthread_create(&thread[0], &attr, _fetch_video_data, NULL); } - if(aud_track != -1){ + if (aud_track != -1) { g_print("In main: creating thread for audio\n"); pthread_create(&thread[1], &attr, _fetch_audio_data, NULL); } @@ -728,7 +723,7 @@ int test_mediademuxer_get_state() { g_print("test_mediademuxer_get_state\n"); mediademuxer_state state; - if(mediademuxer_get_state(demuxer, &state) == MEDIADEMUXER_ERROR_NONE) { + if (mediademuxer_get_state(demuxer, &state) == MEDIADEMUXER_ERROR_NONE) { if (state == MEDIADEMUXER_NONE) g_print("Mediademuxer_state = NONE\n"); else if (state == MEDIADEMUXER_IDLE) @@ -739,23 +734,21 @@ int test_mediademuxer_get_state() g_print("Mediademuxer_state = DEMUXING\n"); else g_print("Mediademuxer_state = NOT SUPPORT STATE\n"); - } - else { + } else g_print("Mediademuxer_state call failed\n"); - } return 0; } void app_err_cb(mediademuxer_error_e error, void *user_data) { - printf("Got Error %d from Mediademuxer\n",error); + printf("Got Error %d from Mediademuxer\n", error); } int test_mediademuxer_set_error_cb() { int ret = 0; g_print("test_mediademuxer_set_error_cb\n"); - ret = mediademuxer_set_error_cb(demuxer,app_err_cb,demuxer); + ret = mediademuxer_set_error_cb(demuxer, app_err_cb, demuxer); return ret; } @@ -906,77 +899,73 @@ gboolean timeout_menu_display(void *data) static void interpret(char *cmd) { switch (g_menu_state) { - case CURRENT_STATUS_MAINMENU: { - _interpret_main_menu(cmd); - break; - } - case CURRENT_STATUS_FILENAME: { - int ret = 0; - ret = test_mediademuxer_set_data_source(demuxer, cmd); + case CURRENT_STATUS_MAINMENU: { + _interpret_main_menu(cmd); + break; + } + case CURRENT_STATUS_FILENAME: { + int ret = 0; + ret = test_mediademuxer_set_data_source(demuxer, cmd); + if (ret != MD_ERROR_INVALID_ARGUMENT) { + ret = test_mediademuxer_prepare(); if (ret != MD_ERROR_INVALID_ARGUMENT) { - ret = test_mediademuxer_prepare(); - if (ret != MD_ERROR_INVALID_ARGUMENT) { - g_menu_state = CURRENT_STATUS_SET_DATA; - } else { - g_print("test_mediademuxer_prepare failed \n"); - g_menu_state = CURRENT_STATUS_FILENAME; - } + g_menu_state = CURRENT_STATUS_SET_DATA; } else { + g_print("test_mediademuxer_prepare failed \n"); g_menu_state = CURRENT_STATUS_FILENAME; } - break; + } else { + g_menu_state = CURRENT_STATUS_FILENAME; } - case CURRENT_STATUS_SET_DATA: { - int len = strlen(cmd); - - if (len == 1) { - if (strncmp(cmd, "1", len) == 0) { - test_mediademuxer_get_track_count(); - } else if (strncmp(cmd, "2", len) == 0) { - test_mediademuxer_select_track(); - } else if (strncmp(cmd, "3", len) == 0) { - test_mediademuxer_start(); - } else if (strncmp(cmd, "4", len) == 0) { - test_mediademuxer_get_track_info(); - } else if (strncmp(cmd, "5", len) == 0) { - test_mediademuxer_read_sample(); - } else if (strncmp(cmd, "6", len) == 0) { - test_mediademuxer_stop(); - } else if (strncmp(cmd, "7", len) == 0) { - test_mediademuxer_unprepare(); - } else if (strncmp(cmd, "8", len) == 0) { - test_mediademuxer_get_state(); - } else if (strncmp(cmd, "9", len) == 0) { - reset_menu_state(); - } else if (strncmp(cmd, "a", len) == 0) { - test_mediademuxer_seek_to(); - } else if (strncmp(cmd, "b", len) == 0) { - test_mediademuxer_unselect_track(); - } else if (strncmp(cmd, "c", len) == 0) { - test_mediademuxer_get_sample_track_index(); - } else if (strncmp(cmd, "d", len) == 0) { - test_mediademuxer_get_sample_track_time(); - } else if (strncmp(cmd, "e", len) == 0) { - test_mediademuxer_advance(); - } else if (strncmp(cmd, "f", len) == 0) { - test_mediademuxer_is_key_frame(); - } else if (strncmp(cmd, "g", len) == 0) { - test_mediademuxer_is_encrypted(); - } else { - g_print("UNKNOW COMMAND\n"); - } - } else if (len == 2) { - if (strncmp(cmd, "10", len) == 0) { - g_print("UNKNOW COMMAND\n"); - } else { - g_print("UNKNOW COMMAND\n"); - } - } else { + break; + } + case CURRENT_STATUS_SET_DATA: { + int len = strlen(cmd); + if (len == 1) { + if (strncmp(cmd, "1", len) == 0) + test_mediademuxer_get_track_count(); + else if (strncmp(cmd, "2", len) == 0) + test_mediademuxer_select_track(); + else if (strncmp(cmd, "3", len) == 0) + test_mediademuxer_start(); + else if (strncmp(cmd, "4", len) == 0) + test_mediademuxer_get_track_info(); + else if (strncmp(cmd, "5", len) == 0) + test_mediademuxer_read_sample(); + else if (strncmp(cmd, "6", len) == 0) + test_mediademuxer_stop(); + else if (strncmp(cmd, "7", len) == 0) + test_mediademuxer_unprepare(); + else if (strncmp(cmd, "8", len) == 0) + test_mediademuxer_get_state(); + else if (strncmp(cmd, "9", len) == 0) + reset_menu_state(); + else if (strncmp(cmd, "a", len) == 0) + test_mediademuxer_seek_to(); + else if (strncmp(cmd, "b", len) == 0) + test_mediademuxer_unselect_track(); + else if (strncmp(cmd, "c", len) == 0) + test_mediademuxer_get_sample_track_index(); + else if (strncmp(cmd, "d", len) == 0) + test_mediademuxer_get_sample_track_time(); + else if (strncmp(cmd, "e", len) == 0) + test_mediademuxer_advance(); + else if (strncmp(cmd, "f", len) == 0) + test_mediademuxer_is_key_frame(); + else if (strncmp(cmd, "g", len) == 0) + test_mediademuxer_is_encrypted(); + else g_print("UNKNOW COMMAND\n"); - } - break; - } - default: + } else if (len == 2) { + if (strncmp(cmd, "10", len) == 0) + g_print("UNKNOW COMMAND\n"); + else + g_print("UNKNOW COMMAND\n"); + } else + g_print("UNKNOW COMMAND\n"); + break; + } + default: break; } g_timeout_add(100, timeout_menu_display, 0); -- 2.7.4