diff options
Diffstat (limited to 'server/mm_sound_mgr_codec.c')
-rw-r--r-- | server/mm_sound_mgr_codec.c | 756 |
1 files changed, 756 insertions, 0 deletions
diff --git a/server/mm_sound_mgr_codec.c b/server/mm_sound_mgr_codec.c new file mode 100644 index 0000000..feb1f5a --- /dev/null +++ b/server/mm_sound_mgr_codec.c @@ -0,0 +1,756 @@ +/* + * libmm-sound + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Seungbae Shin <seungbae.shin@samsung.com> + * + * 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 <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <pthread.h> + +#include <mm_source.h> +#include <mm_error.h> +#include <mm_types.h> +#include <mm_debug.h> +#include <mm_ipc.h> + +#include "include/mm_sound_mgr_common.h" +#include "include/mm_sound_mgr_codec.h" +#include "include/mm_sound_plugin_codec.h" +#include "include/mm_sound_thread_pool.h" +#include "include/mm_sound_pa_client.h" +#include "include/mm_sound_mgr_asm.h" + + + +#define _ENABLE_KEYTONE /* Temporal test code */ + +typedef struct { + int (*callback)(int, void *, void *, int); /* msg_type(pid) client callback & client data info */ + void *param; + int pid; + void *msgcallback; + void *msgdata; + MMHandleType plughandle; + + int pluginid; + int status; + int session_type; + int session_options; + int session_handle; + + bool enable_session; + } __mmsound_mgr_codec_handle_t; + +static MMSoundPluginType *g_codec_plugins = NULL; +static __mmsound_mgr_codec_handle_t g_slots[MANAGER_HANDLE_MAX]; +static mmsound_codec_interface_t g_plugins[MM_SOUND_SUPPORTED_CODEC_NUM]; +static pthread_mutex_t g_slot_mutex; +static pthread_mutex_t codec_wave_mutex; +static int _MMSoundMgrCodecStopCallback(int param); +static int _MMSoundMgrCodecFindKeytoneSlot(int *slotid); +static int _MMSoundMgrCodecGetEmptySlot(int *slotid); +static int _MMSoundMgrCodecFindLocaleSlot(int *slotid); +static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin); + +#define STATUS_IDLE 0 +#define STATUS_KEYTONE 1 +#define STATUS_LOCALE 2 +#define STATUS_SOUND 3 + +#define SOUND_SLOT_START 0 + + + +ASM_cb_result_t +sound_codec_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data) +{ + int slotid = (int)cb_data; + int result = MM_ERROR_NONE; + ASM_cb_result_t cb_res = ASM_CB_RES_NONE; + + debug_log("Got audio session callback msg for session_handle %d\n", handle); + + switch(command) + { + case ASM_COMMAND_STOP: + case ASM_COMMAND_PAUSE: + debug_log("Got msg from asm to Stop or Pause %d\n", command); + result = MMSoundMgrCodecStop(slotid); + if (result != MM_ERROR_NONE) { + debug_log("result error %d\n", result); + } + cb_res = ASM_CB_RES_STOP; + break; + case ASM_COMMAND_RESUME: + case ASM_COMMAND_PLAY: + debug_log("Got msg from asm to Play or Resume %d\n", command); + cb_res = ASM_CB_RES_NONE;; + default: + break; + } + return cb_res; +} + + +int MMSoundMgrCodecInit(const char *targetdir) +{ + int loop = 0; + int count = 0; + + debug_enter("\n"); + + memset (g_slots, 0, sizeof(g_slots)); + + if(pthread_mutex_init(&g_slot_mutex, NULL)) { + debug_error("pthread_mutex_init failed\n"); + return MM_ERROR_SOUND_INTERNAL; + } + + if(pthread_mutex_init(&codec_wave_mutex, NULL)) { + debug_error("pthread_mutex_init failed\n"); + return MM_ERROR_SOUND_INTERNAL; + } + + for (count = 0; count < MANAGER_HANDLE_MAX; count++) { + g_slots[count].status = STATUS_IDLE; + g_slots[count].plughandle = 0; + } + + if (g_codec_plugins) { + debug_warning("Please Check Init twice\n"); + MMSoundPluginRelease(g_codec_plugins); + } + + MMSoundPluginScan(targetdir, MM_SOUND_PLUGIN_TYPE_CODEC, &g_codec_plugins); + + while (g_codec_plugins[loop].type != MM_SOUND_PLUGIN_TYPE_NONE) { + _MMSoundMgrCodecRegisterInterface(&g_codec_plugins[loop++]); + } + + debug_leave("\n"); + return MM_ERROR_NONE; +} + +int MMSoundMgrCodecFini(void) +{ + debug_enter("\n"); + + memset(g_plugins, 0, sizeof(mmsound_codec_interface_t) * MM_SOUND_SUPPORTED_CODEC_NUM); + MMSoundPluginRelease(g_codec_plugins); + g_codec_plugins = NULL; + pthread_mutex_destroy(&g_slot_mutex); + pthread_mutex_destroy(&codec_wave_mutex); + debug_leave("\n"); + return MM_ERROR_NONE; +} + + +int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param) +{ + int count = 0; + mmsound_codec_info_t info; + mmsound_codec_param_t codec_param; + int err = MM_ERROR_NONE; + int errorcode = 0; + int need_asm_unregister = 0; + +#ifdef DEBUG_DETAIL + debug_enter("\n"); +#endif + + for (count = 0; g_plugins[count].GetSupportTypes; count++) { + /* Find codec */ + if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE) + break; + } + + /*The count num means codec type WAV, MP3 */ + debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count); + + if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */ + debug_error("unsupported file type %d\n", count); + err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE; + goto cleanup; + } + + /* KeyTone */ + if (param->keytone == 1) { + /* Find keytone slot */ + err = _MMSoundMgrCodecFindKeytoneSlot(slotid); + /* Not First connect */ + if (err == MM_ERROR_NONE) { + if(g_slots[*slotid].status != STATUS_IDLE) { + MMSoundMgrCodecStop(*slotid); + } + debug_msg("Key tone : Stop to Play !!!\n"); + } + codec_param.keytone = param->keytone; + } else if (param->keytone == 2) { + /* Find keytone slot */ + err = _MMSoundMgrCodecFindLocaleSlot(slotid); + /* Not First connect */ + if (err == MM_ERROR_NONE) { + if(g_slots[*slotid].status != STATUS_IDLE) { + MMSoundMgrCodecStop(*slotid); + } + debug_msg("Key tone : Stop to Play !!!\n"); + } + codec_param.keytone = param->keytone; + } else { +#ifdef DEBUG_DETAIL + debug_msg("Get New handle\n"); +#endif + codec_param.keytone = 0; + } + + err = _MMSoundMgrCodecGetEmptySlot(slotid); + if (err != MM_ERROR_NONE) { + debug_error("Empty g_slot is not found\n"); + goto cleanup; + } + + codec_param.tone = param->tone; + codec_param.volume_config = param->volume_config; + codec_param.repeat_count = param->repeat_count; + codec_param.volume = param->volume; + codec_param.source = param->source; + codec_param.priority = param->priority; + codec_param.stop_cb = _MMSoundMgrCodecStopCallback; + codec_param.param = *slotid; + codec_param.pid = (int)param->param; + codec_param.handle_route = param->handle_route; + codec_param.codec_wave_mutex = &codec_wave_mutex; + pthread_mutex_lock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_msg("After Slot_mutex LOCK\n"); +#endif + + /* In case of KEYTONE */ + if (param->keytone == 1) + g_slots[*slotid].status = STATUS_KEYTONE; + + /* In case of LOCALE */ + if (param->keytone == 2) /* KeyTone */ + g_slots[*slotid].status = STATUS_LOCALE; + + /* + * Register ASM here + */ + if (param->session_type != ASM_EVENT_CALL && + param->session_type != ASM_EVENT_VIDEOCALL && + param->session_type != ASM_EVENT_VOIP && + param->session_type != ASM_EVENT_VOICE_RECOGNITION && + param->priority != HANDLE_PRIORITY_SOLO && + param->enable_session) { + if(!ASM_register_sound_ex((int)param->param, (int *)(¶m->session_handle), param->session_type, ASM_STATE_NONE, + sound_codec_asm_callback, (void*)*slotid, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) { + debug_critical("ASM_register_sound_ex() failed 0x%X\n", errorcode); + pthread_mutex_unlock(&g_slot_mutex); + return MM_ERROR_POLICY_INTERNAL; + } + if(param->session_options) { + if(!ASM_set_session_option(param->session_handle, param->session_options, &errorcode)) { + debug_error("ASM_set_session_option() failed 0x%x\n", errorcode); + } + } + if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) { + debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode); + pthread_mutex_unlock(&g_slot_mutex); + if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) { + debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode); + } + return MM_ERROR_POLICY_INTERNAL; + } + } + // + + /* Codec id WAV or MP3 */ + g_slots[*slotid].pluginid = count; + g_slots[*slotid].callback = param->callback; + g_slots[*slotid].msgcallback = param->msgcallback; + g_slots[*slotid].msgdata = param->msgdata; + g_slots[*slotid].param = param->param; /* This arg is used callback data */ + g_slots[*slotid].session_type = param->session_type; + g_slots[*slotid].session_options = param->session_options; + g_slots[*slotid].session_handle = param->session_handle; + g_slots[*slotid].enable_session = true; + + debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status); + + err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle)); + debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle); + if (err != MM_ERROR_NONE) { + debug_error("Plugin create fail : 0x%08X\n", err); + g_slots[*slotid].status = STATUS_IDLE; + pthread_mutex_unlock(&g_slot_mutex); + debug_warning("After Slot_mutex UNLOCK\n"); + if (param->session_handle) { + need_asm_unregister = 1; + } + goto cleanup; + } + + err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle); + if (err != MM_ERROR_NONE) { + debug_error("Fail to play : 0x%08X\n", err); + g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle); + if (param->session_handle) { + need_asm_unregister = 1; + } + } + + pthread_mutex_unlock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_msg("After Slot_mutex UNLOCK\n"); +#endif + +cleanup: + if(param->session_type != ASM_EVENT_CALL && + param->session_type != ASM_EVENT_VIDEOCALL && + param->session_type != ASM_EVENT_VOIP && + param->session_type != ASM_EVENT_VOICE_RECOGNITION && + param->enable_session && + need_asm_unregister == 1) { + if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_STOP, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) { + debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode); + } + if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) { + debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode); + return MM_ERROR_POLICY_INTERNAL; + } + } + +#ifdef DEBUG_DETAIL + debug_leave("\n"); +#endif + + return err; +} + +#define DTMF_PLUGIN_COUNT 2 +int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param) +{ + int count = 0; + int *codec_type; + mmsound_codec_info_t info; + mmsound_codec_param_t codec_param; + int err = MM_ERROR_NONE; + int errorcode = 0; + int need_asm_unregister = 0; + +#ifdef DEBUG_DETAIL + debug_enter("\n"); +#endif + + for (count = 0; g_plugins[count].GetSupportTypes; count++) { + /* Find codec */ + codec_type = g_plugins[count].GetSupportTypes(); + if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0])) + break; + } + + /*The count num means codec type DTMF */ + debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count); + + if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */ + debug_error("unsupported file type %d\n", count); + printf("unsupported file type %d\n", count); + err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE; + goto cleanup; + } + +#ifdef DEBUG_DETAIL + debug_msg("Get New handle\n"); +#endif + codec_param.keytone = 0; + + err = _MMSoundMgrCodecGetEmptySlot(slotid); + if(err != MM_ERROR_NONE) + { + debug_error("Empty g_slot is not found\n"); + goto cleanup; + } + + codec_param.tone = param->tone; + codec_param.priority = 0; + codec_param.volume_config = param->volume_config; + codec_param.repeat_count = param->repeat_count; + codec_param.volume = param->volume; + codec_param.stop_cb = _MMSoundMgrCodecStopCallback; + codec_param.param = *slotid; + codec_param.pid = (int)param->param; + + pthread_mutex_lock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_msg("After Slot_mutex LOCK\n"); +#endif + + // + /* + * Register ASM here + */ + + if (param->session_type != ASM_EVENT_CALL && + param->session_type != ASM_EVENT_VIDEOCALL && + param->session_type != ASM_EVENT_VOIP && + param->session_type != ASM_EVENT_VOICE_RECOGNITION && + param->enable_session) { + if(!ASM_register_sound_ex((int)param->param, (int *)(¶m->session_handle), param->session_type, ASM_STATE_NONE, + sound_codec_asm_callback, (void*)*slotid, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) { + debug_critical("ASM_register_sound_ex() failed 0x%X\n", errorcode); + pthread_mutex_unlock(&g_slot_mutex); + return MM_ERROR_POLICY_INTERNAL; + } + if(param->session_options) { + if(!ASM_set_session_option(param->session_handle, param->session_options, &errorcode)) { + debug_error("ASM_set_session_option() failed 0x%x\n", errorcode); + } + } + if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) { + debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode); + pthread_mutex_unlock(&g_slot_mutex); + if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) { + debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode); + } + return MM_ERROR_POLICY_INTERNAL; + } + } + + g_slots[*slotid].pluginid = count; + g_slots[*slotid].callback = param->callback; + g_slots[*slotid].param = param->param; /* This arg is used callback data */ + g_slots[*slotid].session_type = param->session_type; + g_slots[*slotid].session_options = param->session_options; + g_slots[*slotid].session_handle = param->session_handle; + g_slots[*slotid].enable_session = param->enable_session; + +#ifdef DEBUG_DETAIL + debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status); +#endif + + err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle)); + debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle); + if (err != MM_ERROR_NONE) { + debug_error("Plugin create fail : 0x%08X\n", err); + g_slots[*slotid].status = STATUS_IDLE; + pthread_mutex_unlock(&g_slot_mutex); + debug_warning("After Slot_mutex UNLOCK\n"); + need_asm_unregister = 1; + goto cleanup; + } + + err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle); + if (err != MM_ERROR_NONE) { + debug_error("Fail to play : 0x%08X\n", err); + g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle); + need_asm_unregister = 1; + } + + pthread_mutex_unlock(&g_slot_mutex); + + debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status); +#ifdef DEBUG_DETAIL + debug_msg("After Slot_mutex UNLOCK\n") +#endif + +cleanup: + if (param->session_type != ASM_EVENT_CALL && + param->session_type != ASM_EVENT_VIDEOCALL && + param->session_type != ASM_EVENT_VOIP && + param->session_type != ASM_EVENT_VOICE_RECOGNITION && + param->enable_session && + need_asm_unregister == 1) { + if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) { + debug_error("Unregister sound failed 0x%X\n", errorcode); + return MM_ERROR_POLICY_INTERNAL; + } + } + +#ifdef DEBUG_DETAIL + debug_leave("\n"); +#endif + + return err; +} + + +int MMSoundMgrCodecStop(const int slotid) +{ + int err = MM_ERROR_NONE; + + debug_enter("(Slotid : [%d])\n", slotid); + + if (slotid < 0 || MANAGER_HANDLE_MAX <= slotid) { + return MM_ERROR_INVALID_ARGUMENT; + } + + pthread_mutex_lock (&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_msg("After Slot_mutex LOCK\n"); +#endif + if (g_slots[slotid].status == STATUS_IDLE) { + err = MM_ERROR_SOUND_INVALID_STATE; + debug_warning("The playing slots is not found, Slot ID : [%d]\n", slotid); + goto cleanup; + } +#ifdef DEBUG_DETAIL + debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status); +#endif + + err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle); + if (err != MM_ERROR_NONE) { + debug_error("Fail to STOP Code : 0x%08X\n", err); + } + debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status); +cleanup: + pthread_mutex_unlock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_msg("After Slot_mutex UNLOCK\n"); +#endif + debug_leave("(err : 0x%08X)\n", err); + + return err; +} + +static int _MMSoundMgrCodecStopCallback(int param) +{ + int err = MM_ERROR_NONE; + + debug_enter("(Slot : %d)\n", param); + + pthread_mutex_lock(&g_slot_mutex); + debug_msg("[CODEC MGR] Slot_mutex lock done\n"); + + + /* + * Unregister ASM here + */ + + int errorcode = 0; + debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session); + + if (g_slots[param].session_handle) { + if(g_slots[param].session_type != ASM_EVENT_CALL && + g_slots[param].session_type != ASM_EVENT_VIDEOCALL && + g_slots[param].session_type != ASM_EVENT_VOIP && + g_slots[param].session_type != ASM_EVENT_VOICE_RECOGNITION && + g_slots[param].enable_session ) { + if(!ASM_set_sound_state_ex(g_slots[param].session_handle, g_slots[param].session_type, ASM_STATE_STOP, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) { + debug_error("[CODEC MGR] ASM_set_sound_state_ex() failed 0x%X\n", errorcode); + } + debug_msg("[CODEC MGR] ASM unregister\n"); + if(!ASM_unregister_sound_ex(g_slots[param].session_handle, g_slots[param].session_type, &errorcode, __asm_process_message)) { + debug_error("[CODEC MGR] ASM_unregister_sound_ex() failed 0x%X\n", errorcode); + } + } + } + + if (g_slots[param].msgcallback) { + debug_msg("[CODEC MGR] msgcallback : %p\n", g_slots[param].msgcallback); + debug_msg("[CODEC MGR] msg data : %p\n", g_slots[param].msgdata); + debug_msg("[CODEC MGR] mgr codec callback : %p\n", g_slots[param].callback); + g_slots[param].callback((int)g_slots[param].param, g_slots[param].msgcallback, g_slots[param].msgdata, param); /*param means client msg_type */ + } + debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param); + debug_msg("Handle allocated handle : [0x%08X]\n", g_slots[param].plughandle); + err = g_plugins[g_slots[param].pluginid].Destroy(g_slots[param].plughandle); + if (err < 0 ) { + debug_critical("[CODEC MGR] Fail to destroy slot number : [%d] err [0x%x]\n", param, err); + } + memset(&g_slots[param], 0, sizeof(__mmsound_mgr_codec_handle_t)); + g_slots[param].status = STATUS_IDLE; + pthread_mutex_unlock(&g_slot_mutex); + debug_msg("[CODEC MGR] Slot_mutex done\n"); + + return err; +} + +static int _MMSoundMgrCodecFindKeytoneSlot(int *slotid) +{ + int count = 0; + int err = MM_ERROR_NONE; + +#ifdef DEBUG_DETAIL + debug_enter("\n"); +#endif + + pthread_mutex_lock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_warning("After Slot_mutex LOCK\n"); +#endif + + for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) { + if (g_slots[count].status == STATUS_KEYTONE) { + break; + } + } + pthread_mutex_unlock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_warning("After Slot_mutex UNLOCK\n"); +#endif + if (count < MANAGER_HANDLE_MAX) { + debug_msg("Found keytone handle allocated (Slot : [%d])\n", count); + *slotid = count; + err = MM_ERROR_NONE; + } else { + debug_warning("Handle is full handle [KEY TONE] : [%d]\n", count); + err = MM_ERROR_SOUND_INTERNAL; + } + +#ifdef DEBUG_DETAIL + debug_leave("\n"); +#endif + + return err; +} + +static int _MMSoundMgrCodecFindLocaleSlot(int *slotid) +{ + int count = 0; + int err = MM_ERROR_NONE; + +#ifdef DEBUG_DETAIL + debug_enter("\n"); +#endif + + pthread_mutex_lock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_warning("After Slot_mutex LOCK\n"); +#endif + + for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) { + if (g_slots[count].status == STATUS_LOCALE) { + break; + } + } + pthread_mutex_unlock(&g_slot_mutex); + +#ifdef DEBUG_DETAIL + debug_warning("After Slot_mutex UNLOCK\n"); +#endif + if (count < MANAGER_HANDLE_MAX) { + debug_msg("Found locale handle allocated (Slot : [%d])\n", count); + *slotid = count; + err = MM_ERROR_NONE; + } else { + debug_warning("Handle is full handle [KEY TONE] \n"); + err = MM_ERROR_SOUND_INTERNAL; + } + +#ifdef DEBUG_DETAIL + debug_leave("\n"); +#endif + + return err; +} + +static int _MMSoundMgrCodecGetEmptySlot(int *slot) +{ + int count = 0; + int err = MM_ERROR_NONE; + +#ifdef DEBUG_DETAIL + debug_enter("\n"); +#endif + debug_msg("Codec slot ID : [%d]\n", *slot); + pthread_mutex_lock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_msg("After Slot_mutex LOCK\n"); +#endif + + for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) { + if (g_slots[count].status == STATUS_IDLE) { + g_slots[count].status = STATUS_SOUND; + break; + } + } + pthread_mutex_unlock(&g_slot_mutex); +#ifdef DEBUG_DETAIL + debug_msg("After Slot_mutex UNLOCK\n"); +#endif + + if (count < MANAGER_HANDLE_MAX) { + debug_msg("New handle allocated (codec slot ID : [%d])\n", count); + *slot = count; + err = MM_ERROR_NONE; + } else { + debug_warning("Handle is full handle : [%d]\n", count); + *slot = -1; + /* Temporal code for reset */ + while(count--) { + g_slots[count].status = STATUS_IDLE; + } + err = MM_ERROR_SOUND_INTERNAL; + } + +#ifdef DEBUG_DETAIL + debug_leave("\n"); +#endif + + return err; +} + +static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin) +{ + int err = MM_ERROR_NONE; + int count = 0; + void *getinterface = NULL; + +#ifdef DEBUG_DETAIL + debug_enter("\n"); +#endif + + /* find emptry slot */ + for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) { + if (g_plugins[count].GetSupportTypes == NULL) + break; + } + + if (count == MM_SOUND_SUPPORTED_CODEC_NUM) { + debug_critical("The plugin support type is not valid\n"); + return MM_ERROR_COMMON_OUT_OF_RANGE; + } + + err = MMSoundPluginGetSymbol(plugin, CODEC_GET_INTERFACE_FUNC_NAME, &getinterface); + if (err != MM_ERROR_NONE) { + debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err); + goto cleanup; + } + debug_msg("interface[%s] empty_slot[%d]\n", (char*)getinterface, count); + + err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]); + if (err != MM_ERROR_NONE) { + debug_error("Get interface fail : %x\n", err); + +cleanup: + /* If error occur, clean interface */ + memset(&g_plugins[count], 0, sizeof(mmsound_codec_interface_t)); + } else { + if (g_plugins[count].SetThreadPool) + g_plugins[count].SetThreadPool(MMSoundThreadPoolRun); + } + +#ifdef DEBUG_DETAIL + debug_leave("\n"); +#endif + + return err; +} + |