} player_media_stream_buffer_status_e;
/**
+ * @brief Enumeration of audio extract option.
+ * @since_tizen 5.5
+ * @see player_set_media_packet_audio_frame_decoded_cb()
+ */
+typedef enum {
+ PLAYER_AUDIO_EXTRACT_DEFAULT = 0x00, /**< Sync with the playback clock and multichannel audio stream */
+ PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK = 0x01, /**< No sync with the playback clock */
+ PLAYER_AUDIO_EXTRACT_DEINTERLEAVE = 0x02, /**< Splits one interleaved multichannel audio stream into many mono audio streams */
+ PLAYER_AUDIO_EXTRACT_NO_SYNC_AND_DEINTERLEAVE = 0x03, /**< No sync with clock and splits into mono streams */
+} player_audio_extract_option_e;
+
+/**
* @}
*/
/**
* @brief Called when the video is captured.
* @since_tizen @if WEARABLE 2.3.1 @else 2.3 @endif
- * @remarks The color space format of the captured image is IMAGE_UTIL_COLORSPACE_RGB888.
+ * @remarks The color space format of the captured image is #IMAGE_UTIL_COLORSPACE_RGB888.
* @remarks The @a captured_data should not be released and it can be used only in the callback.
* To use outside, make a copy.
* @param[in] captured_data The captured image buffer
typedef void (*player_video_captured_cb)(unsigned char *captured_data, int width, int height, unsigned int size, void *user_data);
/**
- * @brief Called to register for notifications about delivering media packet when every video frame is decoded.
+ * @brief Called to register for notifications about delivering media packet when each video frame is decoded.
* @since_tizen @if WEARABLE 2.3.1 @else 2.3 @endif
* @remarks The UI update code must not be directly invoked.\n
* @remarks The @a packet should be released using media_packet_destroy(). \n
typedef void (*player_media_packet_video_decoded_cb)(media_packet_h packet, void *user_data);
/**
+ * @brief Called to register for notifications about delivering media packet when audio frame is decoded.
+ * @since_tizen 5.5
+ * @remarks The @a packet should be released by calling media_packet_destroy(). \n
+ * It is recommended to release it as soon as it is rendered, to avoid memory exhaustion.
+ *
+ * @param[in] packet Reference pointer to the media packet
+ * @param[in] user_data The user data passed from the callback registration function
+ */
+typedef void (*player_media_packet_audio_decoded_cb)(media_packet_h packet, void *user_data);
+
+/**
* @brief Called when the buffer level drops below the threshold of max size or no free space in buffer.
* @since_tizen @if WEARABLE 3.0 @else 2.4 @endif
* @remarks This function is used for media stream playback only.
int player_unset_media_packet_video_frame_decoded_cb(player_h player);
/**
+ * @brief Sets a media packet audio decoded callback function.
+ * @details This function is used to get audio PCM data of input media content via registered callback.\n
+ * This function allows to specify the output PCM format by @ref CAPI_MEDIA_TOOL_MEDIA_FORMAT_MODULE API.
+ * @since_tizen 5.5
+ * @remarks This function must be called before calling player_prepare() or player_prepare_async().\n
+ * A registered callback is called in a separate thread (not in the main loop).\n
+ * The audio PCM data can be retrieved using a registered callback as a media packet
+ * and it is available until it's destroyed by media_packet_destroy().\n
+ * The packet has to be destroyed as quickly as possible after rendering the data\n
+ * and all the packets have to be destroyed before player_unprepare() is called.\n
+ * @param[in] player The handle to the media player
+ * @param[in] format The media format handle about required audio PCM specification.
+ * This format has to include PCM MIME type, audio channel and sampling rate.
+ * If the format is NULL, the original PCM format or platform default PCM format will be applied.
+ * @param[in] opt The audio extract option
+ * @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_INVALID_OPERATION Invalid operation
+ * @pre The player's state must be #PLAYER_STATE_IDLE.
+ * @see player_unset_media_packet_audio_frame_decoded_cb()
+ * @par Example
+ @code
+ #include <player.h>
+ #include <media_format.h>
+ ...
+ player_h player = NULL;
+ media_format_h a_format = NULL;
+ ...
+ media_format_create(&a_format);
+ media_format_set_audio_mime(a_format, MEDIA_FORMAT_PCM_F32LE);
+ media_format_set_audio_channel(a_format, 2);
+ media_format_set_audio_samplerate(a_format, 44100);
+
+ player_set_media_packet_audio_frame_decoded_cb(player, a_format, PLAYER_AUDIO_EXTRACT_DEFAULT, _audio_pcm_cb, udata);
+
+ media_format_unref(a_format);
+ ...
+ @endcode
+ */
+int player_set_media_packet_audio_frame_decoded_cb(player_h player, media_format_h format,
+ player_audio_extract_option_e opt, player_media_packet_audio_decoded_cb callback, void *user_data);
+
+/**
+ * @brief Unsets the media packet audio frame decoded callback function.
+ * @since_tizen 5.5
+ * @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's state must be #PLAYER_STATE_READY or #PLAYER_STATE_IDLE
+ * @see player_set_media_packet_audio_frame_decoded_cb()
+ */
+int player_unset_media_packet_audio_frame_decoded_cb(player_h player);
+
+/**
* @brief Pushes elementary stream to decode audio or video.
* @since_tizen @if WEARABLE 3.0 @else 2.4 @endif
* @remarks player_set_media_stream_info() must be called before using this function.
* @remarks H.264 can be supported.
* @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
+ * @param[in] format The media format to set media information
* @return @c 0 on success,
* otherwise a negative error value
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
- * @see player_set_replaygain_enable()
+ * @see player_set_replaygain_enabled()
*/
int player_is_replaygain_enabled(player_h player, bool *enabled);
Name: capi-media-player
Summary: A Media Player API
-Version: 0.3.116
+Version: 0.3.117
Release: 0
Group: Multimedia/API
License: Apache-2.0
BuildRequires: pkgconfig(storage)
BuildRequires: pkgconfig(capi-system-info)
BuildRequires: pkgconfig(libinput)
-%if "%{TIZEN_PRODUCT_TV}" != "1"
+%if "%{tizen_profile_name}" != "tv"
BuildRequires: pkgconfig(mm-evas-renderer)
%endif
MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
%cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} \
-%if "%{TIZEN_PRODUCT_TV}" == "1"
+%if "%{tizen_profile_name}" == "tv"
-DTIZEN_FEATURE_EVAS_RENDERER=Off
%else
-DTIZEN_FEATURE_EVAS_RENDERER=On
gint fd;
gint fd_id;
bool use_tsurf_pool;
-} _media_pkt_fin_data;
+} _media_pkt_video_fin_data;
+
+typedef struct {
+ gint key;
+ gint fd;
+ gint fd_id;
+ tbm_bo bo;
+} _media_pkt_audio_fin_data;
static int _player_deinit_memory_buffer(player_cli_s *pc);
static void _player_event_queue_add(player_event_queue *ev, _player_cb_data *data);
return ret;
}
-int _player_media_packet_finalize(media_packet_h pkt, int error_code, void *user_data)
+int _player_video_media_packet_finalize(media_packet_h pkt, int error_code, void *user_data)
{
int ret = MEDIA_PACKET_FINALIZE;
muse_player_api_e api = MUSE_PLAYER_API_RETURN_VIDEO_DATA;
- _media_pkt_fin_data *fin_data = (_media_pkt_fin_data *)user_data;
+ _media_pkt_video_fin_data *fin_data = (_media_pkt_video_fin_data *)user_data;
intptr_t v_data = 0;
char *snd_msg = NULL;
int snd_len = 0;
/* continue the remained job */
}
if (tsurf) {
- /* LOGD("_player_media_packet_finalize tsurf destroy %p", tsurf); */
+ /* LOGD("tsurf destroy %p", tsurf); */
tbm_surface_destroy(tsurf);
tsurf = NULL;
}
return ret;
}
+int _player_audio_media_packet_finalize(media_packet_h pkt, int error_code, void *user_data)
+{
+ int ret = MEDIA_PACKET_FINALIZE;
+ muse_player_api_e api = MUSE_PLAYER_API_RETURN_BUFFER;
+ _media_pkt_audio_fin_data *fin_data = (_media_pkt_audio_fin_data *)user_data;
+
+ if (!pkt) {
+ LOGE("invalid parameter buffer %p, user_data %p", pkt, user_data);
+ return ret;
+ }
+
+ if (!fin_data) {
+ LOGE("invalid fin_data");
+ goto EXIT;
+ }
+
+ if (fin_data->bo) {
+ /* LOGD("release memory - %p", fin_data->bo); */
+ tbm_bo_unref(fin_data->bo);
+ }
+
+ if (fin_data->fd > INVALID_DEFAULT_VALUE && muse_core_fd_is_valid(fin_data->fd)) {
+ if (muse_client_check_fd_id_value(fin_data->fd, fin_data->fd_id) == FALSE) {
+ LOGE("[fd:%d,id:%d] is invalid.", fin_data->fd, fin_data->fd_id);
+ goto EXIT;
+ }
+
+ PLAYER_SEND_MSG_ASYNC_WITH_NO_RETURN(api, fin_data->fd, MUSE_TYPE_INT, "key", fin_data->key);
+ } else {
+ LOGE("[fd:%d] is invalid.", fin_data->fd);
+ }
+
+EXIT:
+ if (fin_data) {
+ g_free(fin_data);
+ fin_data = NULL;
+ }
+
+ return ret;
+}
+
static bool _player_video_roi_area_is_valid(double x_scale, double y_scale,
double w_scale, double h_scale)
{
LOGI("Event type : %d ", type);
PLAYER_NULL_ARG_CHECK(CALLBACK_INFO(pc));
+
+ if ((type == MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME) ||
+ (type == MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME)) {
+ /* check state condition */
+ player_state_e state = PLAYER_STATE_NONE;
+
+ if (_get_current_state(pc, &state) != PLAYER_ERROR_NONE) {
+ LOGE("Failed to get current state");
+ return PLAYER_ERROR_INVALID_OPERATION;
+ }
+
+ if (state > PLAYER_STATE_READY) {
+ LOGE("Invalid state %d", state);
+ return PLAYER_ERROR_INVALID_STATE;
+ }
+ }
+
set_null_user_cb_lock(CALLBACK_INFO(pc), type);
PLAYER_SEND_MSG(api, pc, ret_buf, ret,
media_format_mimetype_e mimetype = MEDIA_FORMAT_NV12;
bool make_pkt_fmt = false;
int ret = MEDIA_FORMAT_ERROR_NONE;
- _media_pkt_fin_data *fin_data = NULL;
+ _media_pkt_video_fin_data *fin_data = NULL;
intptr_t v_data = 0;
uint64_t pts = 0;
int i = 0, orientation = 0;
}
}
- fin_data = g_new0(_media_pkt_fin_data, 1);
+ fin_data = g_new0(_media_pkt_video_fin_data, 1);
if (!fin_data) {
LOGE("failed to alloc fin_data");
goto ERROR;
/* Keep the fd id to check validation when the pkt is destroyed. */
fin_data->fd_id = muse_client_get_fd_id_value(fin_data->fd);
- ret = media_packet_create_from_tbm_surface(cb_info->pkt_fmt, tsurf, (media_packet_finalize_cb)_player_media_packet_finalize, (void *)fin_data, &pkt);
+ ret = media_packet_create_from_tbm_surface(cb_info->pkt_fmt, tsurf, (media_packet_finalize_cb)_player_video_media_packet_finalize, (void *)fin_data, &pkt);
if (ret != MEDIA_PACKET_ERROR_NONE || !pkt) {
LOGE("media_packet_create_from_tbm_surface failed %d %p", ret, pkt);
goto ERROR;
static void __media_packet_audio_frame_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
{
+ int ret = MEDIA_FORMAT_ERROR_NONE;
tbm_bo bo = NULL;
tbm_bo_handle thandle;
int key = INVALID_DEFAULT_VALUE;
player_audio_raw_data_s audio; /* DEPRECATED_PLAYER_INTERNAL_API */
+ media_packet_h pkt = NULL;
+ media_format_h fmt = NULL;
+ _media_pkt_audio_fin_data *fin_data = NULL;
if (!player_msg_get(key, recv_data->buffer)) {
LOGE("failed to get key value from msg.");
tbm_bo_unmap(bo);
/* LOGD("user callback data %p, size %d", audio.data, audio.size); */
- if (cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME]) { /* DEPRECATED_PLAYER_INTERNAL_API, will be removed */
- ((player_audio_pcm_extraction_cb)cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME])
- (&audio, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME]);
- }
-/* FIXME: Will be implemented with public api
- else if (cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME]) {
+ if (cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME]) {
+ ret = media_format_create(&fmt);
+ if (ret != MEDIA_FORMAT_ERROR_NONE || !fmt) {
+ LOGE("failed to create media format 0x%X %p", ret, fmt);
+ goto EXIT;
+ }
+
+ ret = media_format_set_audio_mime(fmt, audio.pcm_format);
+ ret |= media_format_set_audio_samplerate(fmt, audio.rate);
+ ret |= media_format_set_audio_channel(fmt, audio.channel);
+ ret |= media_format_set_audio_channel_mask(fmt, audio.channel_mask);
+ if (ret != MEDIA_FORMAT_ERROR_NONE) {
+ LOGE("failed to set audio format 0x%X", ret);
+ goto EXIT;
+ }
+
+ fin_data = g_new0(_media_pkt_audio_fin_data, 1);
+ if (!fin_data) {
+ LOGE("failed to alloc fin_data");
+ goto EXIT;
+ }
+
+ fin_data->key = key;
+ fin_data->fd = cb_info->fd;
+ fin_data->bo = bo;
+
+ /* Keep the fd id to check validation when the pkt is destroyed. */
+ fin_data->fd_id = muse_client_get_fd_id_value(fin_data->fd);
+
+ ret = media_packet_create_from_external_memory(fmt, audio.data, audio.size,
+ (media_packet_finalize_cb)_player_audio_media_packet_finalize, (void *)fin_data, &pkt);
+ if (ret != MEDIA_PACKET_ERROR_NONE || !pkt) {
+ LOGE("failed to create media packet 0x%X %p", ret, pkt);
+ if (pkt)
+ media_packet_destroy(pkt); /* fin_data will be free in finalize function. */
+ else
+ g_free(fin_data);
+ goto EXIT;
+ }
+
+ media_format_unref(fmt);
+ fmt = NULL;
+
((player_media_packet_audio_decoded_cb)cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME])
(pkt, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME]);
- }
-*/
- else {
+ } else if (cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME]) { /* DEPRECATED_PLAYER_INTERNAL_API, will be removed */
+ ((player_audio_pcm_extraction_cb)cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME])
+ (&audio, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME]);
+ } else {
LOGE("there is no registered cb");
goto EXIT;
}
close(recv_data->tfd[0]);
memset(recv_data->tfd, INVALID_DEFAULT_VALUE, sizeof(recv_data->tfd));
- /* return buffer directly, DEPRECATED_PLAYER_INTERNAL_API */
+ if (fmt)
+ media_format_unref(fmt);
+
+ /* return buffer */
if ((cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME] == NULL) &&
(key > INVALID_DEFAULT_VALUE)) {
/* LOGD("send msg to release buffer. key:%d", key); */
PLAYER_SEND_MSG_ASYNC_WITH_NO_RETURN(MUSE_PLAYER_API_RETURN_BUFFER, cb_info->fd, MUSE_TYPE_INT, "key", key);
}
+
+ return;
}
static void __video_frame_render_error_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
return FALSE;
}
- LOGD("enter ev:%d", data->int_data);
+ ev = data->int_data;
+ if ((ev != MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME) &&
+ (ev != MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME))
+ LOGD("enter ev:%d", ev);
g_mutex_lock(&data->event_mutex);
- ev = data->int_data;
if (data->cb_info == NULL) {
/* tried to remove before at _player_remove_idle_event */
return __unset_callback(MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME, player);
}
+int player_set_media_packet_audio_frame_decoded_cb(player_h player, media_format_h format,
+ player_audio_extract_option_e opt, player_media_packet_audio_decoded_cb callback, void *user_data)
+{
+ PLAYER_INSTANCE_CHECK(player);
+ PLAYER_NULL_ARG_CHECK(callback);
+ int ret = PLAYER_ERROR_NONE;
+ player_cli_s *pc = (player_cli_s *)player;
+ muse_player_api_e api = MUSE_PLAYER_API_SET_MEDIA_PACKET_AUDIO_FRAME_DECODED_CB;
+ char *ret_buf = NULL;
+ media_format_mimetype_e mimetype = MEDIA_FORMAT_MAX;
+ int channel = 0;
+ int samplerate = 0;
+
+ LOGD("ENTER");
+
+ if (format) {
+ media_format_ref(format);
+ if (media_format_get_audio_info(format, &mimetype, &channel, &samplerate, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE) {
+ LOGE("failed to get audio info from media format.");
+ media_format_unref(format);
+ return PLAYER_ERROR_INVALID_PARAMETER;
+ }
+ media_format_unref(format);
+
+ if (mimetype < MEDIA_FORMAT_PCM || mimetype > MEDIA_FORMAT_PCM_U32BE) {
+ LOGW("Not supported audio format type : 0x%X", mimetype);
+ return PLAYER_ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ LOGD("pcm spec : 0x%X, %d, %d", mimetype, channel, samplerate);
+
+ PLAYER_SEND_MSG(api, pc, ret_buf, ret,
+ MUSE_TYPE_INT, "opt", opt,
+ MUSE_TYPE_INT, "mimetype", mimetype,
+ MUSE_TYPE_INT, "channel", channel,
+ MUSE_TYPE_INT, "samplerate", samplerate);
+
+ if (ret == PLAYER_ERROR_NONE) {
+ pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME] = callback;
+ pc->cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME] = user_data;
+ LOGI("Event type : %d ", MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME);
+ }
+
+ g_free(ret_buf);
+ return ret;
+}
+
+int player_unset_media_packet_audio_frame_decoded_cb(player_h player)
+{
+ return __unset_callback(MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME, player);
+}
+
int player_set_video_stream_changed_cb(player_h player, player_video_stream_changed_cb callback, void *user_data)
{
return __set_callback(MUSE_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED, player, callback, user_data);
TIZEN_PROFILE_TV = 0x4,
TIZEN_PROFILE_IVI = 0x8,
TIZEN_PROFILE_COMMON = 0x10,
-} tizen_profile_t;
+} tizen_profile_e;
+
+typedef struct {
+ uint64_t mask;
+ FILE *fp_out;
+} audio_pcm_dump_t;
extern int player_set_audio_offload_enabled(player_h player, bool enabled);
extern int player_is_audio_offload_enabled(player_h player, bool *enabled);
mm_navevent_handler_size_s image_size;
#endif
-static tizen_profile_t _get_tizen_profile()
+static tizen_profile_e _get_tizen_profile()
{
char *profileName;
- static tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
+ static tizen_profile_e profile = TIZEN_PROFILE_UNKNOWN;
if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
return profile;
#if DUMP_OUTBUF
FILE *fp_out1 = NULL;
FILE *fp_out2 = NULL;
+GList *audio_dump_list = NULL;
#endif
enum {
CURRENT_STATUS_AUDIO_OFFLOAD,
CURRENT_STATUS_PITCH_CONTROL,
CURRENT_STATUS_PITCH_VALUE,
+ CURRENT_STATUS_EXPORT_PCM_OPTION,
+ CURRENT_STATUS_EXPORT_PCM_CH,
+ CURRENT_STATUS_EXPORT_PCM_RATE,
+ CURRENT_STATUS_EXPORT_PCM_MIME,
};
#define MAX_HANDLE 20
media_packet_destroy(g_audio_pkt);
#if DUMP_OUTBUF
+ GList *list = NULL;
+ audio_pcm_dump_t *a_data = NULL;
+
+ list = audio_dump_list;
+ while(list) {
+ a_data = (audio_pcm_dump_t *)list->data;
+ list = g_list_next(list);
+ if (a_data && a_data->fp_out)
+ fclose(a_data->fp_out);
+ g_free(a_data);
+ }
+ g_list_free(audio_dump_list);
+ audio_dump_list = NULL;
+
if (fp_out1)
fclose(fp_out1);
if (fp_out2)
player_set_media_packet_video_frame_decoded_cb(g_player[0], _video_decoded_cb, g_player[0]);
}
+void _audio_decoded_cb(media_packet_h packet, void *user_data)
+{
+ int mime, channel, rate;
+ uint64_t channel_mask;
+ uint64_t size;
+ void *pkt_data;
+
+ if (!packet) {
+ g_print("invalid packet param");
+ return;
+ }
+
+ media_packet_get_format(packet, &g_audio_fmt);
+ media_format_get_audio_info(g_audio_fmt, (media_format_mimetype_e *)&mime, &channel, &rate, NULL, NULL);
+ media_format_get_audio_channel_mask(g_audio_fmt, &channel_mask);
+ media_packet_get_buffer_data_ptr(packet, &pkt_data);
+ media_packet_get_buffer_size(packet, &size);
+
+ g_print("[ received ] channel: %d size: %"G_GUINT64_FORMAT", mask %"G_GUINT64_FORMAT"\n", channel, size, channel_mask);
+
+#if DUMP_OUTBUF
+ GList *list = NULL;
+ audio_pcm_dump_t *a_data = NULL;
+ FILE *fp_dump = NULL;
+ char file_path[32];
+
+ list = audio_dump_list;
+ while(list) {
+ a_data = (audio_pcm_dump_t *)list->data;
+ list = g_list_next(list);
+
+ if (a_data && a_data->mask == channel_mask) {
+ fp_dump = a_data->fp_out;
+ break;
+ }
+ }
+
+ a_data = NULL;
+ if (!fp_dump) {
+ a_data = g_try_malloc(sizeof(audio_pcm_dump_t));
+ if (a_data == NULL) {
+ g_print("failed to malloc");
+ goto EXIT;
+ }
+
+ snprintf(file_path, 32, "/tmp/out%"G_GUINT64_FORMAT".pcm", channel_mask);
+
+ a_data->mask = channel_mask;
+ a_data->fp_out = fopen(file_path, "wb");
+ if (!a_data->fp_out) {
+ g_free(a_data);
+ g_print("[ERROR] failed to open file\n");
+ goto EXIT;
+ }
+
+ audio_dump_list = g_list_append(audio_dump_list, a_data);
+ fp_dump = a_data->fp_out;
+ }
+
+ fwrite((guint8 *)pkt_data, 1, size, fp_dump);
+#endif
+
+EXIT:
+ media_packet_destroy(packet);
+}
+
+static media_format_mimetype_e __convert_audio_pcm_str_to_media_format_mime(char *audio_pcm_str)
+{
+ int len = strlen("S16LE");
+ if (!audio_pcm_str) {
+ g_print("audio pcm str is NULL\n");
+ return MEDIA_FORMAT_MAX;
+ }
+
+ if (!strncasecmp(audio_pcm_str, "S16LE", len))
+ return MEDIA_FORMAT_PCM_S16LE;
+ else if (!strncasecmp(audio_pcm_str, "S24LE", len))
+ return MEDIA_FORMAT_PCM_S24LE;
+ else if (!strncasecmp(audio_pcm_str, "S32LE", len))
+ return MEDIA_FORMAT_PCM_S32LE;
+ else if (!strncasecmp(audio_pcm_str, "S16BE", len))
+ return MEDIA_FORMAT_PCM_S16BE;
+ else if (!strncasecmp(audio_pcm_str, "S24BE", len))
+ return MEDIA_FORMAT_PCM_S24BE;
+ else if (!strncasecmp(audio_pcm_str, "S32BE", len))
+ return MEDIA_FORMAT_PCM_S32BE;
+ else if (!strncasecmp(audio_pcm_str, "F32LE", len))
+ return MEDIA_FORMAT_PCM_F32LE;
+ else if (!strncasecmp(audio_pcm_str, "F32BE", len))
+ return MEDIA_FORMAT_PCM_F32BE;
+ else if (!strncasecmp(audio_pcm_str, "U16LE", len))
+ return MEDIA_FORMAT_PCM_U16LE;
+ else if (!strncasecmp(audio_pcm_str, "U24LE", len))
+ return MEDIA_FORMAT_PCM_U24LE;
+ else if (!strncasecmp(audio_pcm_str, "U32LE", len))
+ return MEDIA_FORMAT_PCM_U32LE;
+ else if (!strncasecmp(audio_pcm_str, "U16BE", len))
+ return MEDIA_FORMAT_PCM_U16BE;
+ else if (!strncasecmp(audio_pcm_str, "U24BE", len))
+ return MEDIA_FORMAT_PCM_U24BE;
+ else if (!strncasecmp(audio_pcm_str, "U32BE", len))
+ return MEDIA_FORMAT_PCM_U32BE;
+ else {
+ g_print("Not supported audio pcm format str : %s\n", audio_pcm_str);
+ return MEDIA_FORMAT_MAX;
+ }
+}
+
+static void set_audio_frame_decoded_cb(player_audio_extract_option_e opt, char* mime, int ch, int rate)
+{
+ media_format_mimetype_e type = __convert_audio_pcm_str_to_media_format_mime(mime);
+
+ if (type == MEDIA_FORMAT_MAX) {
+ g_print("failed to convert the mime : %s\n", mime);
+ return;
+ }
+
+ media_format_create(&g_audio_fmt);
+ media_format_set_audio_mime(g_audio_fmt, type);
+ media_format_set_audio_channel(g_audio_fmt, ch);
+ media_format_set_audio_samplerate(g_audio_fmt, rate);
+
+ g_print("==========> [Player_Test] option = 0x%X, %s(%d), %d, %d\n", opt, mime, type, ch, rate);
+ player_set_media_packet_audio_frame_decoded_cb(g_player[0], g_audio_fmt, opt, _audio_decoded_cb, g_player[0]);
+
+ media_format_unref(g_audio_fmt);
+ g_audio_fmt = NULL;
+}
+
static void change_surface(int option)
{
player_display_type_e surface_type = 0;
audio_frame_decoded_cb_ex(TRUE);
} else if (strncmp(cmd, "X4", 2) == 0) {
audio_frame_decoded_cb_ex(FALSE);
+ } else if (strncmp(cmd, "X5", 2) == 0) {
+ g_menu_state = CURRENT_STATUS_EXPORT_PCM_OPTION;
} else if (strncmp(cmd, "ep", 2) == 0) {
_player_enable_tsurf_pool();
} else if (strncmp(cmd, "su", 2) == 0) {
g_print("gu. get next uri. \t");
g_print("sg. set gapless. \n");
g_print("[audio_frame_decoded_cb_ex] X3. set audio_cb with sync\t");
- g_print("X4. set audio_cb with async \n");
+ g_print("X4. set audio_cb with async\t");
+ g_print("X5. set audio decoded cb with option\n");
g_print("[video_frame_decoded_cb] ep. enable tbm surface pool\n");
g_print("[buffering] bf. set new buffering size\n");
g_print("[Video 360] si. check spherical info\t");
g_print("*** input pitch control value.(0:disable, 1: enable) \n");
} else if (g_menu_state == CURRENT_STATUS_PITCH_VALUE) {
g_print("*** input pitch value.(0.5 ~ 2) \n");
+ } else if (g_menu_state == CURRENT_STATUS_EXPORT_PCM_OPTION) {
+ g_print("*** set option (0~3) \n");
+ } else if (g_menu_state == CURRENT_STATUS_EXPORT_PCM_CH) {
+ g_print("*** set pcm channel (e.g. 2)\n");
+ } else if (g_menu_state == CURRENT_STATUS_EXPORT_PCM_RATE) {
+ g_print("*** set pcm samplerate (e.g. 44100)\n");
+ } else if (g_menu_state == CURRENT_STATUS_EXPORT_PCM_MIME) {
+ g_print("*** set pcm mime (e.g. S16LE) \n");
} else {
g_print("*** unknown status.\n");
quit_program();
reset_menu_state();
}
break;
+ case CURRENT_STATUS_EXPORT_PCM_OPTION:
+ {
+ value1 = atoi(cmd);
+ g_menu_state = CURRENT_STATUS_EXPORT_PCM_CH;
+ }
+ break;
+ case CURRENT_STATUS_EXPORT_PCM_CH:
+ {
+ value2 = atoi(cmd);
+ g_menu_state = CURRENT_STATUS_EXPORT_PCM_RATE;
+ }
+ break;
+ case CURRENT_STATUS_EXPORT_PCM_RATE:
+ {
+ value3 = atoi(cmd);
+ g_menu_state = CURRENT_STATUS_EXPORT_PCM_MIME;
+ }
+ break;
+ case CURRENT_STATUS_EXPORT_PCM_MIME:
+ {
+ set_audio_frame_decoded_cb((player_audio_extract_option_e)value1, cmd, value2, value3);
+ reset_menu_state();
+ }
+ break;
}
g_timeout_add(100, timeout_menu_display, 0);