From 95ab3ec2ad45e4c70d5c41b0fae734900bf9b86d Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Sat, 24 Oct 2015 16:25:48 +0900 Subject: [PATCH] tizen 2.4 release --- AUTHORS | 6 +- CMakeLists.txt | 18 +- capi-media-player.manifest | 36 +- doc/player_doc.h | 10 + include/mobile/player.h | 1188 ++++++++++++++++++++++------------- include/mobile/player_internal.h | 166 +++++ include/player_private.h | 39 ++ include/wearable/player.h | 1191 +++++++++++++++++++++++------------- include/wearable/player_internal.h | 107 ++++ packaging/capi-media-player.spec | 21 +- src/player.c | 880 ++++++++++++++++++++++---- src/player_internal.c | 173 ++++++ test/CMakeLists.txt | 6 +- test/player_es_push_test.c | 622 +++++++++++++++++++ test/player_media_packet_test.c | 33 +- test/player_test.c | 1126 ++++++++++++++++++++++++++++++---- 16 files changed, 4509 insertions(+), 1113 deletions(-) mode change 100755 => 100644 CMakeLists.txt mode change 100755 => 100644 capi-media-player.manifest mode change 100755 => 100644 include/mobile/player.h create mode 100644 include/mobile/player_internal.h mode change 100755 => 100644 include/player_private.h mode change 100755 => 100644 include/wearable/player.h create mode 100644 include/wearable/player_internal.h mode change 100755 => 100644 packaging/capi-media-player.spec mode change 100755 => 100644 src/player.c create mode 100644 src/player_internal.c mode change 100755 => 100644 test/CMakeLists.txt create mode 100644 test/player_es_push_test.c mode change 100755 => 100644 test/player_media_packet_test.c mode change 100755 => 100644 test/player_test.c diff --git a/AUTHORS b/AUTHORS index b01c60f..2cb3e69 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,4 @@ -Kangho Hur -Seungkeun Lee +Kangho Hur +Seungkeun Lee +Younghwan Ahn +Eunhae Choi diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 17c1c63..af9d354 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ PROJECT(${fw_name}) SET(CMAKE_INSTALL_PREFIX /usr) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) - IF (TIZEN_WEARABLE) SET(INC_DIR include/wearable) ENDIF (TIZEN_WEARABLE) @@ -20,7 +19,7 @@ SET(INC_COM_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}, ${INC_COM_DIR}) -SET(dependents "libtbm capi-media-tool dlog mm-player capi-base-common capi-media-sound-manager gstreamer-0.10 evas ecore elementary capi-system-info") +SET(dependents "libtbm capi-media-tool dlog mm-player capi-base-common capi-media-sound-manager evas ecore elementary ttrace capi-system-info") SET(pc_dependents "libtbm capi-media-tool capi-base-common capi-media-sound-manager") INCLUDE(FindPkgConfig) @@ -29,7 +28,7 @@ FOREACH(flag ${${fw_name}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "-I./${INC_DIR} -I./${INC_COM_DIR} ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -DGST_EXT_TIME_ANALYSIS -D_PLAYER_FOR_PRODUCT") +SET(CMAKE_C_FLAGS "-I./${INC_DIR} ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") IF("${ARCH}" STREQUAL "arm") @@ -38,6 +37,9 @@ ENDIF("${ARCH}" STREQUAL "arm") ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") ADD_DEFINITIONS("-DTIZEN_DEBUG") +IF(TIZEN_TTRACE) +ADD_DEFINITIONS("-DTIZEN_TTRACE") +ENDIF(TIZEN_TTRACE) IF (TIZEN_MOBILE) ADD_DEFINITIONS("-DTIZEN_MOBILE") @@ -45,7 +47,9 @@ ENDIF(TIZEN_MOBILE) SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") -aux_source_directory(src SOURCES) +#aux_source_directory(src SOURCES) +SET(SOURCES src/player.c src/player_internal.c) + ADD_LIBRARY(${fw_name} SHARED ${SOURCES}) TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}) @@ -58,13 +62,13 @@ SET_TARGET_PROPERTIES(${fw_name} ) INSTALL(TARGETS ${fw_name} DESTINATION lib) + INSTALL( DIRECTORY ${INC_DIR}/ DESTINATION include/media FILES_MATCHING PATTERN "*_private.h" EXCLUDE PATTERN "${INC_DIR}/*.h" ) - SET(PC_NAME ${fw_name}) SET(PC_REQUIRED ${pc_dependents}) SET(PC_LDFLAGS -l${fw_name}) @@ -83,10 +87,10 @@ IF(UNIX) ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution) ADD_CUSTOM_COMMAND( - DEPENDS clean + DEPENDS clean COMMENT "distribution clean" COMMAND find - ARGS . + ARGS . -not -name config.cmake -and \( -name tester.c -or -name Testing -or diff --git a/capi-media-player.manifest b/capi-media-player.manifest old mode 100755 new mode 100644 index e3deed8..4aa9a8a --- a/capi-media-player.manifest +++ b/capi-media-player.manifest @@ -1,8 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + diff --git a/doc/player_doc.h b/doc/player_doc.h index 534a2f5..390172b 100755 --- a/doc/player_doc.h +++ b/doc/player_doc.h @@ -298,6 +298,16 @@ * * + * @if WEARABLE + * @section CAPI_MEDIA_PLAYER_MODULE_FEATURE Related Features + * This API is related with the following features: + * - http://tizen.org/feature/network.internet + * + * It is recommended to design feature related codes in your application for reliability. + * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application. + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK. + * More details on featuring your application can be found from Feature Element. + * @endif */ diff --git a/include/mobile/player.h b/include/mobile/player.h old mode 100755 new mode 100644 index a69268d..1cf7930 --- a/include/mobile/player.h +++ b/include/mobile/player.h @@ -133,6 +133,28 @@ typedef enum } audio_latency_mode_e; /** + * @brief Enumeration for stream type. + * @since_tizen 2.4 + */ +typedef enum +{ + PLAYER_STREAM_TYPE_DEFAULT, /**< Container type */ + PLAYER_STREAM_TYPE_AUDIO, /**< Audio element stream type */ + PLAYER_STREAM_TYPE_VIDEO, /**< Video element stream type */ + PLAYER_STREAM_TYPE_TEXT, /**< Text type */ +} player_stream_type_e; + +/** + * @brief Enumeration of media stream buffer status + * @since_tizen 2.4 + */ +typedef enum +{ + PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, + PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, +} player_media_stream_buffer_status_e; + +/** * @brief The player display handle. * @since_tizen 2.3 */ @@ -168,7 +190,7 @@ typedef enum } player_display_rotation_e; /** - * @brief Enumeration for x surface display aspect ratio. + * @brief Enumeration for display mode type. * @since_tizen 2.3 */ typedef enum @@ -332,6 +354,42 @@ typedef void (*player_video_captured_cb)(unsigned char *data, int width, int hei typedef void (*player_media_packet_video_decoded_cb)(media_packet_h pkt, void *user_data); /** + * @brief Called when the buffer level drops below the threshold of max size or no free space in buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @param[in] user_data The user data passed from the callback registration function + * @see player_set_media_stream_buffer_status_cb() + * @see player_set_media_stream_buffer_max_size() + * @see player_set_media_stream_buffer_min_threshold() + */ +typedef void (*player_media_stream_buffer_status_cb) (player_media_stream_buffer_status_e status, void *user_data); + +/** + * @brief Called to notify the next push-buffer offset when seeking is occurred. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @details The next push-buffer should produce buffers from the new offset. + * @param[in] offset The new byte position to seek + * @param[in] user_data The user data passed from the callback registration function + */ +typedef void (*player_media_stream_seek_cb) (unsigned long long offset, void *user_data); + +/** + * @brief Called to notify the video stream changed. + * @since_tizen 2.4 + * @details The video stream changing is detected just before rendering operation. + * @param[in] width The width of the captured image + * @param[in] height The height of the captured image + * @param[in] fps The frame per second of the video \n + It can be @c 0 if there is no video stream information. + * @param[in] bit_rate The video bit rate [Hz] \n + * It can be an invalid value if there is no video stream information. + * @param[in] user_data The user data passed from the callback registration function + * @see player_set_video_stream_changed_cb() + */ +typedef void (*player_video_stream_changed_cb) (int width, int height, int fps, int bit_rate, void *user_data); + +/** * @brief Creates a player handle for playing multimedia content. * @since_tizen 2.3 * @remarks You must release @a player by using player_destroy().\n @@ -396,7 +454,7 @@ int player_prepare(player_h player); * @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 The internet privilege(http://tizen.org/privilege/internet) should be added if any URLs are used to play from network. - * @param[in] player The handle to the media player + * @param[in] player The handle to the media player * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, @@ -461,6 +519,96 @@ int player_unprepare(player_h player); int player_set_uri(player_h player, const char * uri); /** + * @brief Sets the video display. + * @since_tizen 2.3 + * @remarks To get @a display to set, use #GET_DISPLAY(). + * @remarks To use the multiple surface display mode, use player_set_display() again with a different display type. + * @remarks We are not supporting changing display between different types. \n + * If you want to change display handle after calling player_prepare(), you must use the same display type as what you set before. + * @param[in] player The handle to the media player + * @param[in] type The display type + * @param[in] display The handle to display + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_set_display_rotation + */ +int player_set_display(player_h player, player_display_type_e type, player_display_h display); + +/** + * @brief Starts or resumes playback. + * @since_tizen 2.3 + * @details Plays current media content, or resumes play if paused. + * + * @param[in] player The handle to the media player + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_CONNECTION_FAILED Network connection failed + * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error + * @pre player_prepare() must be called before calling this function. + * @pre The player state must be set to #PLAYER_STATE_READY by calling player_prepare() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @post The player state will be #PLAYER_STATE_PLAYING. + * @post It invokes player_completed_cb() when playback completes, if you set a callback with player_set_completed_cb(). + * @post It invokes player_pd_message_cb() when progressive download starts or completes, if you set a download path with player_set_progressive_download_path() and a callback with player_set_progressive_download_message_cb(). + * @see player_prepare() + * @see player_prepare_async() + * @see player_stop() + * @see player_pause() + * @see player_set_completed_cb() + * @see player_completed_cb() + * @see player_set_progressive_download_path() + * @see player_set_progressive_download_message_cb() + * @see player_pd_message_cb() + */ +int player_start(player_h player); + +/** + * @brief Stops playing media content. + * @since_tizen 2.3 + * @param[in] player The handle to the media player + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid state + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @post The player state will be #PLAYER_STATE_READY. + * @post The downloading will be aborted if you use progressive download. + * @see player_start() + * @see player_pause() + */ +int player_stop(player_h player); + +/** + * @brief Pauses the player. + * @since_tizen 2.3 + * @remarks You can resume playback using player_start(). + * + * @param[in] player The handle to the media player + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid state + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error + * @pre The player state must be set to #PLAYER_STATE_PLAYING. + * @post The player state will be #PLAYER_STATE_READY. + * @see player_start() + */ +int player_pause(player_h player); + +/** * @brief Sets memory as the data source. * * @details Associates media content, cached in memory, with the player. Unlike the case of player_set_uri(), the media resides in memory. @@ -587,75 +735,6 @@ int player_set_audio_latency_mode(player_h player, audio_latency_mode_e latency_ int player_get_audio_latency_mode(player_h player, audio_latency_mode_e *latency_mode); /** - * @brief Starts or resumes playback. - * @since_tizen 2.3 - * @details Plays current media content, or resumes play if paused. - * - * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @retval #PLAYER_ERROR_CONNECTION_FAILED Network connection failed - * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error - * @pre player_prepare() must be called before calling this function. - * @pre The player state must be set to #PLAYER_STATE_READY by calling player_prepare() or set to #PLAYER_STATE_PAUSED by calling player_pause(). - * @post The player state will be #PLAYER_STATE_PLAYING. - * @post It invokes player_completed_cb() when playback completes, if you set a callback with player_set_completed_cb(). - * @post It invokes player_pd_message_cb() when progressive download starts or completes, if you set a download path with player_set_progressive_download_path() and a callback with player_set_progressive_download_message_cb(). - * @see player_prepare() - * @see player_prepare_async() - * @see player_stop() - * @see player_pause() - * @see player_set_completed_cb() - * @see player_completed_cb() - * @see player_set_progressive_download_path() - * @see player_set_progressive_download_message_cb() - * @see player_pd_message_cb() - */ -int player_start(player_h player); - -/** - * @brief Stops playing media content. - * @since_tizen 2.3 - * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid state - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). - * @post The player state will be #PLAYER_STATE_READY. - * @post The downloading will be aborted if you use progressive download. - * @see player_start() - * @see player_pause() - */ -int player_stop(player_h player); - -/** - * @brief Pauses the player. - * @since_tizen 2.3 - * @remarks You can resume playback using player_start(). - * - * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid state - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error - * @pre The player state must be set to #PLAYER_STATE_PLAYING. - * @post The player state will be #PLAYER_STATE_READY. - * @see player_start() - */ -int player_pause(player_h player); - -/** * @brief Sets the seek position for playback, asynchronously. * @since_tizen 2.3 * @param[in] player The handle to the media player @@ -768,744 +847,1011 @@ int player_set_looping(player_h player, bool looping); int player_is_looping(player_h player, bool *looping); /** - * @brief Sets the video display. + * @brief Registers a callback function to be invoked when the playback is finished. * @since_tizen 2.3 - * @remarks To get @a display to set, use #GET_DISPLAY(). - * @remarks To use the multiple surface display mode, use player_set_display() again with a different display type. - * @param[in] player The handle to the media player - * @param[in] type The display type - * @param[in] display The handle to display + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_set_display_rotation + * @post player_completed_cb() will be invoked. + * @see player_unset_completed_cb() + * @see player_completed_cb() + * @see player_start() */ -int player_set_display(player_h player, player_display_type_e type, player_display_h display); +int player_set_completed_cb(player_h player, player_completed_cb callback, void *user_data); /** - * @brief Registers a media packet video callback function to be called once per frame. + * @brief Unregisters the callback function. * @since_tizen 2.3 - * @remarks This function should be called before preparing. \n - * A registered callback is called on the internal thread of the player. \n - * A video frame can be retrieved using a registered callback as a media packet.\n - * The callback function holds the same buffer that will be drawn on the display device.\n - * So if you change the media packet in a registerd callback, it will be displayed on the device\n - * and the media packet is available until it's destroyed by media_packet_destroy(). * @param[in] player The handle to the media player - * @param[in] callback The callback function to be registered - * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_STATE Invalid state - * @pre The player's state should be #PLAYER_STATE_IDLE. And, #PLAYER_DISPLAY_TYPE_NONE should be set by calling player_set_display. - * @see player_unset_media_packet_video_frame_decoded_cb + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @see player_set_completed_cb() */ -int player_set_media_packet_video_frame_decoded_cb(player_h player, player_media_packet_video_decoded_cb callback, void *user_data); +int player_unset_completed_cb(player_h player); /** - * @brief Unregisters the callback function. + * @brief Registers a callback function to be invoked when the playback is interrupted or the interrupt is completed. * @since_tizen 2.3 - * @param[in] player The handle to the media player + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @pre The player's state should be #PLAYER_STATE_READY or #PLAYER_STATE_IDLE - * @see player_set_media_packet_video_frame_decoded_cb() - */ -int player_unset_media_packet_video_frame_decoded_cb(player_h player); - -/** - * @} - */ - -/** - * @addtogroup CAPI_MEDIA_PLAYER_DISPLAY_MODULE - * @{ + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @post player_interrupted_cb() will be invoked. + * @see player_unset_interrupted_cb() + * @see #player_interrupted_code_e + * @see player_interrupted_cb() */ +int player_set_interrupted_cb(player_h player, player_interrupted_cb callback, void *user_data); /** - * @brief Sets the video display mode. + * @brief Unregisters the callback function. * @since_tizen 2.3 - * @remarks If no display is set, no operation is performed. - * @param[in] player The handle to the media player - * @param[in] mode The display mode + * @param[in] player The handle to the media player * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_STATE Invalid state - * @pre The player should support display mode changes. - * @see player_get_display_mode() + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @see player_set_interrupted_cb() */ -int player_set_display_mode(player_h player, player_display_mode_e mode); +int player_unset_interrupted_cb(player_h player); /** - * @brief Gets the video display mode. + * @brief Registers a callback function to be invoked when an error occurs. * @since_tizen 2.3 - * @remarks If no display is set, no operation is performed. - * @param[in] player The handle to the media player - * @param[out] mode The current display mode + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @see player_set_display_mode() + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @post player_error_cb() will be invoked. + * @see player_unset_error_cb() + * @see player_error_cb() */ -int player_get_display_mode(player_h player, player_display_mode_e *mode); +int player_set_error_cb(player_h player, player_error_cb callback, void *user_data); /** - * @brief Sets the visibility of the x surface video display + * @brief Unregisters the callback function. * @since_tizen 2.3 - * @param[in] player The handle to the media player - * @param[in] visible The visibility of the display (@c true = visible, @c false = non-visible ) + * @param[in] player The handle to the media player * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_STATE Invalid state - * @see player_is_display_visible() + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @see player_set_error_cb() */ -int player_set_display_visible(player_h player, bool visible); +int player_unset_error_cb(player_h player); /** - * @brief Gets the visibility of the x surface video display. + * @brief Captures the video frame, asynchronously. * @since_tizen 2.3 * @param[in] player The handle to the media player - * @param[out] visible The current visibility of the display (@c true = visible, @c false = non-visible ) + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @see player_set_display_visible() + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * Video type should be set using player_set_display() otherwises, audio stream is only processed even though video file is set. + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @post It invokes player_video_captured_cb() when capture completes, if you set a callback. + * @see player_video_captured_cb() */ -int player_is_display_visible(player_h player, bool* visible); +int player_capture_video(player_h player, player_video_captured_cb callback, void *user_data); /** - * @brief Sets the rotation settings of the video surface display. + * @brief Registers a media packet video callback function to be called once per frame. * @since_tizen 2.3 - * @details Use this function to change the video orientation to portrait mode. - * @param[in] player The handle to the media player - * @param[in] rotation The rotation of the display + * @remarks This function should be called before preparing. \n + * A registered callback is called on the internal thread of the player. \n + * A video frame can be retrieved using a registered callback as a media packet.\n + * The callback function holds the same buffer that will be drawn on the display device.\n + * So if you change the media packet in a registerd callback, it will be displayed on the device\n + * and the media packet is available until it's destroyed by media_packet_destroy(). + * @param[in] player The handle to the media player + * @param[in] callback The callback function to be registered + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid state - * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature - * @see player_set_display - * @see player_get_display_rotation() + * @pre The player's state should be #PLAYER_STATE_IDLE. And, #PLAYER_DISPLAY_TYPE_NONE should be set by calling player_set_display. + * @see player_unset_media_packet_video_frame_decoded_cb */ -int player_set_display_rotation(player_h player, player_display_rotation_e rotation); +int player_set_media_packet_video_frame_decoded_cb(player_h player, player_media_packet_video_decoded_cb callback, void *user_data); /** - * @brief Gets the rotation of the video surface display. + * @brief Unregisters the callback function. * @since_tizen 2.3 * @param[in] player The handle to the media player - * @param[out] rotation The current rotation of the display * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @see player_set_display_rotation() + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The player's state should be #PLAYER_STATE_READY or #PLAYER_STATE_IDLE + * @see player_set_media_packet_video_frame_decoded_cb() */ -int player_get_display_rotation( player_h player, player_display_rotation_e *rotation); +int player_unset_media_packet_video_frame_decoded_cb(player_h player); /** - * @} + * @brief Sets the cookie for streaming playback. + * @since_tizen 2.3 + * @param[in] player The handle to the media player + * @param[in] cookie The cookie to set + * @param[in] size The size of the cookie + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_streaming_user_agent() */ - +int player_set_streaming_cookie(player_h player, const char *cookie, int size); /** - * @addtogroup CAPI_MEDIA_PLAYER_STREAM_INFO_MODULE - * @{ - */ - - /** - * @brief Gets the media content information. + * @brief Sets the streaming user agent for playback. * @since_tizen 2.3 - * @remarks You must release @a value using @c free(). - * @remarks The playback type should be local playback or HTTP streaming playback. - * @param[in] player The handle to the media player - * @param[in] key The key attribute name to get - * @param[out] value The value of the key attribute \n - * It can be an empty string if there is no content information. + * @param[in] player The handle to the media player + * @param[in] user_agent The user agent to set + * @param[in] size The size of the user agent * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_OUT_OF_MEMORY Not enough memory is available + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_streaming_cookie() */ -int player_get_content_info(player_h player, player_content_info_e key, char ** value); +int player_set_streaming_user_agent(player_h player, const char *user_agent, int size); /** - * @brief Gets the audio and video codec information. + * @brief Gets the download progress for streaming playback. * @since_tizen 2.3 - * @remarks You must release @a audio_codec and @a video_codec using free(). - * @remarks The playback type should be local playback or HTTP streaming playback. * @param[in] player The handle to the media player - * @param[out] audio_codec The name of the audio codec \n - * It can be @c NULL if there is no audio codec. - * @param[out] video_codec The name of the video codec \n - * It can be @c NULL if there is no video codec. + * @param[out] start The starting position in percentage [0, 100] + * @param[out] current The current position in percentage [0, 100] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). */ -int player_get_codec_info(player_h player, char **audio_codec, char **video_codec); +int player_get_streaming_download_progress(player_h player, int *start, int *current); /** - * @brief Gets the audio stream information. + * @brief Registers a callback function to be invoked when there is a change in the buffering status of a media stream. * @since_tizen 2.3 - * @remarks The playback type should be local playback or HTTP streaming playback. - * @param[in] player The handle to the media player - * @param[out] sample_rate The audio sample rate [Hz] \n - * Value can be invalid if there is no audio stream information. - * @param[out] channel The audio channel (1: mono, 2: stereo) \n - * Value can be invalid if there is no audio stream information. - * @param[out] bit_rate The audio bit rate [Hz] \n - * Value can be invalid if there is no audio stream information. + * @remarks The media resource should be streamed over the network. + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature + * @post player_buffering_cb() will be invoked. + * @see player_unset_buffering_cb() + * @see player_set_uri() + * @see player_buffering_cb() */ -int player_get_audio_stream_info(player_h player, int *sample_rate, int *channel, int *bit_rate); +int player_set_buffering_cb(player_h player, player_buffering_cb callback, void *user_data); /** - * @brief Gets the video stream information. + * @brief Unregisters the callback function. * @since_tizen 2.3 - * @remarks The playback type should be local playback or HTTP streaming playback. * @param[in] player The handle to the media player - * @param[out] fps The frame per second of the video \n - * It can be @c 0 if there is no video stream information. - * @param[out] bit_rate The video bit rate [Hz] \n - * It can be an invalid value if there is no video stream information. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @see player_set_buffering_cb() */ -int player_get_video_stream_info(player_h player, int *fps, int *bit_rate); +int player_unset_buffering_cb(player_h player); /** - * @brief Gets the video display's height and width. + * @brief Sets a path to download, progressively. * @since_tizen 2.3 - * @remarks The playback type should be local playback or HTTP streaming playback. - * @param[in] player The handle to the media player - * @param[out] width The width of the video \n - * Value can be invalid if there is no video or no display is set. - * @param[out] height The height of the video \n - * Value can be invalid value if there is no video or no display is set. + * @remarks Progressive download will be started when you invoke player_start(). + * @param[in] player The handle to the media player + * @param[in] path The absolute path to download * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_progressive_download_message_cb() + * @see player_unset_progressive_download_message_cb() */ -int player_get_video_size(player_h player, int *width, int *height); +int player_set_progressive_download_path(player_h player, const char *path); /** - * @brief Gets the album art in the media resource. + * @brief Gets the status of progressive download. * @since_tizen 2.3 - * @remarks You must not release @a album_art. It will be released by framework when the player is destroyed. * @param[in] player The handle to the media player - * @param[out] album_art The encoded artwork image - * @param[out] size The encoded artwork size + * @param[out] current The current download position (bytes) + * @param[out] total_size The total size of the file (bytes) * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @pre The progressive download path must be set by calling player_set_progressive_download_path(). + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). */ -int player_get_album_art(player_h player, void **album_art, int *size); +int player_get_progressive_download_status(player_h player, unsigned long *current, unsigned long *total_size); /** - * @brief Gets the total running time of the associated media. + * @brief Registers a callback function to be invoked when progressive download is started or completed. * @since_tizen 2.3 - * @remarks The media source is associated with the player, using either player_set_uri() or player_set_memory_buffer(). - * @remarks The playback type should be local playback or HTTP streaming playback. - * @param[in] player The handle to the media player - * @param[out] duration The duration in milliseconds + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. - * @see player_set_uri() - * @see player_set_memory_buffer() + * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature + * @pre The path to download must be set by calling player_set_progressive_download_path(). + * @post player_pd_message_cb() will be invoked. + * @see player_unset_progressive_download_message_cb() + * @see player_set_progressive_download_path() */ -int player_get_duration(player_h player, int *duration); +int player_set_progressive_download_message_cb(player_h player, player_pd_message_cb callback, void *user_data); /** - * @} + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @param[in] player The handle to the media player + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @see player_set_progressive_download_message_cb() */ +int player_unset_progressive_download_message_cb(player_h player); +/** + * @brief Sets the playback rate. + * @since_tizen 2.3 + * @details The default value is @c 1.0. + * @remarks #PLAYER_ERROR_INVALID_OPERATION occurs when streaming playback. + * @remarks No operation is performed, if @a rate is @c 0. + * @remarks The sound is muted, when playback rate is under @c 0.0 and over @c 2.0. + * @param[in] player The handle to the media player + * @param[in] rate The playback rate (-5.0x ~ 5.0x) + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start(). + * @pre The player state must be set to #PLAYER_STATE_READY by calling player_prepare() or set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + */ +int player_set_playback_rate(player_h player, float rate); /** - * @addtogroup CAPI_MEDIA_PLAYER_AUDIO_EFFECT_MODULE - * @{ + * @brief Registers a callback function to be invoked when video stream is changed. + * @since_tizen 2.4 + * @remarks The stream changing is detected just before rendering operation. + * @param[in] player The handle to the media player + * @param[in] callback The stream changed callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @post player_video_stream_changed_cb() will be invoked. + * @see player_unset_video_stream_changed_cb() + * @see player_video_stream_changed_cb() */ +int player_set_video_stream_changed_cb (player_h player, player_video_stream_changed_cb callback, void *user_data); /** - * @brief Gets the number of equalizer bands. - * @since_tizen 2.3 + * @brief Unregisters the video stream changed callback function. + * @since_tizen 2.4 * @param[in] player The handle to the media player - * @param[out] count The number of equalizer bands + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_video_stream_changed_cb() + */ +int player_unset_video_stream_changed_cb (player_h player); + +/** + * @brief Gets the track count. + * @since_tizen 2.4 + * @remarks PLAYER_STREAM_TYPE_VIDEO is not supported. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[out] count The number of track * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED */ -int player_audio_effect_get_equalizer_bands_count (player_h player, int *count); +int player_get_track_count(player_h player, player_stream_type_e type, int *count); /** - * @brief Sets the gain set for the given equalizer band. - * @since_tizen 2.3 + * @brief Selects a track to play. + * @since_tizen 2.4 + * @remarks PLAYER_STREAM_TYPE_VIDEO is not supported. * @param[in] player The handle to the media player - * @param[in] index The index of the equalizer band to be set - * @param[in] level The new gain in decibel that is set to the given band [dB] + * @param[in] type The type of target stream + * @param[in] index The index of track * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_get_equalizer_bands_count() - * @see player_audio_effect_get_equalizer_level_range() - * @see player_audio_effect_get_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED + * @see player_get_current_track() */ -int player_audio_effect_set_equalizer_band_level(player_h player, int index, int level); +int player_select_track(player_h player, player_stream_type_e type, int index); /** - * @brief Gets the gain set for the given equalizer band. - * @since_tizen 2.3 - * @param[in] player The handle to the media player - * @param[in] index The index of the requested equalizer band - * @param[out] level The gain in decibel of the given band [dB] + * @brief Gets current track index. + * @since_tizen 2.4 + * @details Index starts from 0. + * @remarks PLAYER_STREAM_TYPE_VIDEO is not supported. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[out] index The index of track * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED */ -int player_audio_effect_get_equalizer_band_level(player_h player, int index, int *level); +int player_get_current_track(player_h player, player_stream_type_e type, int *index); /** - * @brief Sets all bands of the equalizer. - * @since_tizen 2.3 + * @brief Gets language code of a track. + * @since_tizen 2.4 + * @remarks @a code must be released with @c free() by caller + * @remarks PLAYER_STREAM_TYPE_VIDEO is not supported. * @param[in] player The handle to the media player - * @param[in] band_levels The list of band levels to be set - * @param[in] length The length of the band level + * @param[in] type The type of target stream + * @param[in] index The index of track + * @param[out] code A language code in ISO 639-1. "und" will be returned if the language is undefined. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_get_equalizer_bands_count() - * @see player_audio_effect_get_equalizer_level_range() - * @see player_audio_effect_set_equalizer_band_level() + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED */ -int player_audio_effect_set_equalizer_all_bands(player_h player, int *band_levels, int length); +int player_get_track_language_code(player_h player, player_stream_type_e type, int index, char **code); /** - * @brief Gets the valid band level range of the equalizer. - * @since_tizen 2.3 + * @brief Pushes elementary stream to decode audio or video + * @since_tizen 2.4 + * @remarks player_set_media_stream_info() should be called before using this API. + * @param[in] player The handle to media player + * @param[in] packet The media packet to decode + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @retval #PLAYER_ERROR_NOT_SUPPORTED_FILE File not supported + * @pre The player state must be set to #PLAYER_STATE_IDLE at least. + * @see player_set_media_stream_info() + */ +int player_push_media_stream(player_h player, media_packet_h packet); + +/** + * @brief Sets contents information for media stream + * @since_tizen 2.4 + * @remarks AV format should be set before pushing elementary stream with player_push_media_stream(). + * @remarks AAC can be supported. + * @remarks H.264 can be supported. + * @remarks This API should be called before calling the player_prepare() or player_prepare_async() \n + to reflect the media information when pipeline is created. + * @param[in] player The handle to media player + * @param[in] type The type of target stream + * @param[in] format The media format to set audio information + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_push_media_stream() + */ +int player_set_media_stream_info(player_h player, player_stream_type_e type, media_format_h format); + +/** + * @brief Registers a callback function to be invoked when buffer underrun or overflow is occurred. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[in] callback The buffer status callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @post player_media_stream_buffer_status_cb() will be invoked. + * @see player_unset_media_stream_buffer_status_cb() + * @see player_media_stream_buffer_status_cb() + */ +int player_set_media_stream_buffer_status_cb(player_h player, player_stream_type_e type, player_media_stream_buffer_status_cb callback, void *user_data); + +/** + * @brief Unregisters the buffer status callback function. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. * @param[in] player The handle to the media player - * @param[out] min The minimum value to be set [dB] - * @param[out] max The maximum value to be set [dB] + * @param[in] type The type of target stream * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_media_stream_buffer_status_cb() + */ +int player_unset_media_stream_buffer_status_cb(player_h player, player_stream_type_e type); + +/** + * @brief Registers a callback function to be invoked when seeking is occurred. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @post player_media_stream_seek_cb() will be invoked. + * @see player_unset_media_stream_seek_cb() + * @see player_media_stream_seek_cb() */ -int player_audio_effect_get_equalizer_level_range(player_h player, int* min, int* max); +int player_set_media_stream_seek_cb(player_h player, player_stream_type_e type, player_media_stream_seek_cb callback, void *user_data); /** - * @brief Gets the band frequency of the equalizer. - * @since_tizen 2.3 + * @brief Unregisters the seek callback function. + * @since_tizen 2.4 * @param[in] player The handle to the media player - * @param[in] index The index of the requested equalizer band - * @param[out] frequency The frequency of the given band [dB] + * @param[in] type The type of target stream + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_media_stream_seek_cb() + */ +int player_unset_media_stream_seek_cb(player_h player, player_stream_type_e type); + +/** + * @brief Sets the max size bytes of buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @remarks If the buffer level over the max size, player_media_stream_buffer_status_cb() will be invoked with overflow status. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[in] max_size The max bytes of buffer * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_get_media_stream_buffer_max_size() + * @see player_media_stream_buffer_status_cb() */ -int player_audio_effect_get_equalizer_band_frequency(player_h player, int index, int *frequency); +int player_set_media_stream_buffer_max_size(player_h player, player_stream_type_e type, unsigned long long max_size); /** - * @brief Gets the band frequency range of the equalizer. - * @since_tizen 2.3 + * @brief Gets the max size bytes of buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @remarks If the buffer level over the max size, player_media_stream_buffer_status_cb() will be invoked with overflow status. * @param[in] player The handle to the media player - * @param[in] index The index of the requested equalizer band - * @param[out] range The frequency range of the given band [dB] + * @param[in] type The type of target stream + * @param[out] max_size The max bytes of buffer * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_media_stream_buffer_max_size() + * @see player_media_stream_buffer_status_cb() */ -int player_audio_effect_get_equalizer_band_frequency_range(player_h player, int index, int *range); +int player_get_media_stream_buffer_max_size(player_h player, player_stream_type_e type, unsigned long long *max_size); /** - * @brief Clears the equalizer effect. - * @since_tizen 2.3 + * @brief Sets the buffer threshold percent of buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @remarks If the buffer level drops below the percent value, player_media_stream_buffer_status_cb() will be invoked with underrun status. * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[in] percent The minimum threshold(0~100) of buffer + * @return @c 0 on success, + * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_get_media_stream_buffer_min_threshold() + * @see player_media_stream_buffer_status_cb() */ -int player_audio_effect_equalizer_clear(player_h player); +int player_set_media_stream_buffer_min_threshold(player_h player, player_stream_type_e type, unsigned int percent); /** - * @brief Checks whether the custom equalizer effect is available. - * @since_tizen 2.3 + * @brief Gets the buffer threshold percent of buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @remarks If the buffer level drops below the percent value, player_media_stream_buffer_status_cb() will be invoked with underrun status. * @param[in] player The handle to the media player - * @param[out] available If @c true the specified audio effect is available, - * otherwise @c false + * @param[in] type The type of target stream + * @param[out] percent The minimum threshold(0~100) of buffer + * @return @c 0 on success, + * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_media_stream_buffer_min_threshold() + * @see player_media_stream_buffer_status_cb() */ -int player_audio_effect_equalizer_is_available(player_h player, bool *available); +int player_get_media_stream_buffer_min_threshold(player_h player, player_stream_type_e type, unsigned int *percent); + /** * @} */ - /** - * @addtogroup CAPI_MEDIA_PLAYER_MODULE + * @addtogroup CAPI_MEDIA_PLAYER_DISPLAY_MODULE * @{ */ /** - * @brief Captures the video frame, asynchronously. + * @brief Sets the video display mode. + * @since_tizen 2.3 + * @remarks If no display is set, no operation is performed. + * @param[in] player The handle to the media player + * @param[in] mode The display mode + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @pre The player should support display mode changes. + * @see player_get_display_mode() + */ +int player_set_display_mode(player_h player, player_display_mode_e mode); + +/** + * @brief Gets the video display mode. * @since_tizen 2.3 + * @remarks If no display is set, no operation is performed. * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[out] mode The current display mode + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_display_mode() + */ +int player_get_display_mode(player_h player, player_display_mode_e *mode); + +/** + * @brief Sets the visibility of the x surface video display + * @since_tizen 2.3 + * @param[in] player The handle to the media player + * @param[in] visible The visibility of the display (@c true = visible, @c false = non-visible ) * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * Video type should be set using player_set_display() otherwises, audio stream is only processed even though video file is set. - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). - * @post It invokes player_video_captured_cb() when capture completes, if you set a callback. - * @see player_video_captured_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @see player_is_display_visible() */ -int player_capture_video(player_h player, player_video_captured_cb callback, void *user_data); +int player_set_display_visible(player_h player, bool visible); /** - * @brief Sets the cookie for streaming playback. + * @brief Gets the visibility of the x surface video display. * @since_tizen 2.3 * @param[in] player The handle to the media player - * @param[in] cookie The cookie to set - * @param[in] size The size of the cookie + * @param[out] visible The current visibility of the display (@c true = visible, @c false = non-visible ) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_display_visible() + */ +int player_is_display_visible(player_h player, bool* visible); + +/** + * @brief Sets the rotation settings of the video surface display. + * @since_tizen 2.3 + * @details Use this function to change the video orientation to portrait mode. + * @param[in] player The handle to the media player + * @param[in] rotation The rotation of the display + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature + * @see player_set_display + * @see player_get_display_rotation() + */ +int player_set_display_rotation(player_h player, player_display_rotation_e rotation); + +/** + * @brief Gets the rotation of the video surface display. + * @since_tizen 2.3 + * @param[in] player The handle to the media player + * @param[out] rotation The current rotation of the display + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_display_rotation() + */ +int player_get_display_rotation( player_h player, player_display_rotation_e *rotation); + +/** + * @} + */ + + +/** + * @addtogroup CAPI_MEDIA_PLAYER_STREAM_INFO_MODULE + * @{ + */ + + /** + * @brief Gets the media content information. + * @since_tizen 2.3 + * @remarks You must release @a value using @c free(). + * @remarks The playback type should be local playback or HTTP streaming playback. + * @param[in] player The handle to the media player + * @param[in] key The key attribute name to get + * @param[out] value The value of the key attribute \n + * It can be an empty string if there is no content information. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_OUT_OF_MEMORY Not enough memory is available * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). - * @see player_set_streaming_user_agent() + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_set_streaming_cookie(player_h player, const char *cookie, int size); +int player_get_content_info(player_h player, player_content_info_e key, char ** value); /** - * @brief Sets the streaming user agent for playback. + * @brief Gets the audio and video codec information. * @since_tizen 2.3 + * @remarks You must release @a audio_codec and @a video_codec using free(). + * @remarks The playback type should be local playback or HTTP streaming playback. + * @remarks If RTSP case, this information is available after posting #MM_MESSAGE_BEGIN_OF_STREAM. * @param[in] player The handle to the media player - * @param[in] user_agent The user agent to set - * @param[in] size The size of the user agent + * @param[out] audio_codec The name of the audio codec \n + * It can be @c NULL if there is no audio codec. + * @param[out] video_codec The name of the video codec \n + * It can be @c NULL if there is no video codec. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). - * @see player_set_streaming_cookie() + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_set_streaming_user_agent(player_h player, const char *user_agent, int size); +int player_get_codec_info(player_h player, char **audio_codec, char **video_codec); /** - * @brief Gets the download progress for streaming playback. + * @brief Gets the audio stream information. * @since_tizen 2.3 + * @remarks The playback type should be local playback or HTTP streaming playback. + * @remarks If RTSP case, this information is available after posting #MM_MESSAGE_BEGIN_OF_STREAM. * @param[in] player The handle to the media player - * @param[out] start The starting position in percentage [0, 100] - * @param[out] current The current position in percentage [0, 100] + * @param[out] sample_rate The audio sample rate [Hz] \n + * Value can be invalid if there is no audio stream information. + * @param[out] channel The audio channel (1: mono, 2: stereo) \n + * Value can be invalid if there is no audio stream information. + * @param[out] bit_rate The audio bit rate [Hz] \n + * Value can be invalid if there is no audio stream information. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_get_streaming_download_progress(player_h player, int *start, int *current); +int player_get_audio_stream_info(player_h player, int *sample_rate, int *channel, int *bit_rate); /** - * @brief Registers a callback function to be invoked when the playback is finished. + * @brief Gets the album art in the media resource. * @since_tizen 2.3 - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @remarks You must not release @a album_art. It will be released by framework when the player is destroyed. + * @param[in] player The handle to the media player + * @param[out] album_art The encoded artwork image + * @param[out] size The encoded artwork size * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @post player_completed_cb() will be invoked. - * @see player_unset_completed_cb() - * @see player_completed_cb() - * @see player_start() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_set_completed_cb(player_h player, player_completed_cb callback, void *user_data); +int player_get_album_art(player_h player, void **album_art, int *size); /** - * @brief Unregisters the callback function. + * @brief Gets the video stream information. * @since_tizen 2.3 + * @remarks The playback type should be local playback or HTTP streaming playback. + * @remarks If RTSP case, this information is available after posting #MM_MESSAGE_BEGIN_OF_STREAM. * @param[in] player The handle to the media player + * @param[out] fps The frame per second of the video \n + * It can be @c 0 if there is no video stream information. + * @param[out] bit_rate The video bit rate [Hz] \n + * It can be an invalid value if there is no video stream information. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_completed_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_unset_completed_cb(player_h player); +int player_get_video_stream_info(player_h player, int *fps, int *bit_rate); /** - * @brief Registers a callback function to be invoked when the playback is interrupted or the interrupt is completed. + * @brief Gets the video display's height and width. * @since_tizen 2.3 - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @remarks The playback type should be local playback or HTTP streaming playback. + * @remarks If RTSP case, this information is available after posting #MM_MESSAGE_BEGIN_OF_STREAM. + * @param[in] player The handle to the media player + * @param[out] width The width of the video \n + * Value can be invalid if there is no video or no display is set. + * @param[out] height The height of the video \n + * Value can be invalid value if there is no video or no display is set. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @post player_interrupted_cb() will be invoked. - * @see player_unset_interrupted_cb() - * @see #player_interrupted_code_e - * @see player_interrupted_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_set_interrupted_cb(player_h player, player_interrupted_cb callback, void *user_data); +int player_get_video_size(player_h player, int *width, int *height); /** - * @brief Unregisters the callback function. + * @brief Gets the total running time of the associated media. * @since_tizen 2.3 - * @param[in] player The handle to the media player + * @remarks The media source is associated with the player, using either player_set_uri() or player_set_memory_buffer(). + * @remarks The playback type should be local playback or HTTP streaming playback. + * @param[in] player The handle to the media player + * @param[out] duration The duration in milliseconds * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_interrupted_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @see player_set_uri() + * @see player_set_memory_buffer() */ -int player_unset_interrupted_cb(player_h player); +int player_get_duration(player_h player, int *duration); /** - * @brief Registers a callback function to be invoked when an error occurs. + * @} + */ + + +/** + * @addtogroup CAPI_MEDIA_PLAYER_AUDIO_EFFECT_MODULE + * @{ + */ + +/** + * @brief Gets the number of equalizer bands. * @since_tizen 2.3 - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[in] player The handle to the media player + * @param[out] count The number of equalizer bands * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @post player_error_cb() will be invoked. - * @see player_unset_error_cb() - * @see player_error_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_set_error_cb(player_h player, player_error_cb callback, void *user_data); +int player_audio_effect_get_equalizer_bands_count (player_h player, int *count); /** - * @brief Unregisters the callback function. + * @brief Sets the gain set for the given equalizer band. * @since_tizen 2.3 * @param[in] player The handle to the media player + * @param[in] index The index of the equalizer band to be set + * @param[in] level The new gain in decibel that is set to the given band [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_error_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_get_equalizer_bands_count() + * @see player_audio_effect_get_equalizer_level_range() + * @see player_audio_effect_get_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_unset_error_cb(player_h player); +int player_audio_effect_set_equalizer_band_level(player_h player, int index, int level); /** - * @brief Registers a callback function to be invoked when there is a change in the buffering status of a media stream. + * @brief Gets the gain set for the given equalizer band. * @since_tizen 2.3 - * @remarks The media resource should be streamed over the network. - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[in] player The handle to the media player + * @param[in] index The index of the requested equalizer band + * @param[out] level The gain in decibel of the given band [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature - * @post player_buffering_cb() will be invoked. - * @see player_unset_buffering_cb() - * @see player_set_uri() - * @see player_buffering_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() */ -int player_set_buffering_cb(player_h player, player_buffering_cb callback, void *user_data); +int player_audio_effect_get_equalizer_band_level(player_h player, int index, int *level); /** - * @brief Unregisters the callback function. + * @brief Sets all bands of the equalizer. * @since_tizen 2.3 * @param[in] player The handle to the media player + * @param[in] band_levels The list of band levels to be set + * @param[in] length The length of the band level * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_buffering_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_get_equalizer_bands_count() + * @see player_audio_effect_get_equalizer_level_range() + * @see player_audio_effect_set_equalizer_band_level() */ -int player_unset_buffering_cb(player_h player); +int player_audio_effect_set_equalizer_all_bands(player_h player, int *band_levels, int length); /** - * @brief Sets a path to download, progressively. + * @brief Gets the valid band level range of the equalizer. * @since_tizen 2.3 - * @remarks Progressive download will be started when you invoke player_start(). - * @param[in] player The handle to the media player - * @param[in] path The absolute path to download + * @param[in] player The handle to the media player + * @param[out] min The minimum value to be set [dB] + * @param[out] max The maximum value to be set [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature - * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). - * @see player_set_progressive_download_message_cb() - * @see player_unset_progressive_download_message_cb() + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_set_progressive_download_path(player_h player, const char *path); +int player_audio_effect_get_equalizer_level_range(player_h player, int* min, int* max); /** - * @brief Gets the status of progressive download. + * @brief Gets the band frequency of the equalizer. * @since_tizen 2.3 * @param[in] player The handle to the media player - * @param[out] current The current download position (bytes) - * @param[out] total_size The total size of the file (bytes) + * @param[in] index The index of the requested equalizer band + * @param[out] frequency The frequency of the given band [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The progressive download path must be set by calling player_set_progressive_download_path(). - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. */ -int player_get_progressive_download_status(player_h player, unsigned long *current, unsigned long *total_size); +int player_audio_effect_get_equalizer_band_frequency(player_h player, int index, int *frequency); /** - * @brief Registers a callback function to be invoked when progressive download is started or completed. + * @brief Gets the band frequency range of the equalizer. * @since_tizen 2.3 - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[in] player The handle to the media player + * @param[in] index The index of the requested equalizer band + * @param[out] range The frequency range of the given band [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature - * @pre The path to download must be set by calling player_set_progressive_download_path(). - * @post player_pd_message_cb() will be invoked. - * @see player_unset_progressive_download_message_cb() - * @see player_set_progressive_download_path() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. */ -int player_set_progressive_download_message_cb(player_h player, player_pd_message_cb callback, void *user_data); +int player_audio_effect_get_equalizer_band_frequency_range(player_h player, int index, int *range); /** - * @brief Unregisters the callback function. + * @brief Clears the equalizer effect. * @since_tizen 2.3 * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_progressive_download_message_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_unset_progressive_download_message_cb(player_h player); +int player_audio_effect_equalizer_clear(player_h player); /** - * @brief Sets the playback rate. + * @brief Checks whether the custom equalizer effect is available. * @since_tizen 2.3 - * @details The default value is @c 1.0. - * @remarks #PLAYER_ERROR_INVALID_OPERATION occurs when streaming playback. - * @remarks No operation is performed, if @a rate is @c 0. - * @remarks The sound is muted, when playback rate is under @c 0.0 and over @c 2.0. - * @param[in] player The handle to the media player - * @param[in] rate The playback rate (-5.0x ~ 5.0x) - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @param[in] player The handle to the media player + * @param[out] available If @c true the specified audio effect is available, + * otherwise @c false + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start(). - * @pre The player state must be set to #PLAYER_STATE_READY by calling player_prepare() or set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_set_playback_rate(player_h player, float rate); +int player_audio_effect_equalizer_is_available(player_h player, bool *available); /** * @} diff --git a/include/mobile/player_internal.h b/include/mobile/player_internal.h new file mode 100644 index 0000000..c2f59aa --- /dev/null +++ b/include/mobile/player_internal.h @@ -0,0 +1,166 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __TIZEN_MEDIA_PLAYER_INTERNAL_H__ +#define __TIZEN_MEDIA_PLAYER_INTERNAL_H__ +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file player_internal.h + */ + +/** + * @addtogroup CAPI_MEDIA_PLAYER_MODULE + * @{ + */ + +/** + * @brief This file contains the media player API for custom features. + * @since_tizen 2.4 + */ +typedef struct +{ + void *data; /**< PCM data */ + int size; /**< Data Size */ + int channel; /**< Channel */ + int rate; /**< Samplerate */ + int depth; /**< Depth */ + bool little_endian; /**< Endianness */ + unsigned long long channel_mask; /**< channel_mask */ +} player_audio_raw_data_s; + +/** + * @brief Called when the media player needs updated xid. + * @remarks If the current display type is not #PLAYER_DISPLAY_TYPE_X11, no operation is performed. + * @param[in] user_data The user data passed from the callback registration function + * @param[in] video_width The width of the video + * @param[in] video_height The height of the video + * @pre It will be invoked when player needs updated xid if you register this callback using player_set_x11_display_pixmap() + * @return The updated xid + * @see player_set_x11_display_pixmap() + */ +typedef unsigned int (*player_x11_pixmap_updated_cb)(void *user_data, unsigned int video_width, unsigned int video_height); + +/** + * @brief Called when the media player needs to inform rendering error. + * @remarks If the current display type is not #PLAYER_DISPLAY_TYPE_X11, no operation is performed. + * @param[in] pixmap_id The pixmap_id where the rendering error is occurred + * @param[in] user_data The user data passed from the callback registration function + * @see player_set_x11_display_pixmap_error_cb() + */ +typedef void (*player_x11_pixmap_error_cb)(unsigned int *pixmap_id, void *user_data); + +/** + * @internal + * @brief Registers a callback function to be invoked when player need updated xid. + * @since_tizen 2.3 + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be either #PLAYER_STATE_IDLE by player_create() or #PLAYER_STATE_READY by player_prepare(). + * @post player_set_x11_display_pixmap() will be invoked + * @see player_set_x11_display_pixmap() + */ +int player_set_x11_display_pixmap (player_h player, player_x11_pixmap_updated_cb callback, void *user_data); + +/** + * @internal + * @brief Registers a callback function to be invoked when failure of rendering video frame happen. + * @since_tizen 2.3 + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be either #PLAYER_STATE_IDLE by player_create() or #PLAYER_STATE_READY by player_prepare(). + * @post player_set_x11_display_pixmap_error_cb() will be invoked + * @see player_set_x11_display_pixmap_error_cb() + */ +int player_set_x11_display_pixmap_error_cb (player_h player, player_x11_pixmap_error_cb callback, void *user_data); + +/** + * @brief Called when the audio frame is decoded. + * @since_tizen 2.4 + * @param[in] audio_raw_frame The decoded audio frame data type + * @param[in] user_data The user data passed from the callback registration function + * @see player_set_audio_frame_decoded_cb() + * @see player_unset_audio_frame_decoded_cb() + */ +typedef void (*player_audio_pcm_extraction_cb)(player_audio_raw_data_s *audio_raw_frame, void *user_data); + + +/** + * @brief Registers a callback function to be invoked when audio frame is decoded. Audio only contents is possible. If included video, error happens. + * @since_tizen 2.4 + * @param[in] player The handle to the media player + * @param[in] sync Sync on the clock + * @param[in] format Audio format of output pcm + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be #PLAYER_STATE_IDLE by player_create() or player_unprepare(). + * @post player_audio_pcm_extraction_cb() will be invoked. + * @see player_unset_audio_frame_decoded_cb_ex() + */ +int player_set_pcm_extraction_mode(player_h player, bool sync, player_audio_pcm_extraction_cb callback, void *user_data); + +/** + * @brief Set pcm mode spec. Samplerate, channel is needed. + * @since_tizen 2.4 + * @param[in] player The handle to the media player + * @param[in] samplerate Samplerate + * @param[in] channel Channel + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be #PLAYER_STATE_IDLE by player_create() or player_unprepare(). + * @see player_set_pcm_extraction_mode() + */ +int player_set_pcm_spec(player_h player, const char *format, int samplerate, int channel); +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif //__TIZEN_MEDIA_PLAYER_PRODUCT_H__ + + diff --git a/include/player_private.h b/include/player_private.h old mode 100755 new mode 100644 index b87277a..ab3be67 --- a/include/player_private.h +++ b/include/player_private.h @@ -28,6 +28,7 @@ extern "C" { #undef LOG_TAG #endif #define LOG_TAG "TIZEN_N_PLAYER" +//#define USE_ECORE_FUNCTIONS #define PLAYER_CHECK_CONDITION(condition,error,msg) \ if(condition) {} else \ @@ -46,6 +47,18 @@ extern "C" { PLAYER_CHECK_CONDITION(arg <= max,PLAYER_ERROR_INVALID_PARAMETER,"PLAYER_ERROR_INVALID_PARAMETER") \ PLAYER_CHECK_CONDITION(arg >= min,PLAYER_ERROR_INVALID_PARAMETER,"PLAYER_ERROR_INVALID_PARAMETER") +#ifdef TIZEN_TTRACE +#include +#define PLAYER_TRACE_BEGIN(NAME) traceBegin(TTRACE_TAG_VIDEO, NAME) +#define PLAYER_TRACE_END() traceEnd(TTRACE_TAG_VIDEO) +#define PLAYER_TRACE_ASYNC_BEGIN(NAME, COOKIE) traceAsyncBegin (TTRACE_TAG_VIDEO, COOKIE, NAME); +#define PLAYER_TRACE_ASYNC_END(NAME, COOKIE) traceAsyncEnd(TTRACE_TAG_VIDEO, COOKIE, NAME); +#else +#define PLAYER_TRACE_BEGIN(NAME) +#define PLAYER_TRACE_END() +#define PLAYER_TRACE_ASYNC_BEGIN(NAME, KEY) +#define PLAYER_TRACE_ASYNC_END(NAME, KEY) +#endif typedef enum { _PLAYER_EVENT_TYPE_PREPARE, @@ -67,9 +80,27 @@ typedef enum { _PLAYER_EVENT_TYPE_IMAGE_BUFFER, _PLAYER_EVENT_TYPE_SELECTED_SUBTITLE_LANGUAGE, #endif + _PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS, + _PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS, + _PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK, + _PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK, + _PLAYER_EVENT_TYPE_AUDIO_STREAM_CHANGED, + _PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED, _PLAYER_EVENT_TYPE_NUM }_player_event_e; +#ifndef USE_ECORE_FUNCTIONS +typedef enum { + PLAYER_MESSAGE_NONE, + PLAYER_MESSAGE_PREPARED, + PLAYER_MESSAGE_ERROR, + PLAYER_MESSAGE_SEEK_DONE, + PLAYER_MESSAGE_EOS, + PLAYER_MESSAGE_LOOP_EXIT, + PLAYER_MESSAGE_MAX +}_player_message_e; +#endif + typedef struct _player_s{ MMHandleType mm_handle; const void* user_cb[_PLAYER_EVENT_TYPE_NUM]; @@ -82,7 +113,15 @@ typedef struct _player_s{ bool is_display_visible; bool is_progressive_download; pthread_t prepare_async_thread; +#ifdef USE_ECORE_FUNCTIONS GHashTable *ecore_jobs; +#else + pthread_t message_thread; + GQueue *message_queue; + GMutex message_queue_lock; + GCond message_queue_cond; + int current_message; +#endif player_error_e error_code; bool is_doing_jobs; media_format_h pkt_fmt; diff --git a/include/wearable/player.h b/include/wearable/player.h old mode 100755 new mode 100644 index 0bc3f35..44f9263 --- a/include/wearable/player.h +++ b/include/wearable/player.h @@ -132,6 +132,28 @@ typedef enum } audio_latency_mode_e; /** + * @brief Enumeration for stream type. + * @since_tizen 2.4 + */ +typedef enum +{ + PLAYER_STREAM_TYPE_DEFAULT, /**< Container type */ + PLAYER_STREAM_TYPE_AUDIO, /**< Audio element stream type */ + PLAYER_STREAM_TYPE_VIDEO, /**< Video element stream type */ + PLAYER_STREAM_TYPE_TEXT, /**< Text type */ +} player_stream_type_e; + +/** + * @brief Enumeration of media stream buffer status + * @since_tizen 2.4 + */ +typedef enum +{ + PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, + PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, +} player_media_stream_buffer_status_e; + +/** * @brief The player display handle. * @since_tizen 2.3.1 */ @@ -167,7 +189,7 @@ typedef enum } player_display_rotation_e; /** - * @brief Enumeration for x surface display aspect ratio. + * @brief Enumeration for display mode type. * @since_tizen 2.3.1 */ typedef enum @@ -331,6 +353,42 @@ typedef void (*player_video_captured_cb)(unsigned char *data, int width, int hei typedef void (*player_media_packet_video_decoded_cb)(media_packet_h pkt, void *user_data); /** + * @brief Called when the buffer level drops below the threshold of max size or no free space in buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @param[in] user_data The user data passed from the callback registration function + * @see player_set_media_stream_buffer_status_cb() + * @see player_set_media_stream_buffer_max_size() + * @see player_set_media_stream_buffer_min_threshold() + */ +typedef void (*player_media_stream_buffer_status_cb) (player_media_stream_buffer_status_e status, void *user_data); + +/** + * @brief Called to notify the next push-buffer offset when seeking is occurred. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @details The next push-buffer should produce buffers from the new offset. + * @param[in] offset The new byte position to seek + * @param[in] user_data The user data passed from the callback registration function + */ +typedef void (*player_media_stream_seek_cb) (unsigned long long offset, void *user_data); + +/** + * @brief Called to notify the video stream changed. + * @since_tizen 2.4 + * @details The video stream changing is detected just before rendering operation. + * @param[in] width The width of the captured image + * @param[in] height The height of the captured image + * @param[in] fps The frame per second of the video \n + It can be @c 0 if there is no video stream information. + * @param[in] bit_rate The video bit rate [Hz] \n + * It can be an invalid value if there is no video stream information. + * @param[in] user_data The user data passed from the callback registration function + * @see player_set_video_stream_changed_cb() + */ +typedef void (*player_video_stream_changed_cb) (int width, int height, int fps, int bit_rate, void *user_data); + +/** * @brief Creates a player handle for playing multimedia content. * @since_tizen 2.3.1 * @remarks You must release @a player by using player_destroy().\n @@ -460,6 +518,96 @@ int player_unprepare(player_h player); int player_set_uri(player_h player, const char * uri); /** + * @brief Sets the video display. + * @since_tizen 2.3.1 + * @remarks To get @a display to set, use #GET_DISPLAY(). + * @remarks To use the multiple surface display mode, use player_set_display() again with a different display type. + * @remarks We are not supporting changing display between different types. \n + * If you want to change display handle after calling player_prepare(), you must use the same display type as what you set before. + * @param[in] player The handle to the media player + * @param[in] type The display type + * @param[in] display The handle to display + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_set_display_rotation + */ +int player_set_display(player_h player, player_display_type_e type, player_display_h display); + +/** + * @brief Starts or resumes playback. + * @since_tizen 2.3.1 + * @details Plays current media content, or resumes play if paused. + * + * @param[in] player The handle to the media player + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_CONNECTION_FAILED Network connection failed + * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error + * @pre player_prepare() must be called before calling this function. + * @pre The player state must be set to #PLAYER_STATE_READY by calling player_prepare() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @post The player state will be #PLAYER_STATE_PLAYING. + * @post It invokes player_completed_cb() when playback completes, if you set a callback with player_set_completed_cb(). + * @post It invokes player_pd_message_cb() when progressive download starts or completes, if you set a download path with player_set_progressive_download_path() and a callback with player_set_progressive_download_message_cb(). + * @see player_prepare() + * @see player_prepare_async() + * @see player_stop() + * @see player_pause() + * @see player_set_completed_cb() + * @see player_completed_cb() + * @see player_set_progressive_download_path() + * @see player_set_progressive_download_message_cb() + * @see player_pd_message_cb() + */ +int player_start(player_h player); + +/** + * @brief Stops playing media content. + * @since_tizen 2.3.1 + * @param[in] player The handle to the media player + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid state + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @post The player state will be #PLAYER_STATE_READY. + * @post The downloading will be aborted if you use progressive download. + * @see player_start() + * @see player_pause() + */ +int player_stop(player_h player); + +/** + * @brief Pauses the player. + * @since_tizen 2.3.1 + * @remarks You can resume playback using player_start(). + * + * @param[in] player The handle to the media player + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid state + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error + * @pre The player state must be set to #PLAYER_STATE_PLAYING. + * @post The player state will be #PLAYER_STATE_READY. + * @see player_start() + */ +int player_pause(player_h player); + +/** * @brief Sets memory as the data source. * * @details Associates media content, cached in memory, with the player. Unlike the case of player_set_uri(), the media resides in memory. @@ -586,75 +734,6 @@ int player_set_audio_latency_mode(player_h player, audio_latency_mode_e latency_ int player_get_audio_latency_mode(player_h player, audio_latency_mode_e *latency_mode); /** - * @brief Starts or resumes playback. - * @since_tizen 2.3.1 - * @details Plays current media content, or resumes play if paused. - * - * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @retval #PLAYER_ERROR_CONNECTION_FAILED Network connection failed - * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error - * @pre player_prepare() must be called before calling this function. - * @pre The player state must be set to #PLAYER_STATE_READY by calling player_prepare() or set to #PLAYER_STATE_PAUSED by calling player_pause(). - * @post The player state will be #PLAYER_STATE_PLAYING. - * @post It invokes player_completed_cb() when playback completes, if you set a callback with player_set_completed_cb(). - * @post It invokes player_pd_message_cb() when progressive download starts or completes, if you set a download path with player_set_progressive_download_path() and a callback with player_set_progressive_download_message_cb(). - * @see player_prepare() - * @see player_prepare_async() - * @see player_stop() - * @see player_pause() - * @see player_set_completed_cb() - * @see player_completed_cb() - * @see player_set_progressive_download_path() - * @see player_set_progressive_download_message_cb() - * @see player_pd_message_cb() - */ -int player_start(player_h player); - -/** - * @brief Stops playing media content. - * @since_tizen 2.3.1 - * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid state - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). - * @post The player state will be #PLAYER_STATE_READY. - * @post The downloading will be aborted if you use progressive download. - * @see player_start() - * @see player_pause() - */ -int player_stop(player_h player); - -/** - * @brief Pauses the player. - * @since_tizen 2.3.1 - * @remarks You can resume playback using player_start(). - * - * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid state - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @retval #PLAYER_ERROR_SOUND_POLICY Sound policy error - * @pre The player state must be set to #PLAYER_STATE_PLAYING. - * @post The player state will be #PLAYER_STATE_READY. - * @see player_start() - */ -int player_pause(player_h player); - -/** * @brief Sets the seek position for playback, asynchronously. * @since_tizen 2.3.1 * @param[in] player The handle to the media player @@ -767,744 +846,1010 @@ int player_set_looping(player_h player, bool looping); int player_is_looping(player_h player, bool *looping); /** - * @brief Sets the video display. + * @brief Registers a callback function to be invoked when the playback is finished. * @since_tizen 2.3.1 - * @remarks To get @a display to set, use #GET_DISPLAY(). - * @remarks To use the multiple surface display mode, use player_set_display() again with a different display type. - * @param[in] player The handle to the media player - * @param[in] type The display type - * @param[in] display The handle to display + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_set_display_rotation + * @post player_completed_cb() will be invoked. + * @see player_unset_completed_cb() + * @see player_completed_cb() + * @see player_start() */ -int player_set_display(player_h player, player_display_type_e type, player_display_h display); +int player_set_completed_cb(player_h player, player_completed_cb callback, void *user_data); /** - * @brief Registers a media packet video callback function to be called once per frame. + * @brief Unregisters the callback function. * @since_tizen 2.3.1 - * @remarks This function should be called before preparing. \n - * A registered callback is called on the internal thread of the player. \n - * A video frame can be retrieved using a registered callback as a media packet.\n - * The callback function holds the same buffer that will be drawn on the display device.\n - * So if you change the media packet in a registerd callback, it will be displayed on the device\n - * and the media packet is available until it's destroyed by media_packet_destroy(). * @param[in] player The handle to the media player - * @param[in] callback The callback function to be registered - * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_STATE Invalid state - * @pre The player's state should be #PLAYER_STATE_IDLE. And, #PLAYER_DISPLAY_TYPE_NONE should be set by calling player_set_display. - * @see player_unset_media_packet_video_frame_decoded_cb + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @see player_set_completed_cb() */ -int player_set_media_packet_video_frame_decoded_cb(player_h player, player_media_packet_video_decoded_cb callback, void *user_data); +int player_unset_completed_cb(player_h player); /** - * @brief Unregisters the callback function. + * @brief Registers a callback function to be invoked when the playback is interrupted or the interrupt is completed. * @since_tizen 2.3.1 - * @param[in] player The handle to the media player + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @pre The player's state should be #PLAYER_STATE_READY or #PLAYER_STATE_IDLE - * @see player_set_media_packet_video_frame_decoded_cb() - */ -int player_unset_media_packet_video_frame_decoded_cb(player_h player); - -/** - * @} - */ - -/** - * @addtogroup CAPI_MEDIA_PLAYER_DISPLAY_MODULE - * @{ + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @post player_interrupted_cb() will be invoked. + * @see player_unset_interrupted_cb() + * @see #player_interrupted_code_e + * @see player_interrupted_cb() */ +int player_set_interrupted_cb(player_h player, player_interrupted_cb callback, void *user_data); /** - * @brief Sets the video display mode. + * @brief Unregisters the callback function. * @since_tizen 2.3.1 - * @remarks If no display is set, no operation is performed. - * @param[in] player The handle to the media player - * @param[in] mode The display mode + * @param[in] player The handle to the media player * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_STATE Invalid state - * @pre The player should support display mode changes. - * @see player_get_display_mode() + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @see player_set_interrupted_cb() */ -int player_set_display_mode(player_h player, player_display_mode_e mode); +int player_unset_interrupted_cb(player_h player); /** - * @brief Gets the video display mode. + * @brief Registers a callback function to be invoked when an error occurs. * @since_tizen 2.3.1 - * @remarks If no display is set, no operation is performed. - * @param[in] player The handle to the media player - * @param[out] mode The current display mode + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @see player_set_display_mode() + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @post player_error_cb() will be invoked. + * @see player_unset_error_cb() + * @see player_error_cb() */ -int player_get_display_mode(player_h player, player_display_mode_e *mode); +int player_set_error_cb(player_h player, player_error_cb callback, void *user_data); /** - * @brief Sets the visibility of the x surface video display + * @brief Unregisters the callback function. * @since_tizen 2.3.1 - * @param[in] player The handle to the media player - * @param[in] visible The visibility of the display (@c true = visible, @c false = non-visible ) + * @param[in] player The handle to the media player * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_STATE Invalid state - * @see player_is_display_visible() + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @see player_set_error_cb() */ -int player_set_display_visible(player_h player, bool visible); +int player_unset_error_cb(player_h player); /** - * @brief Gets the visibility of the x surface video display. + * @brief Captures the video frame, asynchronously. * @since_tizen 2.3.1 * @param[in] player The handle to the media player - * @param[out] visible The current visibility of the display (@c true = visible, @c false = non-visible ) + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @see player_set_display_visible() + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * Video type should be set using player_set_display() otherwises, audio stream is only processed even though video file is set. + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @post It invokes player_video_captured_cb() when capture completes, if you set a callback. + * @see player_video_captured_cb() */ -int player_is_display_visible(player_h player, bool* visible); +int player_set_display(player_h player, player_display_type_e type, player_display_h display); /** - * @brief Sets the rotation settings of the video surface display. + * @brief Registers a media packet video callback function to be called once per frame. * @since_tizen 2.3.1 - * @details Use this function to change the video orientation to portrait mode. - * @param[in] player The handle to the media player - * @param[in] rotation The rotation of the display + * @remarks This function should be called before preparing. \n + * A registered callback is called on the internal thread of the player. \n + * A video frame can be retrieved using a registered callback as a media packet.\n + * The callback function holds the same buffer that will be drawn on the display device.\n + * So if you change the media packet in a registerd callback, it will be displayed on the device\n + * and the media packet is available until it's destroyed by media_packet_destroy(). + * @param[in] player The handle to the media player + * @param[in] callback The callback function to be registered + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid state - * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature - * @see player_set_display - * @see player_get_display_rotation() + * @pre The player's state should be #PLAYER_STATE_IDLE. And, #PLAYER_DISPLAY_TYPE_NONE should be set by calling player_set_display. + * @see player_unset_media_packet_video_frame_decoded_cb */ -int player_set_display_rotation(player_h player, player_display_rotation_e rotation); +int player_set_media_packet_video_frame_decoded_cb(player_h player, player_media_packet_video_decoded_cb callback, void *user_data); /** - * @brief Gets the rotation of the video surface display. + * @brief Unregisters the callback function. * @since_tizen 2.3.1 * @param[in] player The handle to the media player - * @param[out] rotation The current rotation of the display * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @see player_set_display_rotation() + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The player's state should be #PLAYER_STATE_READY or #PLAYER_STATE_IDLE + * @see player_set_media_packet_video_frame_decoded_cb() */ -int player_get_display_rotation( player_h player, player_display_rotation_e *rotation); +int player_unset_media_packet_video_frame_decoded_cb(player_h player); /** - * @} + * @brief Sets the cookie for streaming playback. + * @since_tizen 2.3.1 + * @param[in] player The handle to the media player + * @param[in] cookie The cookie to set + * @param[in] size The size of the cookie + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_streaming_user_agent() */ - +int player_set_streaming_cookie(player_h player, const char *cookie, int size); /** - * @addtogroup CAPI_MEDIA_PLAYER_STREAM_INFO_MODULE - * @{ - */ - - /** - * @brief Gets the media content information. + * @brief Sets the streaming user agent for playback. * @since_tizen 2.3.1 - * @remarks You must release @a value using @c free(). - * @remarks The playback type should be local playback or HTTP streaming playback. - * @param[in] player The handle to the media player - * @param[in] key The key attribute name to get - * @param[out] value The value of the key attribute \n - * It can be an empty string if there is no content information. + * @param[in] player The handle to the media player + * @param[in] user_agent The user agent to set + * @param[in] size The size of the user agent * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_OUT_OF_MEMORY Not enough memory is available + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_streaming_cookie() */ -int player_get_content_info(player_h player, player_content_info_e key, char ** value); +int player_set_streaming_user_agent(player_h player, const char *user_agent, int size); /** - * @brief Gets the audio and video codec information. + * @brief Gets the download progress for streaming playback. * @since_tizen 2.3.1 - * @remarks You must release @a audio_codec and @a video_codec using free(). - * @remarks The playback type should be local playback or HTTP streaming playback. * @param[in] player The handle to the media player - * @param[out] audio_codec The name of the audio codec \n - * It can be @c NULL if there is no audio codec. - * @param[out] video_codec The name of the video codec \n - * It can be @c NULL if there is no video codec. + * @param[out] start The starting position in percentage [0, 100] + * @param[out] current The current position in percentage [0, 100] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). */ -int player_get_codec_info(player_h player, char **audio_codec, char **video_codec); +int player_get_streaming_download_progress(player_h player, int *start, int *current); /** - * @brief Gets the audio stream information. + * @brief Registers a callback function to be invoked when there is a change in the buffering status of a media stream. * @since_tizen 2.3.1 - * @remarks The playback type should be local playback or HTTP streaming playback. - * @param[in] player The handle to the media player - * @param[out] sample_rate The audio sample rate [Hz] \n - * Value can be invalid if there is no audio stream information. - * @param[out] channel The audio channel (1: mono, 2: stereo) \n - * Value can be invalid if there is no audio stream information. - * @param[out] bit_rate The audio bit rate [Hz] \n - * Value can be invalid if there is no audio stream information. + * @remarks The media resource should be streamed over the network. + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature + * @post player_buffering_cb() will be invoked. + * @see player_unset_buffering_cb() + * @see player_set_uri() + * @see player_buffering_cb() */ -int player_get_audio_stream_info(player_h player, int *sample_rate, int *channel, int *bit_rate); +int player_set_buffering_cb(player_h player, player_buffering_cb callback, void *user_data); /** - * @brief Gets the video stream information. + * @brief Unregisters the callback function. * @since_tizen 2.3.1 - * @remarks The playback type should be local playback or HTTP streaming playback. * @param[in] player The handle to the media player - * @param[out] fps The frame per second of the video \n - * It can be @c 0 if there is no video stream information. - * @param[out] bit_rate The video bit rate [Hz] \n - * It can be an invalid value if there is no video stream information. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @see player_set_buffering_cb() */ -int player_get_video_stream_info(player_h player, int *fps, int *bit_rate); +int player_unset_buffering_cb(player_h player); /** - * @brief Gets the video display's height and width. + * @brief Sets a path to download, progressively. * @since_tizen 2.3.1 - * @remarks The playback type should be local playback or HTTP streaming playback. - * @param[in] player The handle to the media player - * @param[out] width The width of the video \n - * Value can be invalid if there is no video or no display is set. - * @param[out] height The height of the video \n - * Value can be invalid value if there is no video or no display is set. + * @remarks Progressive download will be started when you invoke player_start(). + * @param[in] player The handle to the media player + * @param[in] path The absolute path to download * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_progressive_download_message_cb() + * @see player_unset_progressive_download_message_cb() */ -int player_get_video_size(player_h player, int *width, int *height); +int player_set_progressive_download_path(player_h player, const char *path); /** - * @brief Gets the album art in the media resource. + * @brief Gets the status of progressive download. * @since_tizen 2.3.1 - * @remarks You must not release @a album_art. It will be released by framework when the player is destroyed. * @param[in] player The handle to the media player - * @param[out] album_art The encoded artwork image - * @param[out] size The encoded artwork size + * @param[out] current The current download position (bytes) + * @param[out] total_size The total size of the file (bytes) * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @pre The progressive download path must be set by calling player_set_progressive_download_path(). + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). */ -int player_get_album_art(player_h player, void **album_art, int *size); +int player_get_progressive_download_status(player_h player, unsigned long *current, unsigned long *total_size); /** - * @brief Gets the total running time of the associated media. + * @brief Registers a callback function to be invoked when progressive download is started or completed. * @since_tizen 2.3.1 - * @remarks The media source is associated with the player, using either player_set_uri() or player_set_memory_buffer(). - * @remarks The playback type should be local playback or HTTP streaming playback. - * @param[in] player The handle to the media player - * @param[out] duration The duration in milliseconds + * @param[in] player The handle to the media player + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. - * @see player_set_uri() - * @see player_set_memory_buffer() + * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature + * @pre The path to download must be set by calling player_set_progressive_download_path(). + * @post player_pd_message_cb() will be invoked. + * @see player_unset_progressive_download_message_cb() + * @see player_set_progressive_download_path() */ -int player_get_duration(player_h player, int *duration); +int player_set_progressive_download_message_cb(player_h player, player_pd_message_cb callback, void *user_data); /** - * @} + * @brief Unregisters the callback function. + * @since_tizen 2.3.1 + * @param[in] player The handle to the media player + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @see player_set_progressive_download_message_cb() */ +int player_unset_progressive_download_message_cb(player_h player); +/** + * @brief Sets the playback rate. + * @since_tizen 2.3.1 + * @details The default value is @c 1.0. + * @remarks #PLAYER_ERROR_INVALID_OPERATION occurs when streaming playback. + * @remarks No operation is performed, if @a rate is @c 0. + * @remarks The sound is muted, when playback rate is under @c 0.0 and over @c 2.0. + * @param[in] player The handle to the media player + * @param[in] rate The playback rate (-5.0x ~ 5.0x) + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start(). + * @pre The player state must be set to #PLAYER_STATE_READY by calling player_prepare() or set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + */ +int player_set_playback_rate(player_h player, float rate); /** - * @addtogroup CAPI_MEDIA_PLAYER_AUDIO_EFFECT_MODULE - * @{ + * @brief Registers a callback function to be invoked when video stream is changed. + * @since_tizen 2.4 + * @remarks The stream changing is detected just before rendering operation. + * @param[in] player The handle to the media player + * @param[in] callback The stream changed callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @post player_video_stream_changed_cb() will be invoked. + * @see player_unset_video_stream_changed_cb() + * @see player_video_stream_changed_cb() */ +int player_set_video_stream_changed_cb (player_h player, player_video_stream_changed_cb callback, void *user_data); /** - * @brief Gets the number of equalizer bands. - * @since_tizen 2.3.1 + * @brief Unregisters the video stream changed callback function. + * @since_tizen 2.4 * @param[in] player The handle to the media player - * @param[out] count The number of equalizer bands + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_video_stream_changed_cb() + */ +int player_unset_video_stream_changed_cb (player_h player); + +/** + * @brief Gets the track count. + * @since_tizen 2.4 + * @remarks PLAYER_STREAM_TYPE_VIDEO is not supported. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[out] count The number of track * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED */ -int player_audio_effect_get_equalizer_bands_count (player_h player, int *count); +int player_get_track_count(player_h player, player_stream_type_e type, int *count); /** - * @brief Sets the gain set for the given equalizer band. - * @since_tizen 2.3.1 + * @brief Selects a track to play. + * @since_tizen 2.4 + * @remarks PLAYER_STREAM_TYPE_VIDEO is not supported. * @param[in] player The handle to the media player - * @param[in] index The index of the equalizer band to be set - * @param[in] level The new gain in decibel that is set to the given band [dB] + * @param[in] type The type of target stream + * @param[in] index The index of track * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_get_equalizer_bands_count() - * @see player_audio_effect_get_equalizer_level_range() - * @see player_audio_effect_get_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED + * @see player_get_current_track() */ -int player_audio_effect_set_equalizer_band_level(player_h player, int index, int level); +int player_select_track(player_h player, player_stream_type_e type, int index); /** - * @brief Gets the gain set for the given equalizer band. - * @since_tizen 2.3.1 - * @param[in] player The handle to the media player - * @param[in] index The index of the requested equalizer band - * @param[out] level The gain in decibel of the given band [dB] + * @brief Gets current track index. + * @since_tizen 2.4 + * @details Index starts from 0. + * @remarks PLAYER_STREAM_TYPE_VIDEO is not supported. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[out] index The index of track * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED */ -int player_audio_effect_get_equalizer_band_level(player_h player, int index, int *level); +int player_get_current_track(player_h player, player_stream_type_e type, int *index); /** - * @brief Sets all bands of the equalizer. - * @since_tizen 2.3.1 + * @brief Gets language code of a track. + * @since_tizen 2.4 + * @remarks @a code must be released with @c free() by caller + * @remarks PLAYER_STREAM_TYPE_VIDEO is not supported. * @param[in] player The handle to the media player - * @param[in] band_levels The list of band levels to be set - * @param[in] length The length of the band level + * @param[in] type The type of target stream + * @param[in] index The index of track + * @param[out] code A language code in ISO 639-1. "und" will be returned if the language is undefined. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_get_equalizer_bands_count() - * @see player_audio_effect_get_equalizer_level_range() - * @see player_audio_effect_set_equalizer_band_level() + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED */ -int player_audio_effect_set_equalizer_all_bands(player_h player, int *band_levels, int length); +int player_get_track_language_code(player_h player, player_stream_type_e type, int index, char **code); /** - * @brief Gets the valid band level range of the equalizer. - * @since_tizen 2.3.1 + * @brief Pushes elementary stream to decode audio or video + * @since_tizen 2.4 + * @remarks player_set_media_stream_info() should be called before using this API. + * @param[in] player The handle to media player + * @param[in] packet The media packet to decode + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @retval #PLAYER_ERROR_NOT_SUPPORTED_FILE File not supported + * @pre The player state must be set to #PLAYER_STATE_IDLE at least. + * @see player_set_media_stream_info() + */ +int player_push_media_stream(player_h player, media_packet_h packet); + +/** + * @brief Sets contents information for media stream + * @since_tizen 2.4 + * @remarks AV format should be set before pushing elementary stream with player_push_media_stream(). + * @remarks AAC can be supported. + * @remarks H.264 can be supported. + * @remarks This API should be called before calling the player_prepare() or player_prepare_async() \n + to reflect the media information when pipeline is created. + * @param[in] player The handle to media player + * @param[in] type The type of target stream + * @param[in] format The media format to set audio information + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_push_media_stream() + */ +int player_set_media_stream_info(player_h player, player_stream_type_e type, media_format_h format); + +/** + * @brief Registers a callback function to be invoked when buffer underrun or overflow is occurred. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[in] callback The buffer status callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @post player_media_stream_buffer_status_cb() will be invoked. + * @see player_unset_media_stream_buffer_status_cb() + * @see player_media_stream_buffer_status_cb() + */ +int player_set_media_stream_buffer_status_cb(player_h player, player_stream_type_e type, player_media_stream_buffer_status_cb callback, void *user_data); + +/** + * @brief Unregisters the buffer status callback function. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. * @param[in] player The handle to the media player - * @param[out] min The minimum value to be set [dB] - * @param[out] max The maximum value to be set [dB] + * @param[in] type The type of target stream * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_media_stream_buffer_status_cb() + */ +int player_unset_media_stream_buffer_status_cb(player_h player, player_stream_type_e type); + +/** + * @brief Registers a callback function to be invoked when seeking is occurred. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @post player_media_stream_seek_cb() will be invoked. + * @see player_unset_media_stream_seek_cb() + * @see player_media_stream_seek_cb() */ -int player_audio_effect_get_equalizer_level_range(player_h player, int* min, int* max); +int player_set_media_stream_seek_cb(player_h player, player_stream_type_e type, player_media_stream_seek_cb callback, void *user_data); /** - * @brief Gets the band frequency of the equalizer. - * @since_tizen 2.3.1 + * @brief Unregisters the seek callback function. + * @since_tizen 2.4 * @param[in] player The handle to the media player - * @param[in] index The index of the requested equalizer band - * @param[out] frequency The frequency of the given band [dB] + * @param[in] type The type of target stream + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_media_stream_seek_cb() + */ +int player_unset_media_stream_seek_cb(player_h player, player_stream_type_e type); + +/** + * @brief Sets the max size bytes of buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @remarks If the buffer level over the max size, player_media_stream_buffer_status_cb() will be invoked with overflow status. + * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[in] max_size The max bytes of buffer * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_get_media_stream_buffer_max_size() + * @see player_media_stream_buffer_status_cb() */ -int player_audio_effect_get_equalizer_band_frequency(player_h player, int index, int *frequency); +int player_set_media_stream_buffer_max_size(player_h player, player_stream_type_e type, unsigned long long max_size); /** - * @brief Gets the band frequency range of the equalizer. - * @since_tizen 2.3.1 + * @brief Gets the max size bytes of buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @remarks If the buffer level over the max size, player_media_stream_buffer_status_cb() will be invoked with overflow status. * @param[in] player The handle to the media player - * @param[in] index The index of the requested equalizer band - * @param[out] range The frequency range of the given band [dB] + * @param[in] type The type of target stream + * @param[out] max_size The max bytes of buffer * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_media_stream_buffer_max_size() + * @see player_media_stream_buffer_status_cb() */ -int player_audio_effect_get_equalizer_band_frequency_range(player_h player, int index, int *range); +int player_get_media_stream_buffer_max_size(player_h player, player_stream_type_e type, unsigned long long *max_size); /** - * @brief Clears the equalizer effect. - * @since_tizen 2.3.1 + * @brief Sets the buffer threshold percent of buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @remarks If the buffer level drops below the percent value, player_media_stream_buffer_status_cb() will be invoked with underrun status. * @param[in] player The handle to the media player + * @param[in] type The type of target stream + * @param[in] percent The minimum threshold(0~100) of buffer + * @return @c 0 on success, + * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_get_media_stream_buffer_min_threshold() + * @see player_media_stream_buffer_status_cb() */ -int player_audio_effect_equalizer_clear(player_h player); +int player_set_media_stream_buffer_min_threshold(player_h player, player_stream_type_e type, unsigned int percent); /** - * @brief Checks whether the custom equalizer effect is available. - * @since_tizen 2.3.1 + * @brief Gets the buffer threshold percent of buffer. + * @since_tizen 2.4 + * @remarks This API is used for media stream playback only. + * @remarks If the buffer level drops below the percent value, player_media_stream_buffer_status_cb() will be invoked with underrun status. * @param[in] player The handle to the media player - * @param[out] available If @c true the specified audio effect is available, - * otherwise @c false + * @param[in] type The type of target stream + * @param[out] percent The minimum threshold(0~100) of buffer + * @return @c 0 on success, + * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_audio_effect_set_equalizer_band_level() - * @see player_audio_effect_set_equalizer_all_bands() + * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). + * @see player_set_media_stream_buffer_min_threshold() + * @see player_media_stream_buffer_status_cb() */ -int player_audio_effect_equalizer_is_available(player_h player, bool *available); +int player_get_media_stream_buffer_min_threshold(player_h player, player_stream_type_e type, unsigned int *percent); /** * @} */ - /** - * @addtogroup CAPI_MEDIA_PLAYER_MODULE + * @addtogroup CAPI_MEDIA_PLAYER_DISPLAY_MODULE * @{ */ /** - * @brief Captures the video frame, asynchronously. + * @brief Sets the video display mode. * @since_tizen 2.3.1 + * @remarks If no display is set, no operation is performed. + * @param[in] player The handle to the media player + * @param[in] mode The display mode + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @pre The player should support display mode changes. + * @see player_get_display_mode() + */ +int player_set_display_mode(player_h player, player_display_mode_e mode); + +/** + * @brief Gets the video display mode. + * @since_tizen 2.3.1 + * @remarks If no display is set, no operation is performed. * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[out] mode The current display mode + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_display_mode() + */ +int player_get_display_mode(player_h player, player_display_mode_e *mode); + +/** + * @brief Sets the visibility of the x surface video display + * @since_tizen 2.3.1 + * @param[in] player The handle to the media player + * @param[in] visible The visibility of the display (@c true = visible, @c false = non-visible ) * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @see player_is_display_visible() + */ +int player_set_display_visible(player_h player, bool visible); + +/** + * @brief Gets the visibility of the x surface video display. + * @since_tizen 2.3.1 + * @param[in] player The handle to the media player + * @param[out] visible The current visibility of the display (@c true = visible, @c false = non-visible ) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_display_visible() + */ +int player_is_display_visible(player_h player, bool* visible); + +/** + * @brief Sets the rotation settings of the video surface display. + * @since_tizen 2.3.1 + * @details Use this function to change the video orientation to portrait mode. + * @param[in] player The handle to the media player + * @param[in] rotation The rotation of the display + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature + * @see player_set_display + * @see player_get_display_rotation() + */ +int player_set_display_rotation(player_h player, player_display_rotation_e rotation); + +/** + * @brief Gets the rotation of the video surface display. + * @since_tizen 2.3.1 + * @param[in] player The handle to the media player + * @param[out] rotation The current rotation of the display + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @see player_set_display_rotation() + */ +int player_get_display_rotation( player_h player, player_display_rotation_e *rotation); + +/** + * @} + */ + + +/** + * @addtogroup CAPI_MEDIA_PLAYER_STREAM_INFO_MODULE + * @{ + */ + + /** + * @brief Gets the media content information. + * @since_tizen 2.3.1 + * @remarks You must release @a value using @c free(). + * @remarks The playback type should be local playback or HTTP streaming playback. + * @param[in] player The handle to the media player + * @param[in] key The key attribute name to get + * @param[out] value The value of the key attribute \n + * It can be an empty string if there is no content information. + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_OUT_OF_MEMORY Not enough memory is available * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * Video type should be set using player_set_display() otherwises, audio stream is only processed even though video file is set. * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). - * @post It invokes player_video_captured_cb() when capture completes, if you set a callback. - * @see player_video_captured_cb() + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_capture_video(player_h player, player_video_captured_cb callback, void *user_data); +int player_get_content_info(player_h player, player_content_info_e key, char ** value); /** - * @brief Sets the cookie for streaming playback. + * @brief Gets the audio and video codec information. * @since_tizen 2.3.1 + * @remarks You must release @a audio_codec and @a video_codec using free(). + * @remarks The playback type should be local playback or HTTP streaming playback. + * @remarks If RTSP case, this information is available after posting #MM_MESSAGE_BEGIN_OF_STREAM. * @param[in] player The handle to the media player - * @param[in] cookie The cookie to set - * @param[in] size The size of the cookie + * @param[out] audio_codec The name of the audio codec \n + * It can be @c NULL if there is no audio codec. + * @param[out] video_codec The name of the video codec \n + * It can be @c NULL if there is no video codec. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). - * @see player_set_streaming_user_agent() + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_set_streaming_cookie(player_h player, const char *cookie, int size); +int player_get_codec_info(player_h player, char **audio_codec, char **video_codec); /** - * @brief Sets the streaming user agent for playback. + * @brief Gets the audio stream information. * @since_tizen 2.3.1 + * @remarks The playback type should be local playback or HTTP streaming playback. + * @remarks If RTSP case, this information is available after posting #MM_MESSAGE_BEGIN_OF_STREAM. * @param[in] player The handle to the media player - * @param[in] user_agent The user agent to set - * @param[in] size The size of the user agent + * @param[out] sample_rate The audio sample rate [Hz] \n + * Value can be invalid if there is no audio stream information. + * @param[out] channel The audio channel (1: mono, 2: stereo) \n + * Value can be invalid if there is no audio stream information. + * @param[out] bit_rate The audio bit rate [Hz] \n + * Value can be invalid if there is no audio stream information. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). - * @see player_set_streaming_cookie() + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_set_streaming_user_agent(player_h player, const char *user_agent, int size); +int player_get_audio_stream_info(player_h player, int *sample_rate, int *channel, int *bit_rate); /** - * @brief Gets the download progress for streaming playback. + * @brief Gets the album art in the media resource. * @since_tizen 2.3.1 + * @remarks You must not release @a album_art. It will be released by framework when the player is destroyed. * @param[in] player The handle to the media player - * @param[out] start The starting position in percentage [0, 100] - * @param[out] current The current position in percentage [0, 100] + * @param[out] album_art The encoded artwork image + * @param[out] size The encoded artwork size * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_get_streaming_download_progress(player_h player, int *start, int *current); +int player_get_album_art(player_h player, void **album_art, int *size); /** - * @brief Registers a callback function to be invoked when the playback is finished. + * @brief Gets the video stream information. * @since_tizen 2.3.1 - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @remarks The playback type should be local playback or HTTP streaming playback. + * @remarks If RTSP case, this information is available after posting #MM_MESSAGE_BEGIN_OF_STREAM. + * @param[in] player The handle to the media player + * @param[out] fps The frame per second of the video \n + * It can be @c 0 if there is no video stream information. + * @param[out] bit_rate The video bit rate [Hz] \n + * It can be an invalid value if there is no video stream information. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @post player_completed_cb() will be invoked. - * @see player_unset_completed_cb() - * @see player_completed_cb() - * @see player_start() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_set_completed_cb(player_h player, player_completed_cb callback, void *user_data); +int player_get_video_stream_info(player_h player, int *fps, int *bit_rate); /** - * @brief Unregisters the callback function. + * @brief Gets the video display's height and width. * @since_tizen 2.3.1 + * @remarks The playback type should be local playback or HTTP streaming playback. + * @remarks If RTSP case, this information is available after posting #MM_MESSAGE_BEGIN_OF_STREAM. * @param[in] player The handle to the media player + * @param[out] width The width of the video \n + * Value can be invalid if there is no video or no display is set. + * @param[out] height The height of the video \n + * Value can be invalid value if there is no video or no display is set. * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_completed_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. */ -int player_unset_completed_cb(player_h player); +int player_get_video_size(player_h player, int *width, int *height); /** - * @brief Registers a callback function to be invoked when the playback is interrupted or the interrupt is completed. + * @brief Gets the total running time of the associated media. * @since_tizen 2.3.1 - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @remarks The media source is associated with the player, using either player_set_uri() or player_set_memory_buffer(). + * @remarks The playback type should be local playback or HTTP streaming playback. + * @param[in] player The handle to the media player + * @param[out] duration The duration in milliseconds * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @post player_interrupted_cb() will be invoked. - * @see player_unset_interrupted_cb() - * @see #player_interrupted_code_e - * @see player_interrupted_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @see player_set_uri() + * @see player_set_memory_buffer() */ -int player_set_interrupted_cb(player_h player, player_interrupted_cb callback, void *user_data); +int player_get_duration(player_h player, int *duration); /** - * @brief Unregisters the callback function. - * @since_tizen 2.3.1 - * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_interrupted_cb() + * @} */ -int player_unset_interrupted_cb(player_h player); + /** - * @brief Registers a callback function to be invoked when an error occurs. + * @addtogroup CAPI_MEDIA_PLAYER_AUDIO_EFFECT_MODULE + * @{ + */ + +/** + * @brief Gets the number of equalizer bands. * @since_tizen 2.3.1 - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[in] player The handle to the media player + * @param[out] count The number of equalizer bands * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @post player_error_cb() will be invoked. - * @see player_unset_error_cb() - * @see player_error_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_set_error_cb(player_h player, player_error_cb callback, void *user_data); +int player_audio_effect_get_equalizer_bands_count (player_h player, int *count); /** - * @brief Unregisters the callback function. + * @brief Sets the gain set for the given equalizer band. * @since_tizen 2.3.1 * @param[in] player The handle to the media player + * @param[in] index The index of the equalizer band to be set + * @param[in] level The new gain in decibel that is set to the given band [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_error_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_get_equalizer_bands_count() + * @see player_audio_effect_get_equalizer_level_range() + * @see player_audio_effect_get_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_unset_error_cb(player_h player); +int player_audio_effect_set_equalizer_band_level(player_h player, int index, int level); /** - * @brief Registers a callback function to be invoked when there is a change in the buffering status of a media stream. + * @brief Gets the gain set for the given equalizer band. * @since_tizen 2.3.1 - * @remarks The media resource should be streamed over the network. - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[in] player The handle to the media player + * @param[in] index The index of the requested equalizer band + * @param[out] level The gain in decibel of the given band [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature - * @post player_buffering_cb() will be invoked. - * @see player_unset_buffering_cb() - * @see player_set_uri() - * @see player_buffering_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() */ -int player_set_buffering_cb(player_h player, player_buffering_cb callback, void *user_data); +int player_audio_effect_get_equalizer_band_level(player_h player, int index, int *level); /** - * @brief Unregisters the callback function. + * @brief Sets all bands of the equalizer. * @since_tizen 2.3.1 * @param[in] player The handle to the media player + * @param[in] band_levels The list of band levels to be set + * @param[in] length The length of the band level * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_buffering_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_get_equalizer_bands_count() + * @see player_audio_effect_get_equalizer_level_range() + * @see player_audio_effect_set_equalizer_band_level() */ -int player_unset_buffering_cb(player_h player); +int player_audio_effect_set_equalizer_all_bands(player_h player, int *band_levels, int length); /** - * @brief Sets a path to download, progressively. + * @brief Gets the valid band level range of the equalizer. * @since_tizen 2.3.1 - * @remarks Progressive download will be started when you invoke player_start(). - * @param[in] player The handle to the media player - * @param[in] path The absolute path to download + * @param[in] player The handle to the media player + * @param[out] min The minimum value to be set [dB] + * @param[out] max The maximum value to be set [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature - * @pre The player state must be set to #PLAYER_STATE_IDLE by calling player_create() or player_unprepare(). - * @see player_set_progressive_download_message_cb() - * @see player_unset_progressive_download_message_cb() + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_set_progressive_download_path(player_h player, const char *path); +int player_audio_effect_get_equalizer_level_range(player_h player, int* min, int* max); /** - * @brief Gets the status of progressive download. + * @brief Gets the band frequency of the equalizer. * @since_tizen 2.3.1 * @param[in] player The handle to the media player - * @param[out] current The current download position (bytes) - * @param[out] total_size The total size of the file (bytes) + * @param[in] index The index of the requested equalizer band + * @param[out] frequency The frequency of the given band [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The progressive download path must be set by calling player_set_progressive_download_path(). - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. */ -int player_get_progressive_download_status(player_h player, unsigned long *current, unsigned long *total_size); +int player_audio_effect_get_equalizer_band_frequency(player_h player, int index, int *frequency); /** - * @brief Registers a callback function to be invoked when progressive download is started or completed. + * @brief Gets the band frequency range of the equalizer. * @since_tizen 2.3.1 - * @param[in] player The handle to the media player - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function + * @param[in] player The handle to the media player + * @param[in] index The index of the requested equalizer band + * @param[out] range The frequency range of the given band [dB] * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE Unsupported feature - * @pre The path to download must be set by calling player_set_progressive_download_path(). - * @post player_pd_message_cb() will be invoked. - * @see player_unset_progressive_download_message_cb() - * @see player_set_progressive_download_path() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. */ -int player_set_progressive_download_message_cb(player_h player, player_pd_message_cb callback, void *user_data); +int player_audio_effect_get_equalizer_band_frequency_range(player_h player, int index, int *range); /** - * @brief Unregisters the callback function. + * @brief Clears the equalizer effect. * @since_tizen 2.3.1 * @param[in] player The handle to the media player - * @return @c 0 on success, - * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @see player_set_progressive_download_message_cb() + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_unset_progressive_download_message_cb(player_h player); +int player_audio_effect_equalizer_clear(player_h player); /** - * @brief Sets the playback rate. + * @brief Checks whether the custom equalizer effect is available. * @since_tizen 2.3.1 - * @details The default value is @c 1.0. - * @remarks #PLAYER_ERROR_INVALID_OPERATION occurs when streaming playback. - * @remarks No operation is performed, if @a rate is @c 0. - * @remarks The sound is muted, when playback rate is under @c 0.0 and over @c 2.0. - * @param[in] player The handle to the media player - * @param[in] rate The playback rate (-5.0x ~ 5.0x) - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @param[in] player The handle to the media player + * @param[out] available If @c true the specified audio effect is available, + * otherwise @c false + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be set to #PLAYER_STATE_PLAYING by calling player_start(). - * @pre The player state must be set to #PLAYER_STATE_READY by calling player_prepare() or set to #PLAYER_STATE_PLAYING by calling player_start() or set to #PLAYER_STATE_PAUSED by calling player_pause(). + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_audio_effect_set_equalizer_band_level() + * @see player_audio_effect_set_equalizer_all_bands() */ -int player_set_playback_rate(player_h player, float rate); +int player_audio_effect_equalizer_is_available(player_h player, bool *available); /** * @} diff --git a/include/wearable/player_internal.h b/include/wearable/player_internal.h new file mode 100644 index 0000000..8f10698 --- /dev/null +++ b/include/wearable/player_internal.h @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __TIZEN_MEDIA_PLAYER_INTERNAL_H__ +#define __TIZEN_MEDIA_PLAYER_INTERNAL_H__ +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file player_internal.h + */ + +/** + * @addtogroup CAPI_MEDIA_PLAYER_MODULE + * @{ + */ + +/** + * @brief This file contains the media player API for custom features. + * @since_tizen 2.4 + */ +typedef struct +{ + void *data; /**< PCM data */ + int size; /**< Data Size */ + int channel; /**< Channel */ + int rate; /**< Samplerate */ + int depth; /**< Depth */ + bool little_endian; /**< Endianness */ + unsigned long long channel_mask; /**< channel_mask */ +} player_audio_raw_data_s; + +/** + * @brief Called when the audio frame is decoded. + * @since_tizen 2.4 + * @param[in] audio_raw_frame The decoded audio frame data type + * @param[in] user_data The user data passed from the callback registration function + * @see player_set_audio_frame_decoded_cb() + * @see player_unset_audio_frame_decoded_cb() + */ +typedef void (*player_audio_pcm_extraction_cb)(player_audio_raw_data_s *audio_raw_frame, void *user_data); + + +/** + * @brief Registers a callback function to be invoked when audio frame is decoded. Audio only contents is possible. If included video, error happens. + * @since_tizen 2.4 + * @param[in] player The handle to the media player + * @param[in] sync Sync on the clock + * @param[in] format Audio format of output pcm + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be #PLAYER_STATE_IDLE by player_create() or player_unprepare(). + * @post player_audio_pcm_extraction_cb() will be invoked. + */ +int player_set_pcm_extraction_mode(player_h player, bool sync, player_audio_pcm_extraction_cb callback, void *user_data); +/** + * @brief Set pcm mode spec. Samplerate, channel is needed. + * @since_tizen 2.4 + * @param[in] player The handle to the media player + * @param[in] samplerate Samplerate + * @param[in] channel Channel + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @retval #PLAYER_ERROR_NOT_SUPPORTD Not supported + * @pre The player state must be #PLAYER_STATE_IDLE by player_create() or player_unprepare(). + * @see player_set_pcm_extraction_mode() + */ +int player_set_pcm_spec(player_h player, const char *format, int samplerate, int channel); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif //__TIZEN_MEDIA_PLAYER_PRODUCT_H__ + + diff --git a/packaging/capi-media-player.spec b/packaging/capi-media-player.spec old mode 100755 new mode 100644 index d5fc6b7..f5d17e8 --- a/packaging/capi-media-player.spec +++ b/packaging/capi-media-player.spec @@ -1,6 +1,6 @@ Name: capi-media-player Summary: A Media Player library in Tizen Native API -Version: 0.2.2 +Version: 0.2.8 Release: 0 Group: Multimedia/API License: Apache-2.0 @@ -10,7 +10,6 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(mm-player) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-media-sound-manager) -BuildRequires: pkgconfig(gstreamer-0.10) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(elementary) BuildRequires: pkgconfig(ecore) @@ -18,7 +17,9 @@ BuildRequires: pkgconfig(evas) BuildRequires: pkgconfig(ecore-x) BuildRequires: pkgconfig(capi-media-tool) BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(ttrace) BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(eom) Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig @@ -36,6 +37,7 @@ Requires: %{name} = %{version}-%{release} %prep %setup -q + %build %if 0%{?sec_build_binary_debug_enable} export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" @@ -43,25 +45,26 @@ export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" %endif - MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` cmake \ %if "%{?tizen_profile_name}" == "mobile" -DTIZEN_MOBILE=YES \ %else -DTIZEN_WEARABLE=YES \ - %endif - -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} - + %endif + -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} \ + -DTIZEN_TTRACE=YES -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} make %{?jobs:-j%jobs} %install rm -rf %{buildroot} mkdir -p %{buildroot}/usr/share/license -mkdir -p %{buildroot}/opt/usr/devel +mkdir -p %{buildroot}/usr/bin cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} -cp test/player_test %{buildroot}/opt/usr/devel +cp test/player_test %{buildroot}/usr/bin +cp test/player_media_packet_test %{buildroot}/usr/bin +cp test/player_es_push_test %{buildroot}/usr/bin %make_install @@ -75,7 +78,7 @@ cp test/player_test %{buildroot}/opt/usr/devel %manifest capi-media-player.manifest %{_libdir}/libcapi-media-player.so.* %{_datadir}/license/%{name} -/opt/usr/devel/* +/usr/bin/* %files devel %{_includedir}/media/*.h diff --git a/src/player.c b/src/player.c old mode 100755 new mode 100644 index ebc66f4..c7b7489 --- a/src/player.c +++ b/src/player.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -31,12 +32,11 @@ #include #include #include -#include -#define __JOB_KEY_PREPARED "prepared" +#define __JOB_KEY_PREPARED "prepared" #define __JOB_KEY_ERROR "error" #define __JOB_KEY_SEEK_DONE "seek_done" -#define __JOB_KEY_EOS "eos" +#define __JOB_KEY_EOS "eos" #define __RELEASEIF_PREPARE_THREAD(thread_id) \ do { \ @@ -48,6 +48,19 @@ } \ }while(0) +#ifndef USE_ECORE_FUNCTIONS +#define __RELEASEIF_MESSAGE_THREAD(thread_id) \ + do { \ + if (thread_id) \ + { \ + pthread_join(thread_id, NULL); \ + thread_id = 0; \ + LOGI("message thread released\n"); \ + } \ + }while(0) +#endif + +#ifdef USE_ECORE_FUNCTIONS #define __DELETE_ECORE_ITEM(ecore_job) \ do { \ if (ecore_job) \ @@ -67,13 +80,46 @@ \ } while(0) -#define __REMOVE_ECORE_JOB(handle, job_key) \ +#define __REMOVE_ECORE_JOB(handle, job_key) \ do \ { \ LOGI("%s done so, remove\n", job_key); \ g_hash_table_remove(handle->ecore_jobs, job_key); \ handle->is_doing_jobs = FALSE; \ } while(0) +#else +#define __GET_MESSAGE(handle) \ + do { \ + if(handle && handle->message_queue){ \ + g_mutex_lock (&handle->message_queue_lock); \ + if(g_queue_is_empty (handle->message_queue)) \ + { \ + g_cond_wait (&handle->message_queue_cond,&handle->message_queue_lock); \ + } \ + handle->current_message = (int)g_queue_pop_head (handle->message_queue); \ + g_mutex_unlock (&handle->message_queue_lock); \ + LOGI("Retrived message [%d] from queue",handle->current_message); \ + }else{ \ + LOGI("Failed to retrive message from queue"); \ + handle->current_message = PLAYER_MESSAGE_NONE; \ + } \ + }while(0) + +#define __ADD_MESSAGE(handle, message) \ + do { \ + if(handle && handle->message_queue){ \ + g_mutex_lock (&handle->message_queue_lock); \ + if(message==PLAYER_MESSAGE_LOOP_EXIT) \ + g_queue_clear(handle->message_queue); \ + g_queue_push_tail (handle->message_queue,(gpointer)message); \ + g_cond_signal (&handle->message_queue_cond); \ + g_mutex_unlock (&handle->message_queue_lock); \ + LOGI("Adding message [%d] to queue", message); \ + }else{\ + LOGI("Failed to add message [%d] to queue", message); \ + }\ + }while(0) +#endif /* * Internal Implementation @@ -345,11 +391,7 @@ int _player_media_packet_finalize(media_packet_h pkt, int error_code, void *user } /*LOGD("pointer gst buffer %p, ret 0x%x", internal_buffer, ret);*/ - - if (internal_buffer) { - gst_buffer_unref((GstBuffer *)internal_buffer); - internal_buffer = NULL; - } + mm_player_media_packet_video_stream_internal_buffer_unref(internal_buffer); ret = media_packet_get_tbm_surface(pkt, &tsurf); if (ret != MEDIA_PACKET_ERROR_NONE) { @@ -489,6 +531,7 @@ static int __unset_callback(_player_event_e type, player_h player) return PLAYER_ERROR_NONE; } +#ifdef USE_ECORE_FUNCTIONS static void __job_prepared_cb(void *user_data) { player_s * handle = (player_s*)user_data; @@ -533,6 +576,96 @@ static void __job_eos_cb(void *user_data) __REMOVE_ECORE_JOB(handle, __JOB_KEY_EOS); LOGI("End"); } +#else +static void __message_cb_loop(void *data) +{ + bool running = TRUE; + player_s * handle = (player_s*)data; + if(!handle){ + LOGE("null handle in __message_cb_loop"); + return; + } + do{ + __GET_MESSAGE(handle); + switch(handle->current_message){ + case PLAYER_MESSAGE_NONE: + { + LOGW("PLAYER_MESSAGE_NONE"); + running = FALSE; + } + break; + case PLAYER_MESSAGE_PREPARED: + { + LOGW("PLAYER_MESSAGE_PREPARED"); + if(handle->user_cb[_PLAYER_EVENT_TYPE_PREPARE]){ + handle->is_doing_jobs = TRUE; + handle->state = PLAYER_STATE_READY; + ((player_prepared_cb)handle->user_cb[_PLAYER_EVENT_TYPE_PREPARE])(handle->user_data[_PLAYER_EVENT_TYPE_PREPARE]); + handle->user_cb[_PLAYER_EVENT_TYPE_PREPARE] = NULL; + handle->user_data[_PLAYER_EVENT_TYPE_PREPARE] = NULL; + handle->is_doing_jobs = FALSE; + }else{ + LOGE("null handle in PLAYER_MESSAGE_PREPARED"); + } + } + break; + case PLAYER_MESSAGE_ERROR: + { + LOGW("PLAYER_MESSAGE_ERROR"); + if(handle->user_cb[_PLAYER_EVENT_TYPE_ERROR]){ + handle->is_doing_jobs = TRUE; + ((player_error_cb)handle->user_cb[_PLAYER_EVENT_TYPE_ERROR])(handle->error_code,handle->user_data[_PLAYER_EVENT_TYPE_ERROR]); + handle->is_doing_jobs = FALSE; + }else{ + LOGE("null handle in PLAYER_MESSAGE_ERROR"); + } + } + break; + case PLAYER_MESSAGE_SEEK_DONE: + { + LOGW("PLAYER_MESSAGE_SEEK_DONE"); + if(handle->user_cb[_PLAYER_EVENT_TYPE_SEEK]){ + handle->is_doing_jobs = TRUE; + ((player_seek_completed_cb)handle->user_cb[_PLAYER_EVENT_TYPE_SEEK])(handle->user_data[_PLAYER_EVENT_TYPE_SEEK]); + handle->user_cb[_PLAYER_EVENT_TYPE_SEEK] = NULL; + handle->user_data[_PLAYER_EVENT_TYPE_SEEK] = NULL; + handle->is_doing_jobs = FALSE; + }else{ + LOGE("null handle in PLAYER_MESSAGE_SEEK_DONE"); + } + } + break; + case PLAYER_MESSAGE_EOS: + { + LOGW("PLAYER_MESSAGE_EOS"); + if(handle->user_cb[_PLAYER_EVENT_TYPE_COMPLETE]){ + handle->is_doing_jobs = TRUE; + ((player_completed_cb)handle->user_cb[_PLAYER_EVENT_TYPE_COMPLETE])(handle->user_data[_PLAYER_EVENT_TYPE_COMPLETE]); + handle->is_doing_jobs = FALSE; + }else{ + LOGE("null handle in PLAYER_MESSAGE_EOS"); + } + } + break; + case PLAYER_MESSAGE_LOOP_EXIT: + { + LOGW("PLAYER_MESSAGE_LOOP_EXIT"); + running = FALSE; + } + break; + case PLAYER_MESSAGE_MAX: + { + LOGW("PLAYER_MESSAGE_MAX"); + running = FALSE; + } + break; + default: + break; + } + }while(running); + return; +} +#endif static int __msg_callback(int message, void *param, void *user_data) { @@ -553,7 +686,12 @@ static int __msg_callback(int message, void *param, void *user_data) if(handle->user_cb[_PLAYER_EVENT_TYPE_PREPARE]) // asyc && prepared cb has been set { LOGI("[%s] Prepared! [current state : %d]", __FUNCTION__, handle->state); + PLAYER_TRACE_ASYNC_END("MM:PLAYER:PREPARE_ASYNC", *(int *)handle); +#ifdef USE_ECORE_FUNCTIONS __ADD_ECORE_JOB(handle, __JOB_KEY_PREPARED, __job_prepared_cb); +#else + __ADD_MESSAGE(handle,PLAYER_MESSAGE_PREPARED); +#endif } } break; @@ -569,7 +707,11 @@ static int __msg_callback(int message, void *param, void *user_data) case MM_MESSAGE_END_OF_STREAM://0x105 if( handle->user_cb[_PLAYER_EVENT_TYPE_COMPLETE] ) { +#ifdef USE_ECORE_FUNCTIONS __ADD_ECORE_JOB(handle, __JOB_KEY_EOS, __job_eos_cb); +#else + __ADD_MESSAGE(handle,PLAYER_MESSAGE_EOS); +#endif } break; case MM_MESSAGE_BUFFERING: //0x103 @@ -672,7 +814,11 @@ static int __msg_callback(int message, void *param, void *user_data) } if( handle->user_cb[_PLAYER_EVENT_TYPE_SEEK]) { +#ifdef USE_ECORE_FUNCTIONS __ADD_ECORE_JOB(handle, __JOB_KEY_SEEK_DONE, __job_seek_done_cb); +#else + __ADD_MESSAGE(handle,PLAYER_MESSAGE_SEEK_DONE); +#endif } break; case MM_MESSAGE_UNKNOWN: //0x00 @@ -693,7 +839,11 @@ static int __msg_callback(int message, void *param, void *user_data) if(err_code != PLAYER_ERROR_NONE && handle->user_cb[_PLAYER_EVENT_TYPE_ERROR]) { handle->error_code = err_code; +#ifdef USE_ECORE_FUNCTIONS __ADD_ECORE_JOB(handle, __JOB_KEY_ERROR, __job_error_cb); +#else + __ADD_MESSAGE(handle,PLAYER_MESSAGE_ERROR); +#endif } LOGW("[%s] End", __FUNCTION__); return 1; @@ -741,7 +891,7 @@ static bool __video_stream_callback(void *stream, void *user_data) if(i < bo_num) info.planes[i].offset = 0; else - info.planes[i].offset = info.planes[i - 1].size; + info.planes[i].offset = info.planes[i - 1].offset + info.planes[i - 1].size; info.size += info.planes[i].size; } tsurf = tbm_surface_internal_create_with_bos(&info , @@ -750,9 +900,12 @@ static bool __video_stream_callback(void *stream, void *user_data) } else if (bo_num == 0) { int plane_idx = 0; tbm_surface_info_s tsuri; - unsigned char *ptr = video_stream->data; + unsigned char *ptr = video_stream->data[0]; + unsigned char *ptr2 = video_stream->data[1]; if (!ptr) return TRUE; + if (!ptr2 && video_stream->format == MM_PIXEL_FORMAT_NV12T) + return TRUE; tsurf = tbm_surface_create(video_stream->width, video_stream->height, bo_format); if (tsurf) { @@ -762,9 +915,15 @@ static bool __video_stream_callback(void *stream, void *user_data) return TRUE; } - for ( plane_idx = 0; plane_idx < tsuri.num_planes; plane_idx++ ) { - memcpy(tsuri.planes[plane_idx].ptr, ptr, tsuri.planes[plane_idx].size); - ptr += tsuri.planes[plane_idx].size; + if (video_stream->format == MM_PIXEL_FORMAT_NV12T) { + memcpy(tsuri.planes[0].ptr, ptr, tsuri.planes[0].size); + memcpy(tsuri.planes[1].ptr, ptr2, tsuri.planes[1].size); + } + else { + for ( plane_idx = 0; plane_idx < tsuri.num_planes; plane_idx++ ) { + memcpy(tsuri.planes[plane_idx].ptr, ptr, tsuri.planes[plane_idx].size); + ptr += tsuri.planes[plane_idx].size; + } } } else { LOGW("tbm_surface_create failed"); @@ -835,9 +994,8 @@ static bool __video_stream_callback(void *stream, void *user_data) media_packet_destroy(pkt); pkt = NULL; } else { - /* increase ref count of gst buffer */ - if (video_stream->internal_buffer) - gst_buffer_ref((GstBuffer *)video_stream->internal_buffer); + mm_player_media_packet_video_stream_internal_buffer_ref( + video_stream->internal_buffer); /* call media packet callback */ ((player_media_packet_video_decoded_cb)handle->user_cb[_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME])(pkt, handle->user_data[_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME]); @@ -872,6 +1030,8 @@ static int __pd_message_callback(int message, void *param, void *user_data) } return 0; } + +#ifdef USE_ECORE_FUNCTIONS static void __job_key_to_remove(gpointer key) { LOGI("%s",key); @@ -884,6 +1044,7 @@ static void __job_value_to_destroy(gpointer value) LOGI("%p", job); __DELETE_ECORE_ITEM(job); } +#endif /* * Public Implementation @@ -892,6 +1053,7 @@ static void __job_value_to_destroy(gpointer value) int player_create (player_h *player) { PLAYER_INSTANCE_CHECK(player); + PLAYER_TRACE_BEGIN("MM:PLAYER:CREATE"); player_s * handle; handle = (player_s*)malloc( sizeof(player_s)); if (handle != NULL) @@ -917,8 +1079,21 @@ int player_create (player_h *player) handle->display_type = MM_DISPLAY_SURFACE_NULL; // means DISPLAY_TYPE_NONE(3) handle->is_stopped=false; handle->is_display_visible=true; +#ifdef USE_ECORE_FUNCTIONS handle->ecore_jobs = g_hash_table_new_full(g_str_hash, g_str_equal, __job_key_to_remove, __job_value_to_destroy); +#else + handle->message_queue = g_queue_new (); + g_mutex_init(&handle->message_queue_lock); + g_cond_init(&handle->message_queue_cond); + ret = pthread_create(&handle->message_thread, NULL,(void *)__message_cb_loop, (void *)handle); + if (ret != 0) + { + LOGE("[%s] failed to create message thread ret = %d", __FUNCTION__, ret); + return PLAYER_ERROR_OUT_OF_MEMORY; + } +#endif LOGI("[%s] new handle : %p", __FUNCTION__, *player); + PLAYER_TRACE_END(); return PLAYER_ERROR_NONE; } } @@ -926,6 +1101,7 @@ int player_create (player_h *player) int player_destroy (player_h player) { LOGI("[%s] Start, handle to destroy : %p", __FUNCTION__, player); + PLAYER_TRACE_BEGIN("MM:PLAYER:DESTROY"); PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; if (handle->is_doing_jobs) @@ -933,12 +1109,19 @@ int player_destroy (player_h player) LOGE("jobs not completed. can't do destroy"); return PLAYER_ERROR_INVALID_OPERATION; } - +#ifdef USE_ECORE_FUNCTIONS g_hash_table_remove_all(handle->ecore_jobs); g_hash_table_unref(handle->ecore_jobs); - + handle->ecore_jobs = NULL; +#else + __ADD_MESSAGE(handle,PLAYER_MESSAGE_LOOP_EXIT); +#endif __RELEASEIF_PREPARE_THREAD(handle->prepare_async_thread); +#ifndef USE_ECORE_FUNCTIONS + __RELEASEIF_MESSAGE_THREAD(handle->message_thread); +#endif + int ret = mm_player_destroy(handle->mm_handle); if (handle->pkt_fmt) { @@ -956,9 +1139,20 @@ int player_destroy (player_h player) else { handle->state = PLAYER_STATE_NONE; +#ifndef USE_ECORE_FUNCTIONS + if(handle->message_queue){ + g_queue_free (handle->message_queue); + handle->message_queue = NULL; + } + + g_cond_broadcast(&handle->message_queue_cond); + g_mutex_clear(&handle->message_queue_lock); + g_cond_clear(&handle->message_queue_cond); +#endif free(handle); handle= NULL; LOGI("[%s] End", __FUNCTION__); + PLAYER_TRACE_END(); return PLAYER_ERROR_NONE; } } @@ -993,11 +1187,12 @@ int player_prepare_async (player_h player, player_prepared_cb callback, void* us LOGI("[%s] Start", __FUNCTION__); PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; + PLAYER_TRACE_ASYNC_BEGIN("MM:PLAYER:PREPARE_ASYNC", *(int *)handle); PLAYER_STATE_CHECK(handle,PLAYER_STATE_IDLE); int ret; - bool visible; - bool value; + int visible; + int value; if(handle->user_cb[_PLAYER_EVENT_TYPE_PREPARE]) { @@ -1006,7 +1201,6 @@ int player_prepare_async (player_h player, player_prepared_cb callback, void* us } else { - //LOGI("[%s] Event type : %d ",__FUNCTION__, _PLAYER_EVENT_TYPE_PREPARE); handle->user_cb[_PLAYER_EVENT_TYPE_PREPARE] = callback; handle->user_data[_PLAYER_EVENT_TYPE_PREPARE] = user_data; } @@ -1074,6 +1268,7 @@ int player_prepare_async (player_h player, player_prepared_cb callback, void* us int player_prepare (player_h player) { LOGI("[%s] Start", __FUNCTION__); + PLAYER_TRACE_BEGIN("MM:PLAYER:PREPARE"); PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; PLAYER_STATE_CHECK(handle,PLAYER_STATE_IDLE); @@ -1081,7 +1276,6 @@ int player_prepare (player_h player) int ret; int visible; int value; - ret = mm_player_set_message_callback(handle->mm_handle, __msg_callback, (void*)handle); if(ret != MM_ERROR_NONE) { @@ -1138,13 +1332,13 @@ int player_prepare (player_h player) LOGE("[%s] Failed to unrealize - 0x%x", __FUNCTION__,uret); LOGE("[%s] Failed to pause - 0x%x", __FUNCTION__,ret); - return __player_convert_error_code(ret,(char*)__FUNCTION__); } else { handle->state = PLAYER_STATE_READY; LOGI("[%s] End", __FUNCTION__); + PLAYER_TRACE_END(); return PLAYER_ERROR_NONE; } } @@ -1152,10 +1346,11 @@ int player_prepare (player_h player) int player_unprepare (player_h player) { LOGI("[%s] Start", __FUNCTION__); + PLAYER_TRACE_BEGIN("MM:PLAYER:UNPREPARE"); PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) + if (!__player_state_validate(handle, PLAYER_STATE_READY)) { LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); return PLAYER_ERROR_INVALID_STATE; @@ -1190,6 +1385,7 @@ int player_unprepare (player_h player) handle->is_display_visible=true; handle->is_progressive_download=false; LOGI("[%s] End", __FUNCTION__); + PLAYER_TRACE_END(); return PLAYER_ERROR_NONE; } } @@ -1288,11 +1484,9 @@ int player_set_sound_type(player_h player, sound_type_e type) PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } + PLAYER_STATE_CHECK(handle, PLAYER_STATE_IDLE); + + LOGI("[%s] sound type = %d", __FUNCTION__, type); int ret = mm_player_set_attribute(handle->mm_handle, NULL,"sound_volume_type" , type, (char*)NULL); if(ret != MM_ERROR_NONE) @@ -1337,9 +1531,9 @@ int player_start (player_h player) if ( handle->state ==PLAYER_STATE_READY || handle->state ==PLAYER_STATE_PAUSED) { if(handle->display_type == PLAYER_DISPLAY_TYPE_OVERLAY - #ifdef TIZEN_MOBILE +#ifdef TIZEN_MOBILE || handle->display_type == PLAYER_DISPLAY_TYPE_EVAS - #endif +#endif ) { if(handle->is_display_visible) @@ -1394,11 +1588,12 @@ int player_stop (player_h player) if (handle->state == PLAYER_STATE_PLAYING || handle->state == PLAYER_STATE_PAUSED) { int ret = mm_player_stop(handle->mm_handle); + if(handle->display_type == PLAYER_DISPLAY_TYPE_OVERLAY - #ifdef TIZEN_MOBILE +#ifdef TIZEN_MOBILE || handle->display_type == PLAYER_DISPLAY_TYPE_EVAS - #endif - ) +#endif + ) { ret = mm_player_set_attribute(handle->mm_handle, NULL,"display_visible" , 0, (char*)NULL); } @@ -1554,15 +1749,10 @@ int player_is_muted (player_h player, bool *muted) } } -int player_set_looping (player_h player, bool looping) +int player_set_looping (player_h player, bool looping) { PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int value = 0; if(looping==TRUE) @@ -1586,12 +1776,8 @@ int player_is_looping (player_h player, bool *looping) PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(looping); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int count; + int ret = mm_player_get_attribute(handle->mm_handle, NULL,MM_PLAYER_PLAYBACK_COUNT , &count, (char*)NULL); if(ret != MM_ERROR_NONE) { @@ -1642,13 +1828,7 @@ int player_set_display(player_h player, player_display_type_e type, player_displ Evas_Object *obj = NULL; const char *object_type = NULL; void *set_handle = NULL; - int ret; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } if (type != PLAYER_DISPLAY_TYPE_NONE && display == NULL) { @@ -1694,7 +1874,7 @@ int player_set_display(player_h player, player_display_type_e type, player_displ handle->display_handle = (void *)elm_win_xwindow_get(obj); set_handle = &(handle->display_handle); } - #ifdef TIZEN_MOBILE +#ifdef TIZEN_MOBILE else if (type == PLAYER_DISPLAY_TYPE_EVAS && !strcmp(object_type, "image")) { /* evas object surface */ @@ -1702,7 +1882,7 @@ int player_set_display(player_h player, player_display_type_e type, player_displ handle->display_handle = display; set_handle = display; } - #endif +#endif else { LOGE("invalid surface type"); @@ -1722,7 +1902,7 @@ int player_set_display(player_h player, player_display_type_e type, player_displ ret = mm_player_set_attribute(handle->mm_handle, NULL, "display_surface_type", type, "display_overlay", set_handle, - sizeof(display), (char*)NULL); + sizeof(void*), (char*)NULL); if (ret != MM_ERROR_NONE) { @@ -1743,6 +1923,11 @@ int player_set_display(player_h player, player_display_type_e type, player_displ } else //changing surface case { + if (handle->state >= PLAYER_STATE_READY) + { + LOGE("[%s] it is not available to change display surface from %d to %d",__FUNCTION__, handle->display_type, type); + return PLAYER_ERROR_INVALID_OPERATION; + } ret = mm_player_change_videosink(handle->mm_handle, type, set_handle); if (ret != MM_ERROR_NONE) { @@ -1839,7 +2024,6 @@ int player_set_playback_rate(player_h player, float rate) return ret; } - int player_set_display_rotation(player_h player, player_display_rotation_e rotation) { PLAYER_INSTANCE_CHECK(player); @@ -1955,7 +2139,7 @@ int player_get_content_info(player_h player, player_content_info_e key, char ** attr = MM_PLAYER_TAG_DATE; break; default: - attr=NULL; + attr=NULL; } int ret = mm_player_get_attribute(handle->mm_handle, NULL,attr ,&val, &val_len, (char*)NULL); @@ -2110,11 +2294,6 @@ int player_audio_effect_get_equalizer_bands_count (player_h player, int *count) PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(count); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_audio_effect_custom_get_eq_bands_number(handle->mm_handle, count); if(ret != MM_ERROR_NONE) @@ -2128,11 +2307,6 @@ int player_audio_effect_set_equalizer_all_bands(player_h player, int *band_level PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(band_levels); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_audio_effect_custom_set_level_eq_from_list(handle->mm_handle, band_levels, length); if(ret != MM_ERROR_NONE) @@ -2150,11 +2324,6 @@ int player_audio_effect_set_equalizer_band_level(player_h player, int index, int { PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_audio_effect_custom_set_level(handle->mm_handle,MM_AUDIO_EFFECT_CUSTOM_EQ, index, level); if(ret != MM_ERROR_NONE) @@ -2173,11 +2342,6 @@ int player_audio_effect_get_equalizer_band_level(player_h player, int index, int PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(level); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_audio_effect_custom_get_level(handle->mm_handle,MM_AUDIO_EFFECT_CUSTOM_EQ, index, level); if(ret != MM_ERROR_NONE) @@ -2192,11 +2356,6 @@ int player_audio_effect_get_equalizer_level_range(player_h player, int* min, int PLAYER_NULL_ARG_CHECK(min); PLAYER_NULL_ARG_CHECK(max); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_audio_effect_custom_get_level_range(handle->mm_handle, MM_AUDIO_EFFECT_CUSTOM_EQ, min, max); if(ret != MM_ERROR_NONE) @@ -2210,11 +2369,6 @@ int player_audio_effect_get_equalizer_band_frequency(player_h player, int index, PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(frequency); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_audio_effect_custom_get_eq_bands_freq(handle->mm_handle, index, frequency); if(ret != MM_ERROR_NONE) @@ -2228,11 +2382,6 @@ int player_audio_effect_get_equalizer_band_frequency_range(player_h player, int PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(range); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_audio_effect_custom_get_eq_bands_width(handle->mm_handle, index, range); if(ret != MM_ERROR_NONE) @@ -2245,11 +2394,6 @@ int player_audio_effect_equalizer_clear(player_h player) { PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_audio_effect_custom_clear_eq_all(handle->mm_handle); if(ret != MM_ERROR_NONE) @@ -2268,11 +2412,6 @@ int player_audio_effect_equalizer_is_available(player_h player, bool *available) PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(available); player_s * handle = (player_s *) player; - if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } int ret = mm_player_is_supported_custom_effect_type(handle->mm_handle, MM_AUDIO_EFFECT_CUSTOM_EQ); if(ret != MM_ERROR_NONE) @@ -2304,8 +2443,8 @@ int player_set_subtitle_path(player_h player,const char* path) int player_set_subtitle_position_offset(player_h player, int millisecond) { PLAYER_INSTANCE_CHECK(player); -//PLAYER_CHECK_CONDITION(millisecond>=0 ,PLAYER_ERROR_INVALID_PARAMETER ,"PLAYER_ERROR_INVALID_PARAMETER" ); player_s * handle = (player_s *) player; + if (!__player_state_validate(handle, PLAYER_STATE_PLAYING)) { LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); @@ -2345,10 +2484,10 @@ int player_set_progressive_download_path(player_h player, const char *path) int player_get_progressive_download_status(player_h player, unsigned long *current, unsigned long *total_size) { + PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(current); PLAYER_NULL_ARG_CHECK(total_size); - player_s * handle = (player_s *) player; if (handle->state != PLAYER_STATE_PLAYING && handle->state != PLAYER_STATE_PAUSED) { @@ -2455,7 +2594,6 @@ int player_get_streaming_download_progress(player_h player, int *start, int *cur PLAYER_INSTANCE_CHECK(player); PLAYER_NULL_ARG_CHECK(start); PLAYER_NULL_ARG_CHECK(current); - player_s * handle = (player_s *) player; if (handle->state != PLAYER_STATE_PLAYING && handle->state != PLAYER_STATE_PAUSED) { @@ -2535,6 +2673,7 @@ int player_set_progressive_download_message_cb(player_h player, player_pd_messag return PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE; player_s * handle = (player_s *) player; + if (handle->state != PLAYER_STATE_IDLE && handle->state != PLAYER_STATE_READY) { LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); @@ -2596,13 +2735,6 @@ int player_unset_media_packet_video_frame_decoded_cb(player_h player) { PLAYER_INSTANCE_CHECK(player); player_s * handle = (player_s *) player; - - if (handle->state > PLAYER_STATE_READY) - { - LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); - return PLAYER_ERROR_INVALID_STATE; - } - handle->user_cb[_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME] = NULL; handle->user_data[_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME] = NULL; LOGI("Event type : %d ", _PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME); @@ -2613,3 +2745,527 @@ int player_unset_media_packet_video_frame_decoded_cb(player_h player) else return PLAYER_ERROR_NONE; } + +static bool __video_stream_changed_callback (void *user_data) +{ + player_s * handle = (player_s*)user_data; + _player_event_e event_type = _PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED; + + LOGE("[%s] event type %d", __FUNCTION__, event_type); + + if(handle->user_cb[event_type]) + { + int width = 0, height = 0, fps = 0, bit_rate = 0; + int ret = mm_player_get_attribute(handle->mm_handle, NULL, + MM_PLAYER_VIDEO_WIDTH, &width, + MM_PLAYER_VIDEO_HEIGHT, &height, + "content_video_fps", &fps, + "content_video_bitrate", &bit_rate, (char*)NULL); + + if(ret != MM_ERROR_NONE) + { + LOGE("[%s] get attr is failed", __FUNCTION__); + return FALSE; + } + + ((player_video_stream_changed_cb)handle->user_cb[event_type])(width, height, fps, bit_rate, handle->user_data[event_type]); + } + else + { + LOGE("[%s] video stream changed cb was not set.", __FUNCTION__); + return FALSE; + } + + return TRUE; +} + +int player_set_video_stream_changed_cb (player_h player, player_video_stream_changed_cb callback, void *user_data) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(callback); + player_s * handle = (player_s *) player; + + if (handle->state != PLAYER_STATE_IDLE ) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d", __FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + ret = mm_player_set_video_stream_changed_callback ( handle->mm_handle, + (mm_player_stream_changed_callback)__video_stream_changed_callback, (void*)handle ); + + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + + return __set_callback(_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED, player, callback, user_data); +} + +int player_unset_video_stream_changed_cb (player_h player) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + player_s * handle = (player_s *) player; + + __unset_callback(_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED, player); + + ret = mm_player_set_video_stream_changed_callback(handle->mm_handle, NULL, NULL); + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + else + return PLAYER_ERROR_NONE; +} + +static bool __media_stream_buffer_status_callback(player_stream_type_e type, + player_media_stream_buffer_status_e status, + void *user_data) +{ + player_s * handle = (player_s*)user_data; + _player_event_e event_type; + + if (type == PLAYER_STREAM_TYPE_AUDIO) + event_type = _PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS; + else if (type == PLAYER_STREAM_TYPE_VIDEO) + event_type = _PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS; + else + return FALSE; + + LOGE("[%s] event type %d", __FUNCTION__, event_type); + + if (handle->user_cb[event_type]) + { + ((player_media_stream_buffer_status_cb)handle->user_cb[event_type])(status, handle->user_data[event_type]); + } + else + { + LOGE("[%s][type:%d] buffer status cb was not set.", __FUNCTION__, type); + return FALSE; + } + + return TRUE; +} + +static bool __media_stream_seek_data_callback(player_stream_type_e type, + unsigned long long offset, + void *user_data) +{ + player_s * handle = (player_s*)user_data; + _player_event_e event_type; + + if (type == PLAYER_STREAM_TYPE_AUDIO) + event_type = _PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK; + else if (type == PLAYER_STREAM_TYPE_VIDEO) + event_type = _PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK; + else + return FALSE; + + LOGE("[%s] event type %d", __FUNCTION__, event_type); + + if(handle->user_cb[event_type]) + { + ((player_media_stream_seek_cb)handle->user_cb[event_type])(offset, handle->user_data[event_type]); + } + else + { + LOGE("[%s][type:%d] seek cb was not set.", __FUNCTION__, type); + return FALSE; + } + + return TRUE; +} + +int player_set_media_stream_buffer_status_cb ( player_h player, + player_stream_type_e type, + player_media_stream_buffer_status_cb callback, + void *user_data) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(callback); + player_s * handle = (player_s *) player; + + if (handle->state != PLAYER_STATE_IDLE ) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + // the type can be expaned with default and text. + if ((type != PLAYER_STREAM_TYPE_VIDEO) && (type != PLAYER_STREAM_TYPE_AUDIO)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_PARAMETER(type : %d)" ,__FUNCTION__, type); + return PLAYER_ERROR_INVALID_PARAMETER; + } + + ret = mm_player_set_media_stream_buffer_status_callback ( handle->mm_handle, type, + (mm_player_media_stream_buffer_status_callback)__media_stream_buffer_status_callback, (void*)handle ); + + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + + if (type == PLAYER_STREAM_TYPE_VIDEO) + return __set_callback(_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS, player, callback, user_data); + else + return __set_callback(_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS, player, callback, user_data); +} + +int player_unset_media_stream_buffer_status_cb (player_h player, player_stream_type_e type) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + player_s * handle = (player_s *) player; + + if (type == PLAYER_STREAM_TYPE_VIDEO) + __unset_callback(_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS, player); + else if (type == PLAYER_STREAM_TYPE_AUDIO) + __unset_callback(_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS, player); + else + return PLAYER_ERROR_INVALID_PARAMETER; + + ret = mm_player_set_media_stream_buffer_status_callback(handle->mm_handle, type, NULL, NULL); + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + else + return PLAYER_ERROR_NONE; +} + +int player_set_media_stream_seek_cb (player_h player, + player_stream_type_e type, + player_media_stream_seek_cb callback, + void *user_data) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(callback); + player_s * handle = (player_s *) player; + + if (handle->state != PLAYER_STATE_IDLE ) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + // the type can be expaned with default and text. + if ((type != PLAYER_STREAM_TYPE_VIDEO) && (type != PLAYER_STREAM_TYPE_AUDIO)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_PARAMETER(type : %d)" ,__FUNCTION__, type); + return PLAYER_ERROR_INVALID_PARAMETER; + } + + ret = mm_player_set_media_stream_seek_data_callback ( handle->mm_handle, type, + (mm_player_media_stream_seek_data_callback)__media_stream_seek_data_callback, (void*)handle ); + + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + + if (type == PLAYER_STREAM_TYPE_VIDEO) + return __set_callback(_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK, player, callback, user_data); + else + return __set_callback(_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK, player, callback, user_data); +} + +int player_unset_media_stream_seek_cb (player_h player, player_stream_type_e type) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + player_s * handle = (player_s *) player; + + if (type == PLAYER_STREAM_TYPE_VIDEO) + __unset_callback(_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK, player); + else if (type == PLAYER_STREAM_TYPE_AUDIO) + __unset_callback(_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK, player); + else + return PLAYER_ERROR_INVALID_PARAMETER; + + ret = mm_player_set_media_stream_seek_data_callback(handle->mm_handle, type, NULL, NULL); + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + else + return PLAYER_ERROR_NONE; +} + +int player_push_media_stream(player_h player, media_packet_h packet) +{ + PLAYER_INSTANCE_CHECK(player); + player_s * handle = (player_s *) player; + + PLAYER_CHECK_CONDITION(handle->error_code == PLAYER_ERROR_NONE, + PLAYER_ERROR_NOT_SUPPORTED_FILE, "can't support this format"); + + int ret = mm_player_submit_packet(handle->mm_handle, packet); + + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + return PLAYER_ERROR_NONE; + } +} + +int player_set_media_stream_info(player_h player, player_stream_type_e type, media_format_h format) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + player_s * handle = (player_s *) player; + PLAYER_STATE_CHECK(handle,PLAYER_STATE_IDLE); + + if (type == PLAYER_STREAM_TYPE_VIDEO) + ret = mm_player_set_video_info(handle->mm_handle, format); + else if (type == PLAYER_STREAM_TYPE_AUDIO) + ret = mm_player_set_audio_info(handle->mm_handle, format); + else + return PLAYER_ERROR_INVALID_PARAMETER; + + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + return PLAYER_ERROR_NONE; + } + + return PLAYER_ERROR_NONE; +} + +int player_set_media_stream_buffer_max_size(player_h player, player_stream_type_e type, unsigned long long max_size) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + player_s * handle = (player_s *) player; + PLAYER_STATE_CHECK(handle,PLAYER_STATE_IDLE); + + ret = mm_player_set_media_stream_buffer_max_size(handle->mm_handle, type, max_size); + + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + return PLAYER_ERROR_NONE; + } +} + +int player_get_media_stream_buffer_max_size(player_h player, player_stream_type_e type, unsigned long long *max_size) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(max_size); + player_s * handle = (player_s *) player; + + unsigned long long _max_size; + int ret = mm_player_get_media_stream_buffer_max_size(handle->mm_handle, type, &_max_size); + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + *max_size = _max_size; + return PLAYER_ERROR_NONE; + } +} + +int player_set_media_stream_buffer_min_threshold(player_h player, player_stream_type_e type, unsigned int percent) +{ + int ret; + PLAYER_INSTANCE_CHECK(player); + player_s * handle = (player_s *) player; + PLAYER_STATE_CHECK(handle,PLAYER_STATE_IDLE); + + ret = mm_player_set_media_stream_buffer_min_percent(handle->mm_handle, type, percent); + + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + return PLAYER_ERROR_NONE; + } +} + +int player_get_media_stream_buffer_min_threshold(player_h player, player_stream_type_e type, unsigned int *percent) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(percent); + player_s * handle = (player_s *) player; + + unsigned int _value; + int ret = mm_player_get_media_stream_buffer_min_percent(handle->mm_handle, type, &_value); + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + *percent = _value; + return PLAYER_ERROR_NONE; + } +} + +int player_get_track_count(player_h player, player_stream_type_e type, int *count) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(count); + player_s * handle = (player_s *) player; + + if (!__player_state_validate(handle, PLAYER_STATE_READY)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + MMPlayerTrackType track_type = 0; + switch(type) + { + case PLAYER_STREAM_TYPE_AUDIO: + track_type = MM_PLAYER_TRACK_TYPE_AUDIO; + break; + case PLAYER_STREAM_TYPE_TEXT: + track_type = MM_PLAYER_TRACK_TYPE_TEXT; + break; + default: + LOGE("invalid stream type %d", type); + return PLAYER_ERROR_INVALID_PARAMETER; + } + + int ret = mm_player_get_track_count(handle->mm_handle, track_type, count); + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + return PLAYER_ERROR_NONE; +} + +int player_get_current_track(player_h player, player_stream_type_e type, int *index) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(index); + player_s * handle = (player_s *) player; + + if (!__player_state_validate(handle, PLAYER_STATE_READY)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + MMPlayerTrackType track_type = 0; + switch(type) + { + case PLAYER_STREAM_TYPE_AUDIO: + track_type = MM_PLAYER_TRACK_TYPE_AUDIO; + break; + case PLAYER_STREAM_TYPE_TEXT: + track_type = MM_PLAYER_TRACK_TYPE_TEXT; + break; + default: + LOGE("invalid stream type %d", type); + return PLAYER_ERROR_INVALID_PARAMETER; + } + + int ret = mm_player_get_current_track(handle->mm_handle, track_type, index); + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + return PLAYER_ERROR_NONE; +} + +int player_select_track(player_h player, player_stream_type_e type, int index) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_CHECK_CONDITION(index>=0, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER" ); + player_s * handle = (player_s *) player; + + if (!__player_state_validate(handle, PLAYER_STATE_READY)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + MMPlayerTrackType track_type = 0; + switch(type) + { + case PLAYER_STREAM_TYPE_AUDIO: + track_type = MM_PLAYER_TRACK_TYPE_AUDIO; + break; + case PLAYER_STREAM_TYPE_TEXT: + track_type = MM_PLAYER_TRACK_TYPE_TEXT; + break; + default: + LOGE("invalid stream type %d", type); + return PLAYER_ERROR_INVALID_PARAMETER; + } + + int ret = mm_player_select_track(handle->mm_handle, track_type, index); + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + return PLAYER_ERROR_NONE; +} + +int player_get_track_language_code(player_h player, player_stream_type_e type, int index, char **code) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(code); + player_s * handle = (player_s *) player; + if (!__player_state_validate(handle, PLAYER_STATE_READY)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE (0x%08x) : current state - %d" ,__FUNCTION__, PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + char* language_code=NULL; + MMPlayerTrackType track_type = 0; + switch(type) + { + case PLAYER_STREAM_TYPE_AUDIO: + track_type = MM_PLAYER_TRACK_TYPE_AUDIO; + break; + case PLAYER_STREAM_TYPE_VIDEO: + track_type = MM_PLAYER_TRACK_TYPE_VIDEO; + break; + case PLAYER_STREAM_TYPE_TEXT: + track_type = MM_PLAYER_TRACK_TYPE_TEXT; + break; + default: + LOGE("invalid stream type %d", type); + return PLAYER_ERROR_INVALID_PARAMETER; + } + + int ret = mm_player_get_track_language_code(handle->mm_handle, track_type, index, &language_code); + if(ret != MM_ERROR_NONE) + { + if(language_code!=NULL) + free(language_code); + + language_code=NULL; + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + int code_len=0; + *code = NULL; + if(language_code!=NULL && strncmp(language_code, "und", 3)) + { + code_len = 2; + *code = strndup(language_code, code_len); + } + else + { + code_len = 3; + *code = strndup("und", code_len); + } + + if(language_code) + free(language_code); + + language_code=NULL; + + return PLAYER_ERROR_NONE; + } +} diff --git a/src/player_internal.c b/src/player_internal.c new file mode 100644 index 0000000..80baeae --- /dev/null +++ b/src/player_internal.c @@ -0,0 +1,173 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* +* Internal Macros +*/ +#define PLAYER_SET_CALLBACK(event_type, handle, callback, user_data) \ +do \ +{ \ + PLAYER_INSTANCE_CHECK(handle); \ + PLAYER_NULL_ARG_CHECK(callback); \ + handle->user_cb[event_type] = callback; \ + handle->user_data[event_type] = user_data; \ + LOGI("[%s] Event type : %d ",__FUNCTION__, event_type); \ +}while(0) \ + +#ifdef TIZEN_MOBILE +static bool __video_frame_render_error_callback(void *param, void *user_data) +{ + player_s * handle = (player_s*)user_data; + if( handle->user_cb[_PLAYER_EVENT_TYPE_VIDEO_FRAME_RENDER_ERROR]) + { + ((player_x11_pixmap_error_cb)handle->user_cb[_PLAYER_EVENT_TYPE_VIDEO_FRAME_RENDER_ERROR])((unsigned int *)param, handle->user_data[_PLAYER_EVENT_TYPE_VIDEO_FRAME_RENDER_ERROR]); + } + return TRUE; +} + +int player_set_x11_display_pixmap (player_h player, player_x11_pixmap_updated_cb callback, void *user_data) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(callback); + player_s * handle = (player_s *) player; + + if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + if (!handle->is_set_pixmap_cb && handle->display_type != ((int)MM_DISPLAY_SURFACE_NULL)) + { + LOGE("[%s] player_set_display() was set, try it again after calling player_unprepare()" ,__FUNCTION__,PLAYER_ERROR_INVALID_OPERATION); + LOGE("[%s] PLAYER_ERROR_INVALID_OPERATION(0x%08x)" ,__FUNCTION__,PLAYER_ERROR_INVALID_OPERATION); + return PLAYER_ERROR_INVALID_OPERATION; + } + + int ret = mm_player_set_attribute(handle->mm_handle, NULL, "display_surface_type", MM_DISPLAY_SURFACE_X_EXT, "display_overlay" , callback , sizeof(void*), "display_overlay_user_data", user_data, sizeof(user_data), (char*)NULL); + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + handle->is_set_pixmap_cb = true; + handle->display_type = MM_DISPLAY_SURFACE_X; + handle->display_handle = callback; + LOGI("[%s] video display has been changed- type :%d, pixmap_callback addr : 0x%x",__FUNCTION__,handle->display_type, handle->display_handle); + return PLAYER_ERROR_NONE; + } + +} + +int player_set_x11_display_pixmap_error_cb (player_h player, player_x11_pixmap_error_cb callback, void *user_data) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(callback); + player_s * handle = (player_s *) player; + + if (!__player_state_validate(handle, PLAYER_STATE_IDLE)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); + return PLAYER_ERROR_INVALID_STATE; + } + + int ret = mm_player_set_video_frame_render_error_callback(handle->mm_handle, __video_frame_render_error_callback, (void*)handle); + if(ret != MM_ERROR_NONE) + { + return __player_convert_error_code(ret,(char*)__FUNCTION__); + } + else + { + LOGI("[%s] set pixmap_error_cb(0x%08x) and user_data(0x%8x)" ,__FUNCTION__, callback, user_data); + handle->user_cb[_PLAYER_EVENT_TYPE_VIDEO_FRAME_RENDER_ERROR] = callback; + handle->user_data[_PLAYER_EVENT_TYPE_VIDEO_FRAME_RENDER_ERROR] = user_data; + LOGI("[%s] Event type : %d ",__FUNCTION__, _PLAYER_EVENT_TYPE_VIDEO_FRAME_RENDER_ERROR); + return PLAYER_ERROR_NONE; + } +} +#endif + +bool __audio_stream_callback_ex(MMPlayerAudioStreamDataType *stream, void *user_data) +{ + player_s * handle = (player_s*)user_data; + + if (!__player_state_validate(handle, PLAYER_STATE_READY)) + { + LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state); + return TRUE; + } + + if( handle->user_cb[_PLAYER_EVENT_TYPE_AUDIO_FRAME] ) + { + ((player_audio_pcm_extraction_cb)handle->user_cb[_PLAYER_EVENT_TYPE_AUDIO_FRAME])((player_audio_raw_data_s *)stream, handle->user_data[_PLAYER_EVENT_TYPE_AUDIO_FRAME]); + } + return TRUE; +} + +int player_set_pcm_extraction_mode(player_h player, bool sync, player_audio_pcm_extraction_cb callback, void *user_data) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(callback); + player_s * handle = (player_s *) player; + int ret = MM_ERROR_NONE; + + PLAYER_STATE_CHECK(handle, PLAYER_STATE_IDLE); + + ret = mm_player_set_attribute(handle->mm_handle, NULL, "pcm_extraction",TRUE, "pcm_extraction_start_msec", 0, "pcm_extraction_end_msec", 0, NULL); + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + + ret = mm_player_set_audio_stream_callback_ex(handle->mm_handle, sync, __audio_stream_callback_ex, (void*)handle); + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + + PLAYER_SET_CALLBACK(_PLAYER_EVENT_TYPE_AUDIO_FRAME, handle, callback, user_data); + return PLAYER_ERROR_NONE; +} + +int player_set_pcm_spec(player_h player, const char *format, int samplerate, int channel) +{ + PLAYER_INSTANCE_CHECK(player); + + player_s * handle = (player_s *) player; + int ret = MM_ERROR_NONE; + + LOGE("[%s] player_set_pcm_spec %s %d %d", __FUNCTION__, format, samplerate, channel); + ret = mm_player_set_attribute(handle->mm_handle, NULL, "pcm_audioformat", format , strlen(format), NULL); + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + + ret = mm_player_set_pcm_spec(handle->mm_handle, samplerate, channel); + if(ret != MM_ERROR_NONE) + return __player_convert_error_code(ret,(char*)__FUNCTION__); + + return PLAYER_ERROR_NONE; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt old mode 100755 new mode 100644 index efb89aa..988fdf2 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,12 +5,13 @@ INCLUDE_DIRECTORIES(../include/mobile) link_directories(${CMAKE_SOURCE_DIR}/../) INCLUDE(FindPkgConfig) -pkg_check_modules(${fw_test} REQUIRED mm-player appcore-efl elementary ecore evas ecore-x capi-media-sound-manager) +pkg_check_modules(${fw_test} REQUIRED mm-player appcore-efl elementary ecore evas ecore-x capi-media-sound-manager eom) FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -pie") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_EXE_LINKER_FLAGS "-pie -Wl,--as-needed -Wl,--rpath=/usr/lib/gstreamer-1.0") aux_source_directory(. sources) FOREACH(src ${sources}) @@ -18,5 +19,6 @@ FOREACH(src ${sources}) MESSAGE("${src_name}") ADD_EXECUTABLE(${src_name} ${src}) TARGET_LINK_LIBRARIES(${src_name} capi-media-player ${${fw_test}_LDFLAGS}) + INSTALL(TARGETS ${src_name} DESTINATION bin) ENDFOREACH() diff --git a/test/player_es_push_test.c b/test/player_es_push_test.c new file mode 100644 index 0000000..776e964 --- /dev/null +++ b/test/player_es_push_test.c @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2014 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 + +#define ES_DEFAULT_DIR_PATH "/opt/usr/media/" +#define ES_DEFAULT_H264_VIDEO_PATH ES_DEFAULT_DIR_PATH"Simpsons.h264" +#define ES_DEFAULT_VIDEO_FORMAT_TYPE MEDIA_FORMAT_H264_SP +#define ES_DEFAULT_VIDEO_FORMAT_WIDTH 1280 +#define ES_DEFAULT_VIDEO_FORMAT_HEIGHT 544 +#define ES_DEFAULT_VIDEO_PTS_OFFSET 20000000 +#define ES_DEFAULT_NUMBER_OF_FEED 2000 + +unsigned char sps[100]; +unsigned char pps[100]; +unsigned char tmp_buf[1000000]; +static int sps_len, pps_len; + +#ifdef PACKAGE +#undef PACKAGE +#endif +#define PACKAGE "player_es_push_test" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "PLAYER_TEST" + +static int app_create(void *data); +static int app_reset(bundle *b, void *data); +static int app_resume(void *data); +static int app_pause(void *data); +static int app_terminate(void *data); + +struct appcore_ops ops = { + .create = app_create, + .terminate = app_terminate, + .pause = app_pause, + .resume = app_resume, + .reset = app_reset, +}; + +typedef struct appdata { + Evas_Object *win; + Evas_Object *rect; + player_h player_handle; + media_packet_h video_pkt; + media_format_h video_fmt; + FILE *file_src; + pthread_t feeding_thread_id; +} appdata_s; + +static void +win_delete_request_cb(void *data , Evas_Object *obj , void *event_info) +{ + elm_exit(); +} + +static Eina_Bool +keydown_cb(void *data , int type , void *event) +{ + //appdata_s *ad = data; + Ecore_Event_Key *ev = event; + + LOGD("start"); + + if (!strcmp(ev->keyname, "XF86Back")) { + /* Let window go to hide state. */ + //elm_win_lower(ad->win); + LOGD("elm exit"); + elm_exit(); + + return ECORE_CALLBACK_DONE; + } + + LOGD("done"); + + return ECORE_CALLBACK_PASS_ON; +} + +static void win_del(void *data, Evas_Object *obj, void *event) +{ + elm_exit(); +} + +static Evas_Object* create_win(const char *name) +{ + Evas_Object *eo = NULL; + + eo = elm_win_add(NULL, name, ELM_WIN_BASIC); + if (eo) { + elm_win_title_set(eo, name); + elm_win_borderless_set(eo, EINA_TRUE); + evas_object_smart_callback_add(eo, "delete,request",win_del, NULL); + elm_win_autodel_set(eo, EINA_TRUE); + } + return eo; +} + +static Evas_Object *create_render_rect(Evas_Object *pParent) +{ + if(!pParent) { + return NULL; + } + + Evas *pEvas = evas_object_evas_get(pParent); + Evas_Object *pObj = evas_object_rectangle_add(pEvas); + if(pObj == NULL) { + return NULL; + } + + evas_object_size_hint_weight_set(pObj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_color_set(pObj, 0, 0, 0, 0); + evas_object_render_op_set(pObj, EVAS_RENDER_COPY); + evas_object_show(pObj); + elm_win_resize_object_add(pParent, pObj); + + return pObj; +} + +static void +create_base_gui(appdata_s *ad) +{ + /* Enable GLES Backened */ + elm_config_preferred_engine_set("3d"); + + /* Window */ + ad->win = create_win(PACKAGE);//elm_win_util_standard_add(PACKAGE, PACKAGE); + ad->rect = create_render_rect(ad->win); + + elm_win_wm_desktop_layout_support_set(ad->win, EINA_TRUE); + elm_win_autodel_set(ad->win, EINA_TRUE); + evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, ad); + + /* Show window after base gui is set up */ + elm_win_activate(ad->win); + evas_object_show(ad->win); +} + +static int app_create(void *data) +{ + /* Hook to take necessary actions before main event loop starts + Initialize UI resources and application's data + If this function returns true, the main loop of application starts + If this function returns false, the application is terminated */ + appdata_s *ad = data; + + LOGD("start"); + + create_base_gui(ad); + ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, keydown_cb, NULL); + + /* open test file*/ + ad->file_src = fopen(ES_DEFAULT_H264_VIDEO_PATH, "r"); + + LOGD("done"); + + return 0; +} + +static int app_pause(void *data) +{ + /* Take necessary actions when application becomes invisible. */ + appdata_s *ad = (appdata_s *)data; + int ret = PLAYER_ERROR_NONE; + + LOGD("start"); + + if (ad == NULL) { + LOGE("appdata is NULL"); + return -1; + } + + if (ad->player_handle == NULL) { + printf("player_handle is NULL"); + return -1; + } + + if (ad->feeding_thread_id) + { + pthread_join(ad->feeding_thread_id, NULL); + ad->feeding_thread_id = 0; + } + + player_unset_media_stream_buffer_status_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO); + player_unset_media_stream_buffer_status_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO); + player_unset_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO); + player_unset_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO); + + ret = player_unprepare(ad->player_handle); + if (ret != PLAYER_ERROR_NONE) { + printf("player_unprepare failed : 0x%x", ret); + return false; + } + + /* unref media format */ + if (ad->video_fmt) + media_format_unref(ad->video_fmt); + + fclose(ad->file_src); + + /* destroy player handle */ + ret = player_destroy(ad->player_handle); + if (ret != PLAYER_ERROR_NONE) { + printf("player_destroy failed : 0x%x", ret); + return false; + } + + ad->player_handle = NULL; + + LOGD("done"); + + return 0; +} + +static int app_resume(void *data) +{ + LOGD("start"); + + LOGD("done"); + + return 0; +} + +static void _player_prepared_cb(void *user_data) +{ + int ret = PLAYER_ERROR_NONE; + appdata_s *ad = (appdata_s *)user_data; + + LOGD("prepared"); + + ret = player_start(ad->player_handle); + if (ret != PLAYER_ERROR_NONE) { + LOGE("player start failed : 0x%x", ret); + } + LOGD("done"); +} + +int bytestream2nalunit(FILE *fd, unsigned char* nal) +{ + int nal_length = 0; + size_t result; + int read_size = 1; + unsigned char buffer[1000000]; + unsigned char val, zero_count, i; + int nal_unit_type = 0; + int init; + + zero_count = 0; + if (feof(fd)) + return -1; + + result = fread(buffer, 1, read_size, fd); + + if(result != read_size) + { + //exit(1); + return -1; + } + val = buffer[0]; + while (!val) + { + if ((zero_count == 2 || zero_count == 3) && val == 1) + { + break; + } + zero_count++; + result = fread(buffer, 1, read_size, fd); + + if(result != read_size) + { + break; + } + val = buffer[0]; + } + nal[nal_length++] = 0; + nal[nal_length++] = 0; + nal[nal_length++] = 0; + nal[nal_length++] = 1; + zero_count = 0; + init = 1; + while(1) + { + if (feof(fd)) + return -1; + + result = fread(buffer, 1, read_size, fd); + if(result != read_size) + { + if (init == 1) + return -1; + break; + } + val = buffer[0]; + + if(init) { + nal_unit_type = val & 0xf; + init = 0; + } + if (!val) + { + zero_count++; + } + else + { + if ((zero_count == 2 || zero_count == 3 || zero_count == 4) && (val == 1)) + { + break; + } + else + { + for (i = 0; ivideo_fmt, NULL, NULL, &ad->video_pkt) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_create_alloc failed\n"); + return; + } + + if (media_packet_set_buffer_size(ad->video_pkt, (uint64_t)0) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_set_buffer_size failed\n"); + return; + } + + media_packet_set_flags(ad->video_pkt, MEDIA_PACKET_END_OF_STREAM); + if (player_push_media_stream(ad->player_handle, ad->video_pkt) != PLAYER_ERROR_NONE) { + LOGE("fail to push media packet\n"); + } + + media_packet_destroy(ad->video_pkt); + ad->video_pkt = NULL; + + return; +} + +static bool feed_video_data(appdata_s *appdata) +{ + bool ret = FALSE; + int read = 0; + static guint64 pts = 0L; + void *buf_data_ptr = NULL; + appdata_s *ad = appdata; + + if (media_packet_create_alloc(ad->video_fmt, NULL, NULL, &ad->video_pkt) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_create_alloc failed\n"); + return FALSE; + } + + if (media_packet_get_buffer_data_ptr(ad->video_pkt, &buf_data_ptr) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_get_buffer_data_ptr failed\n"); + goto ERROR; + } + + if (media_packet_set_pts(ad->video_pkt, (uint64_t)(pts/1000000)) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_set_pts failed\n"); + goto ERROR; + } + + /* NOTE: In case of H.264 video, stream format for feeding is NAL unit. + * And, SPS(0x67) and PPS(0x68) should be located before IDR.(0x65). + */ + read = bytestream2nalunit(ad->file_src, buf_data_ptr); + LOGD("real length = %d\n", read); + if (read == 0) { + LOGE("input file read failed\n"); + ret = TRUE; + goto ERROR; + } + else if (read < 0) { + LOGD("push EOS"); + media_packet_set_buffer_size(ad->video_pkt, (uint64_t)0); + media_packet_set_flags (ad->video_pkt, MEDIA_PACKET_END_OF_STREAM); + if (player_push_media_stream(ad->player_handle, ad->video_pkt) != PLAYER_ERROR_NONE) { + LOGE("fail to push media packet\n"); + } + goto ERROR; + } + + if (media_packet_set_buffer_size(ad->video_pkt, (uint64_t)read) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_set_buffer_size failed\n"); + goto ERROR; + } + + /* push media packet */ + player_push_media_stream(ad->player_handle, ad->video_pkt); + pts += ES_DEFAULT_VIDEO_PTS_OFFSET; + ret = TRUE; + +ERROR: + /* destroy media packet after use*/ + media_packet_destroy(ad->video_pkt); + ad->video_pkt = NULL; + return ret; +} + +static void feed_video_data_thread_func(void *data) +{ + appdata_s *ad = (appdata_s *)data; + + while (TRUE) + { + static int frame_count = 0; + + if (frame_count < ES_DEFAULT_NUMBER_OF_FEED) { + if (!feed_video_data(ad)) + break; + frame_count++; + } else { + feed_eos_data(ad); + break; + } + } +} + +void _video_buffer_status_cb (player_media_stream_buffer_status_e status, void *user_data) +{ + if (status == PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN) + { + LOGE("video buffer is underrun state"); + } + else if (status == PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW) + { + LOGE("video buffer is overrun state"); + } +} + +void _audio_buffer_status_cb (player_media_stream_buffer_status_e status, void *user_data) +{ + if (status == PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN) + LOGE("audio buffer is underrun state"); + else if (status == PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW) + LOGE("audio buffer is overrun state"); +} + +void _video_seek_data_cb (unsigned long long offset, void *user_data) +{ + LOGE("seek offset of video is %llu", offset); +} + +void _audio_seek_data_cb (unsigned long long offset, void *user_data) +{ + LOGE("seek offset of audio is %llu", offset); +} + +static int app_reset(bundle *b, void *data) +{ + /* Take necessary actions when application becomes visible. */ + appdata_s *ad = (appdata_s *)data; + int ret = PLAYER_ERROR_NONE; + + LOGD("start"); + + if (ad == NULL) { + LOGE("appdata is NULL"); + return -1; + } + + ret = player_create(&ad->player_handle); + if (ret != PLAYER_ERROR_NONE) { + LOGE("player_create failed : 0x%x", ret); + return -1; + } + + ret = player_set_display(ad->player_handle, PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(ad->win)); + if (ret != PLAYER_ERROR_NONE) { + LOGE("player_set_display failed : 0x%x", ret); + goto FAILED; + } + + /* get media format format */ + ret = media_format_create(&ad->video_fmt); + if (ret != MEDIA_FORMAT_ERROR_NONE) { + LOGE("media_format_create : 0x%x", ret); + goto FAILED; + } + + /* set video format */ + media_format_set_video_mime(ad->video_fmt, ES_DEFAULT_VIDEO_FORMAT_TYPE); + media_format_set_video_width(ad->video_fmt, ES_DEFAULT_VIDEO_FORMAT_WIDTH); + media_format_set_video_height(ad->video_fmt,ES_DEFAULT_VIDEO_FORMAT_HEIGHT); + + ret = player_set_media_stream_buffer_status_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, _video_buffer_status_cb, (void*)ad); + if (ret != PLAYER_ERROR_NONE) { + LOGE("player set video buffer status cb failed : 0x%x", ret); + goto FAILED; + } + ret = player_set_media_stream_buffer_status_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO, _audio_buffer_status_cb, (void*)ad); + if (ret != PLAYER_ERROR_NONE) { + LOGE("player set audio buffer status cb failed : 0x%x", ret); + goto FAILED; + } + + ret = player_set_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, _video_seek_data_cb, (void*)ad); + if (ret != PLAYER_ERROR_NONE) { + LOGE("player set seek data cb for video failed : 0x%x", ret); + goto FAILED; + } + ret = player_set_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO, _audio_seek_data_cb, (void*)ad); + if (ret != PLAYER_ERROR_NONE) { + LOGE("player set seek data cb for audio failed : 0x%x", ret); + goto FAILED; + } + + /* send media packet to player */ + player_set_media_stream_info(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, ad->video_fmt); + + ret = player_prepare_async(ad->player_handle, _player_prepared_cb, (void*)ad); + if (ret != PLAYER_ERROR_NONE) { + LOGE("player prepare failed : 0x%x", ret); + goto FAILED; + } + + pthread_create(&ad->feeding_thread_id, NULL, (void*)feed_video_data_thread_func, (void *)ad); + + LOGD("done"); + + return 0; + +FAILED: + if (ad->player_handle) { + player_destroy(ad->player_handle); + ad->player_handle = NULL; + } + + return -1; +} + +static int app_terminate(void *data) +{ + /* Release all resources. */ + appdata_s *ad = (appdata_s *)data; + + LOGD("start"); + + if (ad == NULL) { + LOGE("appdata is NULL"); + return -1; + } + + app_pause(data); + + LOGD("done"); + + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + static appdata_s ad = {0,}; + + LOGD("start"); + + memset(&ad, 0x0, sizeof(appdata_s)); + + LOGD("call appcore_efl_main"); + + ops.data = &ad; + + ret = appcore_efl_main(PACKAGE, &argc, &argv, &ops); + + LOGD("appcore_efl_main() ret = 0x%x", ret); + + return ret; +} diff --git a/test/player_media_packet_test.c b/test/player_media_packet_test.c old mode 100755 new mode 100644 index 6a7e85c..81ac684 --- a/test/player_media_packet_test.c +++ b/test/player_media_packet_test.c @@ -21,7 +21,6 @@ #include #include -#define KEY_END "XF86Stop" #define MEDIA_FILE_PATH "/opt/usr/media/Color.mp4" #ifdef PACKAGE #undef PACKAGE @@ -72,7 +71,7 @@ keydown_cb(void *data , int type , void *event) LOGD("start"); - if (!strcmp(ev->keyname, KEY_END)) { + if (!strcmp(ev->keyname, "XF86Back")) { /* Let window go to hide state. */ //elm_win_lower(ad->win); LOGD("elm exit"); @@ -90,7 +89,7 @@ static void create_base_gui(appdata_s *ad) { /* Enable GLES Backened */ - elm_config_preferred_engine_set("opengl_x11"); + elm_config_preferred_engine_set("3d"); /* Window */ ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE); @@ -159,7 +158,11 @@ pipe_cb(void *data, void *buf, unsigned int len) /* Now, we get a player surface to be set here. */ appdata_s *ad = data; tbm_surface_h surface; +#if _CAN_USE_NATIVE_SURFACE_TBM Evas_Native_Surface surf; +#endif + tbm_surface_info_s suf_info; + uint32_t plane_idx; int ret; GList *last_item = NULL; @@ -207,6 +210,7 @@ pipe_cb(void *data, void *buf, unsigned int len) g_mutex_unlock(&ad->buffer_lock); +#if _CAN_USE_NATIVE_SURFACE_TBM /* Set tbm surface to image native surface */ memset(&surf, 0x0, sizeof(surf)); surf.version = EVAS_NATIVE_SURFACE_VERSION; @@ -217,6 +221,29 @@ pipe_cb(void *data, void *buf, unsigned int len) /* Set dirty image region to be redrawn */ evas_object_image_data_update_add(ad->img, 0, 0, ad->w, ad->h); +#else + unsigned char *ptr = NULL; + unsigned char *buf_data = NULL; + media_format_h format = NULL; + media_format_mimetype_e mimetype; + + media_packet_get_format(ad->packet, &format); + media_format_get_video_info(format, &mimetype, NULL, NULL, NULL, NULL); + + if (mimetype == MEDIA_FORMAT_I420 || mimetype == MEDIA_FORMAT_NV12 || mimetype == MEDIA_FORMAT_NV12T) { + + tbm_surface_get_info(surface,&suf_info); + buf_data = (unsigned char*)g_malloc0(suf_info.size); + ptr = buf_data; + + for (plane_idx = 0; plane_idx < suf_info.num_planes; plane_idx++) { + memcpy(ptr, suf_info.planes[plane_idx].ptr, suf_info.planes[plane_idx].size); + ptr += suf_info.planes[plane_idx].size; + } + /* dump buf data here, if needed */ + g_free(buf_data); + } +#endif LOGD("done"); diff --git a/test/player_test.c b/test/player_test.c old mode 100755 new mode 100644 index 3fd4fc0..3f7c8df --- a/test/player_test.c +++ b/test/player_test.c @@ -14,12 +14,17 @@ * limitations under the License. */ #include +#include +#include #include #include #include #include #include #include +#ifdef _ACTIVATE_EOM_ +#include +#endif //#define _USE_X_DIRECT_ #ifdef _USE_X_DIRECT_ #include @@ -31,9 +36,26 @@ #define INI_SAMPLE_LIST_MAX 9 #define DEFAULT_HTTP_TIMEOUT -1 -char g_uri[MAX_STRING_LEN]; -char g_subtitle_uri[MAX_STRING_LEN]; -FILE *g_pcm_fd; +static gboolean g_memory_playback = FALSE; +static char g_uri[MAX_STRING_LEN]; +static char g_subtitle_uri[MAX_STRING_LEN]; +static FILE *g_pcm_fd; + +static gboolean is_es_push_mode = FALSE; +static pthread_t g_feed_video_thread_id = 0; +static bool g_thread_end = FALSE; +static media_packet_h g_audio_pkt = NULL; +static media_format_h g_audio_fmt = NULL; + +static media_packet_h g_video_pkt = NULL; +static media_format_h g_video_fmt = NULL; + +#define DUMP_OUTBUF 1 +#if DUMP_OUTBUF +FILE *fp_out1 = NULL; +FILE *fp_out2 = NULL; +#endif + enum { CURRENT_STATUS_MAINMENU, @@ -53,76 +75,78 @@ enum CURRENT_STATUS_DISPLAY_SRC_CROP, CURRENT_STATUS_SUBTITLE_FILENAME, CURRENT_STATUS_AUDIO_EQUALIZER, + CURRENT_STATUS_PLAYBACK_RATE, + CURRENT_STATUS_SWITCH_AUDIO, + CURRENT_STATUS_SWITCH_SUBTITLE, }; #define MAX_HANDLE 20 /* for video display */ #ifdef _USE_X_DIRECT_ -Window g_xid; -Display *g_dpy; -GC g_gc; +static Window g_xid; +static Display *g_dpy; +static GC g_gc; #else -Evas_Object* g_xid; +static Evas_Object* g_xid; +#ifdef _ACTIVATE_EOM_ +static Evas_Object* g_external_xid; +#endif +static Evas_Object* selected_xid; #endif -Evas_Object* g_eo_win; -Evas_Object* g_eo[MAX_HANDLE] = {0}; -int g_current_surface_type = PLAYER_DISPLAY_TYPE_OVERLAY; +static Evas_Object* g_eo[MAX_HANDLE] = {0}; +static int g_current_surface_type = PLAYER_DISPLAY_TYPE_OVERLAY; -struct appdata +typedef struct { - Evas_Object *win; - Evas_Object *bg; - Evas_Object *rect; - Evas_Object *layout_main; /* layout widget based on EDJ */ Ecore_X_Window xid; /* add more variables here */ -}; - -static Evas_Object *create_bg(Evas_Object *pParent) -{ - if(!pParent) { - return NULL; - } +#ifdef _ACTIVATE_EOM_ + int hdmi_output_id; +#endif + char * file; +} appdata; - Evas_Object *pObj = NULL; +static appdata ad; +static player_h g_player[MAX_HANDLE] = {0}; +int g_handle_num = 1; +int g_menu_state = CURRENT_STATUS_MAINMENU; +char g_file_list[9][256]; +gboolean quit_pushing; - pObj = elm_bg_add(pParent); - evas_object_size_hint_weight_set(pObj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_win_resize_object_add(pParent, pObj); - evas_object_color_set(pObj, 0, 0, 0, 0); - evas_object_show(pObj); - return pObj; -} +static void input_filename(char *filename); +static void _player_prepare(bool async); +static void _player_play(); static void win_del(void *data, Evas_Object *obj, void *event) { - elm_exit(); + elm_exit(); } static Evas_Object* create_win(const char *name) { Evas_Object *eo = NULL; - printf ("[%s][%d] name=%s\n", __func__, __LINE__, name); + printf ("[%s][%d] name=%s\n", __func__, __LINE__, name); - eo = elm_win_add(NULL, name, ELM_WIN_BASIC); - if (eo) { - elm_win_title_set(eo, name); - elm_win_borderless_set(eo, EINA_TRUE); - evas_object_smart_callback_add(eo, "delete,request",win_del, NULL); - elm_win_autodel_set(eo, EINA_TRUE); - } - return eo; + eo = elm_win_add(NULL, name, ELM_WIN_BASIC); + if (eo) + { + elm_win_title_set(eo, name); + elm_win_borderless_set(eo, EINA_TRUE); + evas_object_smart_callback_add(eo, "delete,request",win_del, NULL); + elm_win_autodel_set(eo, EINA_TRUE); + } + return eo; } static Evas_Object *create_image_object(Evas_Object *eo_parent) { - if(!eo_parent) { + if(!eo_parent) return NULL; - } + Evas *evas = evas_object_evas_get(eo_parent); Evas_Object *eo = NULL; @@ -131,44 +155,282 @@ static Evas_Object *create_image_object(Evas_Object *eo_parent) return eo; } -static Evas_Object *create_render_rect(Evas_Object *pParent) +void +create_render_rect_and_bg (Evas_Object* win) { - if(!pParent) { - return NULL; + if(!win) + { + g_print("no win"); + return; } + Evas_Object *bg, *rect; - Evas *pEvas = evas_object_evas_get(pParent); - Evas_Object *pObj = evas_object_rectangle_add(pEvas); - if(pObj == NULL) { - return NULL; + bg = elm_bg_add (win); + elm_win_resize_object_add (win, bg); + evas_object_size_hint_weight_set (bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show (bg); + + rect = evas_object_rectangle_add (evas_object_evas_get(win)); + if(!rect) + { + g_print("no rect"); + return; } + evas_object_color_set (rect, 0, 0, 0, 0); + evas_object_render_op_set (rect, EVAS_RENDER_COPY); - evas_object_size_hint_weight_set(pObj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_color_set(pObj, 0, 0, 0, 0); - evas_object_render_op_set(pObj, EVAS_RENDER_COPY); - evas_object_show(pObj); - elm_win_resize_object_add(pParent, pObj); + elm_win_resize_object_add (win, rect); + evas_object_size_hint_weight_set (rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show (rect); + evas_object_show (win); +} +#ifdef _ACTIVATE_EOM_ +int +eom_get_output_id (const char *output_name) +{ + eom_output_id *output_ids = NULL; + eom_output_id output_id = 0; + eom_output_type_e output_type = EOM_OUTPUT_TYPE_UNKNOWN; + int id_cnt = 0; + int i; - return pObj; + /* get output_ids */ + output_ids = eom_get_eom_output_ids(&id_cnt); + if (id_cnt == 0) + { + g_print ("[eom] no external outuputs supported\n"); + return 0; + } + + /* find output ids interested */ + for (i = 0; i < id_cnt; i++) + { + eom_get_output_type(output_ids[i], &output_type); + if (!strncmp(output_name, "HDMI", 4)) + { + if (output_type == EOM_OUTPUT_TYPE_HDMIA || output_type == EOM_OUTPUT_TYPE_HDMIB) + { + output_id = output_ids[i]; + break; + } + } + else if (!strncmp(output_name, "Virtual", 4)) + { + if (output_type == EOM_OUTPUT_TYPE_VIRTUAL) + { + output_id = output_ids[i]; + break; + } + } + } + + if (output_ids) + free (output_ids); + + return output_id; +} + +static void +eom_notify_cb_output_add (eom_output_id output_id, void *user_data) +{ + appdata *info = (appdata*)user_data; + + if (info->hdmi_output_id != output_id) + { + g_print ("[eom] OUTPUT ADDED. SKIP. my output ID is %d\n", info->hdmi_output_id); + return; + } + g_print ("[eom] output(%d) connected\n", output_id); + /* it is for external window */ + if (!g_external_xid) + { + g_external_xid = elm_win_add(NULL, "External", ELM_WIN_BASIC); + if (eom_set_output_window(info->hdmi_output_id, g_external_xid) == EOM_ERROR_NONE) + { + create_render_rect_and_bg(g_external_xid); + g_print ("[eom] create external window\n"); + } + else + { + evas_object_del (g_external_xid); + g_external_xid = NULL; + g_print ("[eom] create external window fail\n"); + } + } +} + +static void +eom_notify_cb_output_remove (eom_output_id output_id, void *user_data) +{ + appdata *info = (appdata*)user_data; + player_state_e state; + + if (info->hdmi_output_id != output_id) + { + g_print ("[eom] OUTPUT REMOVED. SKIP. my output ID is %d\n", info->hdmi_output_id); + return; + } + g_print ("[eom] output(%d) disconnected\n", output_id); + + if(selected_xid==g_external_xid && g_player[0]) + { + player_get_state(g_player[0], &state); + if (state>=PLAYER_STATE_READY) + { + if(!g_xid) + { + g_xid = create_win(PACKAGE); + if (g_xid == NULL) + return; + g_print("create xid %p\n", g_xid); + create_render_rect_and_bg(g_xid); + elm_win_activate(g_xid); + evas_object_show(g_xid); + } + player_set_display(g_player[0], PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(g_xid)); + } + } + + /* it is for external window */ + if (g_external_xid) + { + evas_object_del(g_external_xid); + g_external_xid = NULL; + } + selected_xid = g_xid; } +static void +eom_notify_cb_mode_changed (eom_output_id output_id, void *user_data) +{ + appdata *info = (appdata*)user_data; + eom_output_mode_e mode = EOM_OUTPUT_MODE_NONE; + + if (info->hdmi_output_id != output_id) + { + g_print ("[eom] MODE CHANGED. SKIP. my output ID is %d\n", info->hdmi_output_id); + return; + } + + eom_get_output_mode(output_id, &mode); + g_print ("[eom] output(%d) mode changed(%d)\n", output_id, mode); +} + +static void +eom_notify_cb_attribute_changed (eom_output_id output_id, void *user_data) +{ + appdata *info = (appdata*)user_data; + + eom_output_attribute_e attribute = EOM_OUTPUT_ATTRIBUTE_NONE; + eom_output_attribute_state_e state = EOM_OUTPUT_ATTRIBUTE_STATE_NONE; + + if (info->hdmi_output_id != output_id) + { + g_print ("[eom] ATTR CHANGED. SKIP. my output ID is %d\n", info->hdmi_output_id); + return; + } + + eom_get_output_attribute(output_id, &attribute); + eom_get_output_attribute_state(output_id, &state); + + g_print ("[eom] output(%d) attribute changed(%d, %d)\n", output_id, attribute, state); + if (state == EOM_OUTPUT_ATTRIBUTE_STATE_ACTIVE) + { + g_print ("[eom] active\n"); + if (!g_external_xid) + { + g_external_xid = elm_win_add(NULL, "External", ELM_WIN_BASIC); + if (eom_set_output_window(info->hdmi_output_id, g_external_xid) == EOM_ERROR_NONE) + { + create_render_rect_and_bg(g_external_xid); + g_print ("[eom] create external window\n"); + } + else + { + evas_object_del (g_external_xid); + g_external_xid = NULL; + g_print ("[eom] create external window fail\n"); + } + } + selected_xid = g_external_xid; + /* play video on external window */ + if (g_player[0]) + player_set_display(g_player[0], PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(selected_xid)); + } + else if (state == EOM_OUTPUT_ATTRIBUTE_STATE_INACTIVE) + { + g_print ("[eom] inactive\n"); + if(!g_xid) + { + g_xid = create_win(PACKAGE); + if (g_xid == NULL) + return; + g_print("create xid %p\n", g_xid); + create_render_rect_and_bg(g_xid); + elm_win_activate(g_xid); + evas_object_show(g_xid); + } + selected_xid = g_xid; + if (g_player[0]) + player_set_display(g_player[0], PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(selected_xid)); + + if (g_external_xid) + { + evas_object_del(g_external_xid); + g_external_xid = NULL; + } + } + else if (state == EOM_OUTPUT_ATTRIBUTE_STATE_LOST) + { + g_print ("[eom] lost\n"); + if(!g_xid) + { + g_xid = create_win(PACKAGE); + if (g_xid == NULL) + return; + g_print("create xid %p\n", g_xid); + create_render_rect_and_bg(g_xid); + elm_win_activate(g_xid); + evas_object_show(g_xid); + } + selected_xid = g_xid; + + if (g_player[0]) + player_set_display(g_player[0], PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(selected_xid)); + + if (g_external_xid) + { + evas_object_del(g_external_xid); + g_external_xid = NULL; + } + + eom_unset_output_added_cb(eom_notify_cb_output_add); + eom_unset_output_removed_cb(eom_notify_cb_output_remove); + eom_unset_mode_changed_cb(eom_notify_cb_mode_changed); + eom_unset_attribute_changed_cb(eom_notify_cb_attribute_changed); + + eom_deinit (); + } +} +#endif static int app_create(void *data) { - struct appdata *ad = data; + appdata *ad = data; Evas_Object *win = NULL; - +#ifdef _ACTIVATE_EOM_ + eom_output_mode_e output_mode = EOM_OUTPUT_MODE_NONE; +#endif /* use gl backend */ - elm_config_preferred_engine_set("opengl_x11"); + elm_config_preferred_engine_set("3d"); /* create window */ win = create_win(PACKAGE); if (win == NULL) - return -1; + return -1; ad->win = win; - g_eo_win = win; - ad->bg = create_bg(ad->win); - ad->rect = create_render_rect(ad->win); - g_xid = g_eo_win; + g_xid = win; + selected_xid = g_xid; + create_render_rect_and_bg(ad->win); /* Create evas image object for EVAS surface */ g_eo[0] = create_image_object(ad->win); evas_object_image_size_set(g_eo[0], 500, 500); @@ -177,13 +439,59 @@ static int app_create(void *data) elm_win_activate(win); evas_object_show(win); +#ifdef _ACTIVATE_EOM_ + /* check external device */ + eom_init (); + ad->hdmi_output_id = eom_get_output_id ("HDMI"); + if (ad->hdmi_output_id == 0) + { + g_print ("[eom] error : HDMI output id is NULL.\n"); + return 0; + } + + g_print ("eom_set_output_attribute EOM_OUTPUT_ATTRIBUTE_NORMAL(id:%d)\n", ad->hdmi_output_id); + if (eom_set_output_attribute(ad->hdmi_output_id, EOM_OUTPUT_ATTRIBUTE_NORMAL) != EOM_ERROR_NONE) + { + g_print ("attribute set fail. cannot use external output\n"); + eom_deinit (); + } + eom_get_output_mode(ad->hdmi_output_id, &output_mode); + if (output_mode != EOM_OUTPUT_MODE_NONE) + { + g_external_xid = elm_win_add(NULL, "External", ELM_WIN_BASIC); + if (eom_set_output_window(ad->hdmi_output_id, g_external_xid) == EOM_ERROR_NONE) + { + create_render_rect_and_bg(g_external_xid); + g_print ("[eom] create external window\n"); + } + else + { + evas_object_del (g_external_xid); + g_external_xid = NULL; + g_print ("[eom] create external window fail\n"); + } + selected_xid = g_external_xid; + } + + /* set callback for detecting external device */ + eom_set_output_added_cb(eom_notify_cb_output_add, ad); + eom_set_output_removed_cb(eom_notify_cb_output_remove, ad); + eom_set_mode_changed_cb(eom_notify_cb_mode_changed, ad); + eom_set_attribute_changed_cb(eom_notify_cb_attribute_changed, ad); +#endif + if(ad->file) + { + input_filename(ad->file); + _player_prepare(FALSE); + _player_play(); + } return 0; } static int app_terminate(void *data) { - struct appdata *ad = data; + appdata *ad = data; int i = 0; for (i = 0 ; i < MAX_HANDLE; i++) @@ -194,11 +502,18 @@ static int app_terminate(void *data) g_eo[i] = NULL; } } - if (g_eo_win) { - evas_object_del(g_eo_win); - g_eo_win = NULL; + if (g_xid) { + evas_object_del(g_xid); + g_xid = NULL; } +#ifdef _ACTIVATE_EOM_ + if (g_external_xid) { + evas_object_del(g_external_xid); + g_external_xid = NULL; + } +#endif ad->win = NULL; + selected_xid = NULL; #ifdef _USE_X_DIRECT_ if(g_dpy) { @@ -211,6 +526,14 @@ static int app_terminate(void *data) g_dpy = NULL; } #endif +#ifdef _ACTIVATE_EOM_ + eom_unset_output_added_cb(eom_notify_cb_output_add); + eom_unset_output_removed_cb(eom_notify_cb_output_remove); + eom_unset_mode_changed_cb(eom_notify_cb_mode_changed); + eom_unset_attribute_changed_cb(eom_notify_cb_attribute_changed); + + eom_deinit (); +#endif return 0; } @@ -219,18 +542,27 @@ struct appcore_ops ops = { .terminate = app_terminate, }; -struct appdata ad; -static player_h g_player[MAX_HANDLE] = {0}; -int g_handle_num = 1; -int g_menu_state = CURRENT_STATUS_MAINMENU; -char g_file_list[9][256]; -gboolean quit_pushing; - static void prepared_cb(void *user_data) { g_print("[Player_Test] prepared_cb!!!!\n"); } +static void _audio_frame_decoded_cb_ex(player_audio_raw_data_s *audio_raw_frame, void *user_data) +{ + player_audio_raw_data_s* audio_raw = audio_raw_frame; + + if (!audio_raw) return; + + g_print("[Player_Test] decoded_cb_ex! channel: %d channel_mask: %" G_GUINT64_FORMAT "\n", audio_raw->channel, audio_raw->channel_mask); + +#ifdef DUMP_OUTBUF + if(audio_raw->channel_mask == 1) + fwrite((guint8 *)audio_raw->data, 1, audio_raw->size, fp_out1); + else if(audio_raw->channel_mask == 2) + fwrite((guint8 *)audio_raw->data, 1, audio_raw->size, fp_out2); +#endif +} + static void progress_down_cb(player_pd_message_type_e type, void *user_data) { g_print("[Player_Test] progress_down_cb!!!! type : %d\n", type); @@ -303,7 +635,7 @@ int _save(unsigned char * src, int length) else { g_print("open success\n"); - if(fwrite(src, 1, length, fp )!=1) + if(fwrite(src, 1, length, fp ) < 1) { g_print("file write error!!\n"); fclose(fp); @@ -401,28 +733,245 @@ static void input_filename(char *filename) for (i = 0; i < g_handle_num; i++) { ret = player_get_state(g_player[i], &state); - g_print("player_get_state returned [%d]", ret); + g_print("player_get_state returned [%d]\n", ret); g_print("1. After player_create() - Current State : %d \n", state); } } -#if 0 + // use this API instead of player_set_uri static void player_set_memory_buffer_test() { - if(!g_uri) - g_print("g_uri is NULL\n"); GMappedFile *file; gsize file_size; guint8* g_media_mem = NULL; - file = g_mapped_file_new (g_uri, FALSE, NULL); + file = g_mapped_file_new (g_uri, FALSE, NULL); file_size = g_mapped_file_get_length (file); g_media_mem = (guint8 *) g_mapped_file_get_contents (file); int ret = player_set_memory_buffer(g_player[0], (void*)g_media_mem, file_size); g_print("player_set_memory_buffer ret : %d\n", ret); } + +int video_packet_count = 0; + +static void buffer_need_video_data_cb(unsigned int size, void *user_data) +{ + int real_read_len = 0; + char fname[128]; + char fptsname[128]; + static guint64 pts = 0L; + + FILE *fp = NULL; + guint8 *buff_ptr = NULL; + void *src = NULL; + + memset(fname, 0, 128); + memset(fptsname, 0, 128); + + video_packet_count++; + + if (video_packet_count > 1000) + { + g_print("EOS.\n"); +// player_submit_packet(g_player[0], NULL, 0, 0, 1); + player_push_media_stream(g_player[0], NULL); + g_thread_end = TRUE; + } +// snprintf(fname, 128, "/opt/storage/usb/test/packet/packet_%d.dat", video_packet_count); +// snprintf(fptsname, 128, "/opt/storage/usb/test/packet/gstpts_%d.dat", video_packet_count); + snprintf(fname, 128, "/home/developer/test/packet/packet_%d.dat", video_packet_count); + snprintf(fptsname, 128, "/home/developer/test/packet/gstpts_%d.dat", video_packet_count); + + fp = fopen(fptsname, "rb"); + if (fp) + { + int pts_len = 0; + pts_len = fread(&pts, 1, sizeof(guint64), fp); + if (pts_len != sizeof(guint64)) + { + g_print("Warning, pts value can be wrong.\n"); + } + fclose(fp); + fp = NULL; + } + + fp = fopen(fname, "rb"); + if (fp) + { + buff_ptr = (guint8 *)g_malloc0(1048576); + real_read_len = fread(buff_ptr, 1, size, fp); + fclose(fp); + fp = NULL; + } + g_print("video need data - data size : %d, pts : %" G_GUINT64_FORMAT "\n", real_read_len, pts); +#if 0 + player_submit_packet(g_player[0], buff_ptr, real_read_len, (pts/1000000), 1); +#else + /* create media packet */ + if (g_video_pkt) { + media_packet_destroy(g_video_pkt); + g_video_pkt = NULL; + } + + media_packet_create_alloc(g_video_fmt, NULL, NULL, &g_video_pkt); + + g_print("packet = %p, src = %p\n", g_video_pkt, src); + + + if (media_packet_get_buffer_data_ptr(g_video_pkt, &src) != MEDIA_PACKET_ERROR_NONE) + return; + + if (media_packet_set_pts(g_video_pkt, (uint64_t)(pts/1000000)) != MEDIA_PACKET_ERROR_NONE) + return; + + if (media_packet_set_buffer_size(g_video_pkt, (uint64_t)real_read_len) != MEDIA_PACKET_ERROR_NONE) + return; + + memcpy(src, buff_ptr, real_read_len); + + /* then, push it */ + player_push_media_stream(g_player[0], g_video_pkt); +#endif + + if (buff_ptr) + { + g_free(buff_ptr); + buff_ptr = NULL; + } +} + +int audio_packet_count = 0; +static void buffer_need_audio_data_cb(unsigned int size, void *user_data) +{ + int real_read_len = 0; + char fname[128]; + FILE *fp = NULL; + guint8 *buff_ptr = NULL; + void *src = NULL; + + memset(fname, 0, 128); + audio_packet_count++; + + if (audio_packet_count > 1000) + { + g_print("EOS.\n"); +// player_submit_packet(g_player[0], NULL, 0, 0, 0); + player_push_media_stream(g_player[0], NULL); + g_thread_end = TRUE; + } + +// snprintf(fname, 128, "/opt/storage/usb/test/audio_packet/packet_%d.dat", audio_packet_count); + snprintf(fname, 128, "/home/developer/test/audio_packet/packet_%d.dat", audio_packet_count); + + static guint64 audio_pts = 0; + guint64 audio_dur = 21333333; + + fp = fopen(fname, "rb"); + if (fp) + { + buff_ptr = (guint8 *)g_malloc0(1048576); + real_read_len = fread(buff_ptr, 1, size, fp); + fclose(fp); + fp = NULL; + + g_print("\t audio need data - data size : %d, pts : %" G_GUINT64_FORMAT "\n", real_read_len, audio_pts); + } +#if 0 + player_submit_packet(g_player[0], buff_ptr, real_read_len, (audio_pts/1000000), 0); +#else + /* create media packet */ + if (g_audio_pkt) { + media_packet_destroy(g_audio_pkt); + g_audio_pkt = NULL; + } + media_packet_create_alloc(g_audio_fmt, NULL, NULL, &g_audio_pkt); + + g_print("packet = %p, src = %p\n", g_audio_pkt, src); + + + if (media_packet_get_buffer_data_ptr(g_audio_pkt, &src) != MEDIA_PACKET_ERROR_NONE) + return; + + if (media_packet_set_pts(g_audio_pkt, (uint64_t)(audio_pts/1000000)) != MEDIA_PACKET_ERROR_NONE) + return; + + if (media_packet_set_buffer_size(g_audio_pkt, (uint64_t)real_read_len) != MEDIA_PACKET_ERROR_NONE) + return; + + memcpy(src, buff_ptr, real_read_len); + + /* then, push it */ + player_push_media_stream(g_player[0], g_audio_pkt); #endif + + audio_pts += audio_dur; + + if (buff_ptr) + { + g_free(buff_ptr); + buff_ptr = NULL; + } +} + +static void set_content_info(bool is_push_mode) +{ + /* testcode for es buff src case, please input url as es_buff://123 or es_buff://push_mode */ +// unsigned char codec_data[45] = {0x0,0x0,0x1,0xb0,0x1,0x0,0x0,0x1,0xb5,0x89,0x13,0x0,0x0,0x1,0x0,0x0,0x0,0x1,0x20,0x0,0xc4,0x8d,0x88,0x5d,0xad,0x14,0x4,0x22,0x14,0x43,0x0,0x0,0x1,0xb2,0x4c,0x61,0x76,0x63,0x35,0x31,0x2e,0x34,0x30,0x2e,0x34}; + + /* create media format */ + media_format_create(&g_audio_fmt); + media_format_create(&g_video_fmt); + + //Video + /* configure media format for video and set to player */ + media_format_set_video_mime(g_video_fmt, MEDIA_FORMAT_MPEG4_SP); + media_format_set_video_width(g_video_fmt, 640); + media_format_set_video_height(g_video_fmt,272); +// player_set_media_stream_info(g_player[0], PLAYER_STREAM_TYPE_VIDEO, g_video_fmt); + + //Audio--aac--StarWars.mp4 + media_format_set_audio_mime(g_audio_fmt, MEDIA_FORMAT_AAC); + media_format_set_audio_channel(g_audio_fmt, 2); + media_format_set_audio_samplerate(g_audio_fmt, 48000); +// player_set_media_stream_info(g_player[0], PLAYER_STREAM_TYPE_AUDIO, g_audio_fmt); +#if 0 +// video_info->mime = g_strdup("video/mpeg"); //CODEC_ID_MPEG4VIDEO + video_info->width = 640; + video_info->height = 272; + video_info->version = 4; + video_info->framerate_den = 100; + video_info->framerate_num = 2997; + + video_info->extradata_size = 45; + video_info->codec_extradata = codec_data; + player_set_video_stream_info(g_player[0], video_info); + + + //audio--aac--StarWars.mp4 +// audio_info->mime = g_strdup("audio/mpeg"); + //audio_info->version = 2; +// audio_info->user_info = 0; //raw +#endif + +#ifdef _ES_PULL_ + if (!is_push_mode) + { + player_set_buffer_need_video_data_cb(g_player[0], buffer_need_video_data_cb, (void*)g_player[0]); + player_set_buffer_need_audio_data_cb(g_player[0], buffer_need_audio_data_cb, (void*)g_player[0]); + } +#endif +} + +static void feed_video_data_thread_func(void *data) +{ + while (!g_thread_end) + { + buffer_need_video_data_cb(1048576, NULL); + buffer_need_audio_data_cb(1048576, NULL); + } +} + static void _player_prepare(bool async) { int ret = FALSE; @@ -436,13 +985,15 @@ static void _player_prepare(bool async) } if (g_current_surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) { - player_set_display(g_player[0], g_current_surface_type, GET_DISPLAY(g_xid)); + player_set_display(g_player[0], g_current_surface_type, GET_DISPLAY(selected_xid)); player_set_buffering_cb(g_player[0], buffering_cb, (void*)g_player[0]); player_set_completed_cb(g_player[0], completed_cb, (void*)g_player[0]); player_set_interrupted_cb(g_player[0], interrupted_cb, (void*)g_player[0]); player_set_error_cb(g_player[0], error_cb, (void*)g_player[0]); - player_set_uri(g_player[0], g_uri); - //player_set_memory_buffer_test(); + if (g_memory_playback) + player_set_memory_buffer_test(); + else + player_set_uri(g_player[0], g_uri); } else { @@ -454,11 +1005,33 @@ static void _player_prepare(bool async) player_set_completed_cb(g_player[i], completed_cb, (void*)g_player[i]); player_set_interrupted_cb(g_player[i], interrupted_cb, (void*)g_player[i]); player_set_error_cb(g_player[i], error_cb, (void*)g_player[i]); - player_set_uri(g_player[i], g_uri); - //player_set_memory_buffer_test(); + if (g_memory_playback) + player_set_memory_buffer_test(); + else + player_set_uri(g_player[i], g_uri); } } + if (strstr(g_uri, "es_buff://")) + { + is_es_push_mode = FALSE; + video_packet_count = 0; + audio_packet_count = 0; + + if (strstr(g_uri, "es_buff://push_mode")) + { + set_content_info(TRUE); + async = TRUE; + is_es_push_mode = TRUE; + } +#ifdef _ES_PULL_ + else + { + set_content_info(FALSE); + } +#endif + } + if (g_current_surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) { if ( async ) @@ -502,6 +1075,10 @@ static void _player_prepare(bool async) } } + if (is_es_push_mode) { + pthread_create(&g_feed_video_thread_id, NULL, (void*)feed_video_data_thread_func, NULL); + } + } static void _player_unprepare() @@ -529,7 +1106,6 @@ static void _player_unprepare() ret = player_unset_error_cb(g_player[0]); g_print("player_unset_error_cb ret %d\n", ret); - } else { @@ -559,7 +1135,7 @@ static void _player_unprepare() } } } - reset_display(); + reset_display(); //attention! surface(evas) -> unprepare -> surface(evas) : evas object will disappear. memset(g_subtitle_uri, 0 , sizeof(g_subtitle_uri)); player_state_e state; if (g_current_surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) @@ -580,6 +1156,7 @@ static void _player_unprepare() static void _player_destroy() { int i = 0; + if (g_current_surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) { player_unprepare(g_player[0]); @@ -601,6 +1178,20 @@ static void _player_destroy() } } } + + if (g_video_pkt) + media_packet_destroy(g_video_pkt); + + if (g_audio_pkt) + media_packet_destroy(g_audio_pkt); + +#if DUMP_OUTBUF + if (fp_out1) + fclose(fp_out1); + if (fp_out2) + fclose(fp_out2); +#endif + } static void _player_play() @@ -609,6 +1200,8 @@ static void _player_play() int i = 0; if (g_current_surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) { + //for checking external display.... + player_set_display(g_player[0], g_current_surface_type, GET_DISPLAY(selected_xid)); bRet = player_start(g_player[0]); g_print("player_start returned [%d]", bRet); } @@ -639,6 +1232,14 @@ static void _player_stop() g_print("player_stop returned [%d]", bRet); } } + + g_thread_end = TRUE; + if (g_feed_video_thread_id) + { + pthread_join(g_feed_video_thread_id, NULL); + g_feed_video_thread_id = 0; + } + } static void _player_resume() @@ -647,6 +1248,8 @@ static void _player_resume() int i = 0; if (g_current_surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) { + //for checking external display.... + player_set_display(g_player[0], PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(selected_xid)); bRet = player_start(g_player[0]); g_print("player_start returned [%d]", bRet); } @@ -692,6 +1295,15 @@ static void _player_set_progressive_download() player_set_progressive_download_message_cb(g_player[0], progress_down_cb, (void*)g_player[0]); } +static void _player_get_streaming_download_progress(void) +{ + int start = 0; + int current = 0; + + player_get_streaming_download_progress(g_player[0], &start, ¤t); + g_print(" ==> [Player_Test] download progress : %d / %d\n", start, current); +} + static void set_volume(float volume) { if ( player_set_volume(g_player[0], volume, volume) != PLAYER_ERROR_NONE ) @@ -746,6 +1358,14 @@ static void set_position(int position) } } +static void set_playback_rate(float rate) +{ + if ( player_set_playback_rate(g_player[0], rate) != PLAYER_ERROR_NONE ) + { + g_print("failed to set playback rate\n"); + } +} + static void get_duration() { int duration = 0; @@ -755,6 +1375,27 @@ static void get_duration() g_print(" ==> [Player_Test] Duration: [%d ] msec\n",duration); } +static void audio_frame_decoded_cb_ex() +{ + int ret; + +#if DUMP_OUTBUF + fp_out1 = fopen("/opt/usr/media/out1.pcm", "wb"); + fp_out2 = fopen("/opt/usr/media/out2.pcm", "wb"); +#endif + + ret = player_set_pcm_extraction_mode(g_player[0], false, _audio_frame_decoded_cb_ex, &ret); + g_print(" ==> [Player_Test] player_set_audio_frame_decoded_cb_ex return: %d\n", ret); +} + +static void set_pcm_spec() +{ + int ret; + + ret = player_set_pcm_spec(g_player[0], "F32LE", 44100, 2); + g_print("[Player_Test] set_pcm_spec return: %d\n", ret); +} + static void get_stream_info() { int w = 0; @@ -842,17 +1483,26 @@ static void change_surface(int option) { player_display_type_e surface_type = 0; int ret = PLAYER_ERROR_NONE; - +#ifdef _ACTIVATE_EOM_ + int hdmi_output_id; + eom_output_mode_e output_mode; +#endif switch (option) { case 0: /* X surface */ surface_type = PLAYER_DISPLAY_TYPE_OVERLAY; g_print("change surface type to X\n"); break; +#ifdef TIZEN_MOBILE case 1: /* EVAS surface */ surface_type = PLAYER_DISPLAY_TYPE_EVAS; g_print("change surface type to EVAS\n"); break; +#endif + case 2: + g_print("change surface type to NONE\n"); + player_set_display(g_player[0], PLAYER_DISPLAY_TYPE_NONE, NULL); + break; default: g_print("invalid surface type\n"); return; @@ -871,58 +1521,87 @@ static void change_surface(int option) { g_print("failed to player_get_state(), ret(0x%x)\n", ret); } - /* state check */ - if (player_state == PLAYER_STATE_NONE || player_state == PLAYER_STATE_IDLE ) - { - reset_display(); + reset_display(); - if (surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) - { + if (surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) + { #ifdef _USE_X_DIRECT_ - /* Create xwindow for X surface */ - if(!g_dpy) - { - g_dpy = XOpenDisplay (NULL); - g_xid = create_window (g_dpy, 0, 0, 500, 500); - g_gc = XCreateGC (g_dpy, g_xid, 0, 0); - } - g_print("create x window dpy(%p), gc(%x), xid(%d)\n", g_dpy, (unsigned int)g_gc, (int)g_xid); - XImage *xim = make_transparent_image (g_dpy, 500, 500); - XPutImage (g_dpy, g_xid, g_gc, xim, 0, 0, 0, 0, 500, 500); - XSync (g_dpy, False); + /* Create xwindow for X surface */ + if(!g_dpy) + { + g_dpy = XOpenDisplay (NULL); + g_xid = create_window (g_dpy, 0, 0, 500, 500); + g_gc = XCreateGC (g_dpy, g_xid, 0, 0); + } + g_print("create x window dpy(%p), gc(%x), xid(%d)\n", g_dpy, (unsigned int)g_gc, (int)g_xid); + XImage *xim = make_transparent_image (g_dpy, 500, 500); + XPutImage (g_dpy, g_xid, g_gc, xim, 0, 0, 0, 0, 500, 500); + XSync (g_dpy, False); #else - g_xid = g_eo_win; +#ifdef _ACTIVATE_EOM_ + hdmi_output_id = eom_get_output_id ("HDMI"); + if (hdmi_output_id == 0) + g_print ("[eom] error : HDMI output id is NULL.\n"); + + eom_get_output_mode(hdmi_output_id, &output_mode); + if (output_mode == EOM_OUTPUT_MODE_NONE) #endif - ret = player_set_display(g_player[0], surface_type, GET_DISPLAY(g_xid)); - } - else { - int i = 0; - for (i = 0; i < g_handle_num ; i++) + if(!g_xid) { - /* Create evas image object for EVAS surface */ - if (!g_eo[i]) - { - g_eo[i] = create_image_object(g_eo_win); - evas_object_image_size_set(g_eo[i], 500, 500); - evas_object_image_fill_set(g_eo[i], 0, 0, 500, 500); - evas_object_resize(g_eo[i], 500, 500); - evas_object_move(g_eo[i], i*20, i*20); - } - ret = player_set_display(g_player[i], surface_type, g_eo[i]); + g_xid = create_win(PACKAGE); + if (g_xid == NULL) + return; + g_print("create xid %p\n", g_xid); + create_render_rect_and_bg(g_xid); + elm_win_activate(g_xid); + evas_object_show(g_xid); + g_xid = selected_xid; } } - if (ret) +#ifdef _ACTIVATE_EOM_ + else { - g_print("failed to set display, surface_type(%d)\n", surface_type); - return; + //for external } - g_current_surface_type = surface_type; +#endif +#endif + ret = player_set_display(g_player[0], surface_type, GET_DISPLAY(selected_xid)); } else { - g_print("could not change surface type, current_state(%d)\n", player_state); + if(!g_xid) + { + g_xid = create_win(PACKAGE); + if (g_xid == NULL) + return; + g_print("create xid %p\n", g_xid); + create_render_rect_and_bg(g_xid); + elm_win_activate(g_xid); + evas_object_show(g_xid); + } + int i = 0; + for (i = 0; i < g_handle_num ; i++) + { + /* Create evas image object for EVAS surface */ + if (!g_eo[i]) + { + g_eo[i] = create_image_object(g_xid); + g_print("create eo[%d] %p\n", i, g_eo[i]); + evas_object_image_size_set(g_eo[i], 500, 500); + evas_object_image_fill_set(g_eo[i], 0, 0, 500, 500); + evas_object_resize(g_eo[i], 500, 500); + evas_object_move(g_eo[i], i*20, i*20); + } + ret = player_set_display(g_player[i], surface_type, g_eo[i]); + } + } + if (ret) + { + g_print("failed to set display, surface_type(%d)\n", surface_type); + return; } + g_current_surface_type = surface_type; } return; } @@ -1061,12 +1740,84 @@ static void input_subtitle_filename(char *subtitle_filename) if ( len < 1 || len > MAX_STRING_LEN ) return; - + memset(g_subtitle_uri, 0 , sizeof(g_subtitle_uri)); strncpy (g_subtitle_uri, subtitle_filename,len); g_print("subtitle uri is set to %s\n", g_subtitle_uri); player_set_subtitle_path (g_player[0], g_subtitle_uri); } +static const char* get_track_name(player_stream_type_e type) +{ + switch(type) + { + case PLAYER_STREAM_TYPE_AUDIO: + return "Audio"; + case PLAYER_STREAM_TYPE_VIDEO: + return "Video"; + case PLAYER_STREAM_TYPE_TEXT: + return "Text"; + default: + return "Unknown"; + } +} + +static void get_track_info(void) +{ + char* lang_code = NULL; + player_stream_type_e type = PLAYER_STREAM_TYPE_AUDIO; + int count = 0, idx = 0, cur_index = 0; + + for (type = PLAYER_STREAM_TYPE_AUDIO; type <= PLAYER_STREAM_TYPE_TEXT; type++) + { + count = 0; + player_get_track_count (g_player[0], type, &count); + if (count) { + g_print("\n track: %s (num of tracks : %d)\n", get_track_name(type), count); + player_get_current_track (g_player[0], type, &cur_index); + + for (idx=0;idx track lang code %s %s\n", idx, lang_code, (cur_index==idx)?"**y**":" n "); + } else { + g_print("%d> track has no lang code\n", idx); + } + + if (lang_code) { + free(lang_code); + lang_code = NULL; + } + } + } + } +} + +static void switch_audio(int index) +{ + char* lang_code = NULL; + if (player_select_track (g_player[0], PLAYER_STREAM_TYPE_AUDIO, index) != PLAYER_ERROR_NONE) + { + g_print("player_select_track failed\n"); + } + if (player_get_track_language_code(g_player[0], PLAYER_STREAM_TYPE_AUDIO, index, &lang_code) == PLAYER_ERROR_NONE) { + g_print("selected track code %s\n", lang_code); + free(lang_code); + } +} + +static void switch_subtitle(int index) +{ + char* lang_code = NULL; + if (player_select_track (g_player[0], PLAYER_STREAM_TYPE_TEXT, index) != PLAYER_ERROR_NONE) + { + g_print("player_select_track failed\n"); + } + if (player_get_track_language_code(g_player[0], PLAYER_STREAM_TYPE_TEXT, index, &lang_code) == PLAYER_ERROR_NONE) { + g_print("selected track code %s\n", lang_code); + free(lang_code); + } +} + static void capture_video() { if( player_capture_video(g_player[0],video_captured_cb,NULL)!=PLAYER_ERROR_NONE) @@ -1160,6 +1911,12 @@ void quit_program() } } elm_exit(); + + if (g_audio_fmt) + media_format_unref(g_audio_fmt); + + if (g_video_fmt) + media_format_unref(g_video_fmt); } void play_with_ini(char *file_path) @@ -1362,7 +2119,7 @@ void _interpret_main_menu(char *cmd) } else if(len == 2) { - if (strncmp(cmd, "pr", 2) == 0) + if (strncmp(cmd, "pr", 2) == 0) { _player_prepare(FALSE); // sync } @@ -1382,6 +2139,15 @@ void _interpret_main_menu(char *cmd) { _player_set_progressive_download(); } + else if (strncmp(cmd, "dp", 2) == 0) + { + _player_get_streaming_download_progress(); + } + else if (strncmp(cmd, "mp", 2) == 0) + { + g_memory_playback = (g_memory_playback ? FALSE : TRUE); + g_print("memory playback = %d\n", g_memory_playback); + } else if (strncmp(cmd, "ds", 2) == 0 ) { g_menu_state = CURRENT_STATUS_DISPLAY_SURFACE_CHANGE; @@ -1390,7 +2156,31 @@ void _interpret_main_menu(char *cmd) { g_menu_state = CURRENT_STATUS_HANDLE_NUM; } - else + else if (strncmp(cmd, "tr", 2) == 0 ) + { + g_menu_state = CURRENT_STATUS_PLAYBACK_RATE; + } + else if (strncmp(cmd, "ti", 2) == 0 ) + { + get_track_info(); + } + else if (strncmp(cmd, "as", 2) == 0 ) + { + g_menu_state = CURRENT_STATUS_SWITCH_AUDIO; + } + else if (strncmp(cmd, "ss", 2) == 0 ) + { + g_menu_state = CURRENT_STATUS_SWITCH_SUBTITLE; + } + else if(strncmp(cmd, "X3", 2) == 0) + { + audio_frame_decoded_cb_ex(); + } + else if(strncmp(cmd, "X4", 2) == 0) + { + set_pcm_spec(); + } + else { g_print("unknown menu \n"); } @@ -1429,12 +2219,15 @@ void display_sub_basic() g_print("[ volume ] f. Set Volume\t"); g_print("g. Get Volume\t"); g_print("z. Set Sound type\t"); + g_print("k. Set Sound Stream Info.\t"); g_print("[ mute ] h. Set Mute\t"); g_print("i. Get Mute\n"); g_print("[audio eq] E. Set Audio EQ\t"); g_print("H. Get Audio EQ\n"); g_print("[position] j. Set Position \t"); - g_print("l. Get Position\n"); + g_print("l. Get Position \n"); + g_print("[streaming] dp. get download progress\n"); + g_print("[trick] tr. set playback rate\n"); g_print("[duration] m. Get Duration\n"); g_print("[Stream Info] n. Get stream info (Video Size, codec, audio stream info, and tag info)\n"); g_print("[Looping] o. Set Looping\t"); @@ -1445,10 +2238,14 @@ void display_sub_basic() g_print("[x display] r. Set display mode\t"); g_print("s. Get display mode\n"); g_print("[x display] t. Set display Rotation\t"); - g_print("[Track] tl. Get Track language info(single only)\n"); g_print("[subtitle] A. Set(or change) subtitle path\n"); + g_print("[Track] ti. Get Track Info.\t"); + g_print("as. Select(or change) Audio track.\t"); + g_print("ss. Select(or change) subtitle track\n"); g_print("[Video Capture] C. Capture \n"); - g_print("[etc] sp. Set Progressive Download\n"); + g_print("[etc] sp. Set Progressive Download\t"); + g_print("mp. memory playback\n"); + g_print("[audio_frame_decoded_cb_ex] X3. (input) set audio_frame_decoded_cb_ex callback \n"); g_print("\n"); g_print("=========================================================================================\n"); } @@ -1522,6 +2319,46 @@ static void displaymenu() { g_print(" *** input audio eq value.(0: UNSET, 1: SET) \n"); } + else if (g_menu_state == CURRENT_STATUS_PLAYBACK_RATE) + { + g_print(" *** input playback rate.(-5.0 ~ 5.0)\n"); + } + else if (g_menu_state == CURRENT_STATUS_SWITCH_AUDIO) + { + int count = 0, cur_index = 0; + int ret = 0; + + ret = player_get_track_count (g_player[0], PLAYER_STREAM_TYPE_AUDIO, &count); + if(ret!=PLAYER_ERROR_NONE) + g_print ("player_get_track_count fail!!!!\n"); + else if (count) + { + g_print ("Total audio tracks = %d \n", count); + player_get_current_track (g_player[0], PLAYER_STREAM_TYPE_AUDIO, &cur_index); + g_print ("Current index = %d \n", cur_index); + g_print (" *** input correct index 0 to %d\n:", (count - 1)); + } + else + g_print("no track\n"); + } + else if (g_menu_state == CURRENT_STATUS_SWITCH_SUBTITLE) + { + int count = 0, cur_index = 0; + int ret = 0; + + ret = player_get_track_count (g_player[0], PLAYER_STREAM_TYPE_TEXT, &count); + if(ret!=PLAYER_ERROR_NONE) + g_print ("player_get_track_count fail!!!!\n"); + else if (count) + { + g_print ("Total subtitle tracks = %d \n", count); + player_get_current_track (g_player[0], PLAYER_STREAM_TYPE_TEXT, &cur_index); + g_print ("Current index = %d \n", cur_index); + g_print (" *** input correct index 0 to %d\n:", (count - 1)); + } + else + g_print("no track\n"); + } else { g_print("*** unknown status.\n"); @@ -1725,6 +2562,27 @@ static void interpret (char *cmd) reset_menu_state(); } break; + case CURRENT_STATUS_PLAYBACK_RATE: + { + float rate = atof(cmd); + set_playback_rate(rate); + reset_menu_state(); + } + break; + case CURRENT_STATUS_SWITCH_AUDIO: + { + int index = atoi(cmd); + switch_audio(index); + reset_menu_state(); + } + break; + case CURRENT_STATUS_SWITCH_SUBTITLE: + { + int index = atoi(cmd); + switch_subtitle(index); + reset_menu_state(); + } + break; } g_timeout_add(100, timeout_menu_display, 0); } @@ -1751,7 +2609,9 @@ int main(int argc, char *argv[]) g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL); displaymenu(); - memset(&ad, 0x0, sizeof(struct appdata)); + memset(&ad, 0x0, sizeof(appdata)); + if(argv[1]) + ad.file = argv[1]; ops.data = &ad; return appcore_efl_main(PACKAGE, &argc, &argv, &ops); -- 2.7.4