Implement audio pcm extraction API(internal) 72/48272/1 accepted/tizen/mobile/20150918.024641 accepted/tizen/tv/20150918.024655 accepted/tizen/wearable/20150918.024709 submit/tizen/20150917.021316 submit/tizen/20150917.064134
authorHyongtaek Lim <hyongtaek.lim@samsung.com>
Thu, 17 Sep 2015 04:20:13 +0000 (13:20 +0900)
committerHyongtaek Lim <hyongtaek.lim@samsung.com>
Thu, 17 Sep 2015 04:20:38 +0000 (13:20 +0900)
Signed-off-by: Hyongtaek Lim <hyongtaek.lim@samsung.com>
Change-Id: I5b9383d81be25a044133cd96c9c11026adc1653b

client/src/player2.c
client/src/player2_internal.c [new file with mode: 0644]
client/test/player_test.c
include/player2_private.h
include/player_msg_private.h
src/player_msg_dispatcher.c

index 4de0584..290dea9 100644 (file)
 #include "mmsvc_core_ipc.h"
 #include "player2_private.h"
 #include "player_msg_private.h"
+#include "player_internal.h"
 #include "sound_manager_internal.h"
 #include "mm_error.h"
 #include "mm_player.h"
 #include "mm_player_mused.h"
 #include "dlog.h"
 
-#define CALLBACK_TIME_OUT 16
-static tbm_bufmgr bufmgr;
-
 typedef struct {
        int int_data;
        char *buf;
@@ -424,7 +422,7 @@ static void __capture_cb_handler(callback_cb_info_s * cb_info, char *recvMsg)
                if(!player_msg_get(key, recvMsg))
                        goto capture_event_exit1;
 
-               bo = tbm_bo_import(bufmgr, key);
+               bo = tbm_bo_import(cb_info->bufmgr, key);
                if(bo == NULL) {
                        LOGE("TBM get error : bo is NULL");
                        goto capture_event_exit1;
@@ -498,7 +496,7 @@ static void __media_packet_video_frame_cb_handler(
        for(i = 0; i < 4; i++) {
                if(key[i]){
                        bo_num++;
-                       bo[i] = tbm_bo_import(bufmgr, key[i]);
+                       bo[i] = tbm_bo_import(cb_info->bufmgr, key[i]);
                }
        }
 
@@ -567,6 +565,53 @@ static void __media_packet_video_frame_cb_handler(
 static void __audio_frame_cb_handler(
                callback_cb_info_s * cb_info, char *recvMsg)
 {
+       unsigned char *data = NULL;
+       unsigned int size = 0;
+       tbm_bo bo;
+       tbm_bo_handle thandle;
+       tbm_key key;
+       player_audio_raw_data_s audio;
+       void *audio_frame = &audio;
+
+       if(player_msg_get_array(audio_frame, recvMsg) && player_msg_get(size, recvMsg)) {
+               if(!player_msg_get(key, recvMsg))
+                       return;
+
+               bo = tbm_bo_import(cb_info->bufmgr, key);
+               if(bo == NULL) {
+                       LOGE("TBM get error : bo is NULL");
+                       return;
+               }
+               thandle = tbm_bo_map (bo, TBM_DEVICE_CPU,
+                               TBM_OPTION_WRITE | TBM_OPTION_READ);
+               if(thandle.ptr == NULL)
+               {
+                       LOGE("TBM get error : handle pointer is NULL");
+                       tbm_bo_unref(bo);
+                       return;
+               }
+               data = g_new(unsigned char, size);
+               if(data){
+                       memcpy(data, thandle.ptr, size);
+                       audio.data = data;
+                       audio.size = size;
+                       LOGD("user callback data %p, size %d", audio.data, audio.size);
+                       ((player_audio_pcm_extraction_cb)
+                       cb_info->user_cb[_PLAYER_EVENT_TYPE_AUDIO_FRAME]) (
+                               &audio,
+                               cb_info->user_data[_PLAYER_EVENT_TYPE_AUDIO_FRAME]);
+                       g_free(data);
+               }
+               else
+                       LOGE("g_new failure");
+
+               /* mark to read */
+               *((char *)thandle.ptr+size) = 0;
+               LOGD("Fin");
+
+               tbm_bo_unmap(bo);
+               tbm_bo_unref(bo);
+       }
 }
 
 static void __video_frame_render_error_cb_handler(
@@ -992,7 +1037,7 @@ static void callback_destroy(callback_cb_info_s * cb_info)
        g_free(cb_info);
 }
 
-static int wait_for_cb_return(mm_player_api_e api, callback_cb_info_s *cb_info,
+int wait_for_cb_return(mm_player_api_e api, callback_cb_info_s *cb_info,
                char **ret_buf, int time_out)
 {
        int ret = PLAYER_ERROR_NONE;
@@ -1105,7 +1150,7 @@ int player_create(player_h * player)
        } else
                goto ErrorExit;
 
-       bufmgr = tbm_bufmgr_init (-1);
+       pc->cb_info->bufmgr = tbm_bufmgr_init (-1);
 
        g_free(ret_buf);
        return ret;
@@ -1141,9 +1186,9 @@ int player_destroy(player_h player)
                ret = PLAYER_ERROR_INVALID_OPERATION;
 
        _player_event_queue_destroy(pc->cb_info);
-       callback_destroy(pc->cb_info);
+       tbm_bufmgr_deinit (pc->cb_info->bufmgr);
 
-       tbm_bufmgr_deinit (bufmgr);
+       callback_destroy(pc->cb_info);
 
        g_free(pc);
        pc = NULL;
@@ -1273,7 +1318,7 @@ int player_set_memory_buffer(player_h player, const void *data, int size)
                return PLAYER_ERROR_INVALID_OPERATION;
        }
 
-       bo = tbm_bo_alloc (bufmgr, size, TBM_BO_DEFAULT);
+       bo = tbm_bo_alloc (pc->cb_info->bufmgr, size, TBM_BO_DEFAULT);
        if(bo == NULL) {
                LOGE("TBM get error : bo is NULL");
                return PLAYER_ERROR_INVALID_OPERATION;
@@ -2927,7 +2972,7 @@ int player_push_media_stream(player_h player, media_packet_h packet)
 
 #ifdef __UN_USED
        if(push_media.buf_type == PUSH_MEDIA_BUF_TYPE_TBM) {
-               bo = tbm_bo_alloc (bufmgr, push_media.size, TBM_BO_DEFAULT);
+               bo = tbm_bo_alloc (pc->cb_info->bufmgr, push_media.size, TBM_BO_DEFAULT);
                if(bo == NULL) {
                        LOGE("TBM get error : bo is NULL");
                        return PLAYER_ERROR_INVALID_OPERATION;
diff --git a/client/src/player2_internal.c b/client/src/player2_internal.c
new file mode 100644 (file)
index 0000000..4e386ae
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <mmsvc_core.h>
+#include <mmsvc_core_msg_json.h>
+#include <mmsvc_core_ipc.h>
+#include <mm_error.h>
+#include <dlog.h>
+#include "player2_private.h"
+#include "player_msg_private.h"
+#include "player_internal.h"
+
+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);
+       int ret = PLAYER_ERROR_NONE;
+       mm_player_api_e api = MM_PLAYER_API_SET_PCM_EXTRACTION_MODE;
+       player_cli_s *pc = (player_cli_s *) player;
+       int sock_fd = pc->cb_info->fd;
+       char *ret_buf = NULL;
+       _player_event_e event = _PLAYER_EVENT_TYPE_AUDIO_FRAME;
+
+       LOGD("ENTER");
+
+       player_msg_send1(api, EXT_HANDLE(pc), sock_fd, pc->cb_info, ret_buf, ret,
+                       INT, sync);
+
+       if(ret == PLAYER_ERROR_NONE){
+               pc->cb_info->user_cb[event] = callback;
+               pc->cb_info->user_data[event] = user_data;
+               LOGI("Event type : %d ", event);
+       }
+
+       g_free(ret_buf);
+       return ret;
+}
+
+int player_set_pcm_spec(player_h player, const char *format, int samplerate, int channel)
+{
+       PLAYER_INSTANCE_CHECK(player);
+       int ret = PLAYER_ERROR_NONE;
+       mm_player_api_e api = MM_PLAYER_API_SET_PCM_SPEC;
+       player_cli_s *pc = (player_cli_s *) player;
+       int sock_fd = pc->cb_info->fd;
+       char *ret_buf = NULL;
+
+       LOGD("ENTER");
+
+       player_msg_send3(api, EXT_HANDLE(pc), sock_fd, pc->cb_info, ret_buf, ret,
+                       STRING, format, INT, samplerate, INT, channel);
+
+       g_free(ret_buf);
+       return ret;
+}
index 4c41bca..4917109 100644 (file)
@@ -548,8 +548,6 @@ static void prepared_cb(void *user_data)
        g_print("[Player_Test] prepared_cb!!!!\n");
 }
 
-/* TODO : Make internal API */
-#if 0
 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;
@@ -559,13 +557,12 @@ static void _audio_frame_decoded_cb_ex(player_audio_raw_data_s *audio_raw_frame,
        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)
+       if(audio_raw->channel_mask == 1 && fp_out1)
                fwrite((guint8 *)audio_raw->data, 1, audio_raw->size, fp_out1);
-       else if(audio_raw->channel_mask == 2)
+       else if(audio_raw->channel_mask == 2 && fp_out2)
                fwrite((guint8 *)audio_raw->data, 1, audio_raw->size, fp_out2);
 #endif
 }
-#endif
 
 static void progress_down_cb(player_pd_message_type_e type, void *user_data)
 {
@@ -1414,29 +1411,27 @@ static void get_duration()
 
 static void audio_frame_decoded_cb_ex()
 {
-/* TODO : Make internal API */
-#if 0
        int ret;
 
 #if DUMP_OUTBUF
-    fp_out1 = fopen("/opt/usr/media/out1.pcm", "wb");
-    fp_out2 = fopen("/opt/usr/media/out2.pcm", "wb");
+       fp_out1 = fopen("/home/owner/content/out1.pcm", "wb");
+       fp_out2 = fopen("/home/owner/content/out2.pcm", "wb");
+       if(!fp_out1 || !fp_out2) {
+               g_print("File open error\n");
+               return;
+       }
 #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);
-#endif
 }
 
 static void set_pcm_spec()
 {
-/* TODO : Make internal API */
-#if 0
        int ret = 0;
 
        ret = player_set_pcm_spec(g_player[0], "F32LE", 44100, 2);
        g_print("[Player_Test] set_pcm_spec return: %d\n", ret);
-#endif
 }
 
 static void get_stream_info()
index fc48fb1..63367c0 100644 (file)
@@ -16,6 +16,7 @@
 
 #ifndef __TIZEN_MEDIA_PLAYER_2_PRIVATE_H__
 #define        __TIZEN_MEDIA_PLAYER_2_PRIVATE_H__
+#include <tbm_bufmgr.h>
 #include "player.h"
 #include "mm_types.h"
 #include "mmsvc_core.h"
@@ -118,6 +119,8 @@ extern "C" {
                MM_PLAYER_API_GET_CURRENT_TRACK,
                MM_PLAYER_API_SELECT_TRACK,
                MM_PLAYER_API_GET_TRACK_LANGUAGE_CODE,
+               MM_PLAYER_API_SET_PCM_EXTRACTION_MODE,
+               MM_PLAYER_API_SET_PCM_SPEC,
                MM_PLAYER_API_MAX
        } mm_player_api_e;
 
@@ -236,6 +239,7 @@ typedef struct _callback_cb_info {
        player_event_queue event_queue;
        media_format_h pkt_fmt;
        MMHandleType local_handle;
+       tbm_bufmgr bufmgr;
 } callback_cb_info_s;
 
 typedef struct {
@@ -254,6 +258,9 @@ typedef struct _player_cli_s{
 /* external handle cast */
 #define EXT_HANDLE(h)          ((h)->remote_handle)
 
+
+int wait_for_cb_return(mm_player_api_e api, callback_cb_info_s *cb_info,
+               char **ret_buf, int time_out);
 int player_sound_register(player_h player, int pid);
 
 /**
index 09432e8..e98d1f6 100644 (file)
@@ -25,6 +25,8 @@ extern "C" {
 #include "media_format.h"
 #include "tbm_bufmgr.h"
 
+#define CALLBACK_TIME_OUT 35
+
 typedef int32_t INT;
 typedef int64_t INT64;
 typedef intptr_t POINTER;
index a0cd8a9..d28acad 100644 (file)
@@ -36,6 +36,7 @@
 #include "mmsvc_core_ipc.h"
 #include "player2_private.h"
 #include "player_msg_private.h"
+#include "player_internal.h"
 
 #define STREAM_PATH_LENGTH 32
 #define STREAM_PATH_BASE "/tmp/mused_gst.%d"
@@ -292,6 +293,68 @@ static void _media_packet_video_decoded_cb(media_packet_h pkt, void *user_data)
                        surface_info, surface_info_size, sizeof(char));
 }
 
+static void _audio_frame_decoded_cb(player_audio_raw_data_s *audio_frame, void *user_data)
+{
+       mm_player_cb_e api = MM_PLAYER_CB_EVENT;
+       _player_event_e ev = _PLAYER_EVENT_TYPE_AUDIO_FRAME;
+       Client client = (Client)user_data;
+       tbm_bo bo;
+       tbm_bo_handle thandle;
+       tbm_key key;
+       char checker = 1;
+       unsigned int expired = 0x0fffffff;
+       int size = 0;
+       void *data = NULL;
+       if(audio_frame) {
+               size = audio_frame->size;
+               data = audio_frame->data;
+       } else {
+               LOGE("audio frame is NULL");
+               return;
+       }
+
+       LOGD("ENTER");
+
+       bo = tbm_bo_alloc (bufmgr, size+1, TBM_BO_DEFAULT);
+       if(!bo) {
+               LOGE("TBM get error : tbm_bo_alloc return NULL");
+               return;
+       }
+       thandle = tbm_bo_map (bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
+       if(thandle.ptr == NULL)
+       {
+               LOGE("TBM get error : handle pointer is NULL");
+               tbm_bo_unref(bo);
+               return;
+       }
+       memcpy(thandle.ptr, data, size);
+       key = tbm_bo_export(bo);
+       if(key == 0)
+       {
+               LOGE("TBM get error : export key is 0");
+               checker = 0;
+               tbm_bo_unmap(bo);
+               tbm_bo_unref(bo);
+               return;
+       }
+       /* mark to write */
+       *((char *)thandle.ptr+size) = 1;
+
+       tbm_bo_unmap(bo);
+
+       player_msg_event2_array(api, ev, client, INT, key, INT, size,
+                       audio_frame, sizeof(player_audio_raw_data_s), sizeof(char));
+
+       while(checker && expired--) {
+               thandle = tbm_bo_map (bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
+               checker = *((char *)thandle.ptr+size);
+               tbm_bo_unmap(bo);
+       }
+
+       tbm_bo_unref(bo);
+}
+
+
 static void _video_stream_changed_cb(
                int width, int height, int fps, int bit_rate, void *user_data)
 {
@@ -2126,6 +2189,45 @@ static int player_disp_get_track_language_code(Client client)
        return ret;
 }
 
+static int player_disp_set_pcm_extraction_mode(Client client)
+{
+       int ret = -1;
+       intptr_t handle;
+       mm_player_api_e api = MM_PLAYER_API_SET_PCM_EXTRACTION_MODE;
+       int sync;
+
+       player_msg_get_type(handle, mmsvc_core_client_get_msg(client), POINTER);
+       player_msg_get(sync, mmsvc_core_client_get_msg(client));
+
+       ret = player_set_pcm_extraction_mode((player_h) handle,
+                       sync, _audio_frame_decoded_cb, client);
+
+       player_msg_return(api, ret, client);
+
+       return ret;
+}
+
+static int player_disp_set_pcm_spec(Client client)
+{
+       int ret = -1;
+       intptr_t handle;
+       mm_player_api_e api = MM_PLAYER_API_SET_PCM_SPEC;
+       char format[MM_URI_MAX_LENGTH] = { 0, };
+       int samplerate;
+       int channel;
+
+       player_msg_get_type(handle, mmsvc_core_client_get_msg(client), POINTER);
+       player_msg_get_string(format, mmsvc_core_client_get_msg(client));
+       player_msg_get(samplerate, mmsvc_core_client_get_msg(client));
+       player_msg_get(channel, mmsvc_core_client_get_msg(client));
+
+       ret = player_set_pcm_spec((player_h)handle, format, samplerate, channel);
+
+       player_msg_return(api, ret, client);
+
+       return ret;
+}
+
 int (*dispatcher[MM_PLAYER_API_MAX]) (Client client) = {
        player_disp_create,     /* MM_PLAYER_API_CREATE */
                player_disp_destroy,    /* MM_PLAYER_API_DESTROY */
@@ -2197,5 +2299,7 @@ int (*dispatcher[MM_PLAYER_API_MAX]) (Client client) = {
                player_disp_get_current_track, /* MM_PLAYER_API_GET_CURRENT_TRACK */
                player_disp_select_track, /* MM_PLAYER_API_SELECT_TRACK */
                player_disp_get_track_language_code, /* MM_PLAYER_API_GET_TRACK_LANGUAGE_CODE */
+               player_disp_set_pcm_extraction_mode, /* MM_PLAYER_API_SET_PCM_EXTRACTION_MODE */
+               player_disp_set_pcm_spec, /* MM_PLAYER_API_SET_PCM_SPEC */
 };