4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungbae Shin <seungbae.shin@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <mm_source.h>
33 #include "include/mm_sound_mgr_common.h"
34 #include "include/mm_sound_mgr_codec.h"
35 #include "include/mm_sound_plugin_codec.h"
36 #include "include/mm_sound_thread_pool.h"
37 #include "include/mm_sound_pa_client.h"
38 #include "include/mm_sound_mgr_asm.h"
42 #define _ENABLE_KEYTONE /* Temporal test code */
45 int (*callback)(int, void *, void *, int); /* msg_type(pid) client callback & client data info */
50 MMHandleType plughandle;
59 } __mmsound_mgr_codec_handle_t;
61 static MMSoundPluginType *g_codec_plugins = NULL;
62 static __mmsound_mgr_codec_handle_t g_slots[MANAGER_HANDLE_MAX];
63 static mmsound_codec_interface_t g_plugins[MM_SOUND_SUPPORTED_CODEC_NUM];
64 static pthread_mutex_t g_slot_mutex;
65 static pthread_mutex_t codec_wave_mutex;
66 static int _MMSoundMgrCodecStopCallback(int param);
67 static int _MMSoundMgrCodecFindKeytoneSlot(int *slotid);
68 static int _MMSoundMgrCodecGetEmptySlot(int *slotid);
69 static int _MMSoundMgrCodecFindLocaleSlot(int *slotid);
70 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin);
73 #define STATUS_KEYTONE 1
74 #define STATUS_LOCALE 2
75 #define STATUS_SOUND 3
77 #define SOUND_SLOT_START 0
82 sound_codec_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data)
84 int slotid = (int)cb_data;
85 int result = MM_ERROR_NONE;
86 ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
88 debug_log("Got audio session callback msg for session_handle %d\n", handle);
92 case ASM_COMMAND_STOP:
93 case ASM_COMMAND_PAUSE:
94 debug_log("Got msg from asm to Stop or Pause %d\n", command);
95 result = MMSoundMgrCodecStop(slotid);
96 if (result != MM_ERROR_NONE) {
97 debug_log("result error %d\n", result);
99 cb_res = ASM_CB_RES_STOP;
101 case ASM_COMMAND_RESUME:
102 case ASM_COMMAND_PLAY:
103 debug_log("Got msg from asm to Play or Resume %d\n", command);
104 cb_res = ASM_CB_RES_NONE;;
112 int MMSoundMgrCodecInit(const char *targetdir)
119 memset (g_slots, 0, sizeof(g_slots));
121 if(pthread_mutex_init(&g_slot_mutex, NULL)) {
122 debug_error("pthread_mutex_init failed\n");
123 return MM_ERROR_SOUND_INTERNAL;
126 if(pthread_mutex_init(&codec_wave_mutex, NULL)) {
127 debug_error("pthread_mutex_init failed\n");
128 return MM_ERROR_SOUND_INTERNAL;
131 for (count = 0; count < MANAGER_HANDLE_MAX; count++) {
132 g_slots[count].status = STATUS_IDLE;
133 g_slots[count].plughandle = 0;
136 if (g_codec_plugins) {
137 debug_warning("Please Check Init twice\n");
138 MMSoundPluginRelease(g_codec_plugins);
141 MMSoundPluginScan(targetdir, MM_SOUND_PLUGIN_TYPE_CODEC, &g_codec_plugins);
143 while (g_codec_plugins[loop].type != MM_SOUND_PLUGIN_TYPE_NONE) {
144 _MMSoundMgrCodecRegisterInterface(&g_codec_plugins[loop++]);
148 return MM_ERROR_NONE;
151 int MMSoundMgrCodecFini(void)
155 memset(g_plugins, 0, sizeof(mmsound_codec_interface_t) * MM_SOUND_SUPPORTED_CODEC_NUM);
156 MMSoundPluginRelease(g_codec_plugins);
157 g_codec_plugins = NULL;
158 pthread_mutex_destroy(&g_slot_mutex);
159 pthread_mutex_destroy(&codec_wave_mutex);
161 return MM_ERROR_NONE;
165 int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
168 mmsound_codec_info_t info;
169 mmsound_codec_param_t codec_param;
170 int err = MM_ERROR_NONE;
172 int need_asm_unregister = 0;
178 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
180 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
184 /*The count num means codec type WAV, MP3 */
185 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
187 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
188 debug_error("unsupported file type %d\n", count);
189 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
194 if (param->keytone == 1) {
195 /* Find keytone slot */
196 err = _MMSoundMgrCodecFindKeytoneSlot(slotid);
197 /* Not First connect */
198 if (err == MM_ERROR_NONE) {
199 if(g_slots[*slotid].status != STATUS_IDLE) {
200 MMSoundMgrCodecStop(*slotid);
202 debug_msg("Key tone : Stop to Play !!!\n");
204 codec_param.keytone = param->keytone;
205 } else if (param->keytone == 2) {
206 /* Find keytone slot */
207 err = _MMSoundMgrCodecFindLocaleSlot(slotid);
208 /* Not First connect */
209 if (err == MM_ERROR_NONE) {
210 if(g_slots[*slotid].status != STATUS_IDLE) {
211 MMSoundMgrCodecStop(*slotid);
213 debug_msg("Key tone : Stop to Play !!!\n");
215 codec_param.keytone = param->keytone;
218 debug_msg("Get New handle\n");
220 codec_param.keytone = 0;
223 err = _MMSoundMgrCodecGetEmptySlot(slotid);
224 if (err != MM_ERROR_NONE) {
225 debug_error("Empty g_slot is not found\n");
229 codec_param.tone = param->tone;
230 codec_param.volume_config = param->volume_config;
231 codec_param.repeat_count = param->repeat_count;
232 codec_param.volume = param->volume;
233 codec_param.source = param->source;
234 codec_param.priority = param->priority;
235 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
236 codec_param.param = *slotid;
237 codec_param.pid = (int)param->param;
238 codec_param.handle_route = param->handle_route;
239 codec_param.codec_wave_mutex = &codec_wave_mutex;
240 pthread_mutex_lock(&g_slot_mutex);
242 debug_msg("After Slot_mutex LOCK\n");
245 /* In case of KEYTONE */
246 if (param->keytone == 1)
247 g_slots[*slotid].status = STATUS_KEYTONE;
249 /* In case of LOCALE */
250 if (param->keytone == 2) /* KeyTone */
251 g_slots[*slotid].status = STATUS_LOCALE;
256 if (param->session_type != ASM_EVENT_CALL &&
257 param->session_type != ASM_EVENT_VIDEOCALL &&
258 param->session_type != ASM_EVENT_VOIP &&
259 param->session_type != ASM_EVENT_VOICE_RECOGNITION &&
260 param->priority != HANDLE_PRIORITY_SOLO &&
261 param->enable_session) {
262 if(!ASM_register_sound_ex((int)param->param, (int *)(¶m->session_handle), param->session_type, ASM_STATE_NONE,
263 sound_codec_asm_callback, (void*)*slotid, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
264 debug_critical("ASM_register_sound_ex() failed 0x%X\n", errorcode);
265 pthread_mutex_unlock(&g_slot_mutex);
266 return MM_ERROR_POLICY_INTERNAL;
268 if(param->session_options) {
269 if(!ASM_set_session_option(param->session_handle, param->session_options, &errorcode)) {
270 debug_error("ASM_set_session_option() failed 0x%x\n", errorcode);
273 if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
274 debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode);
275 pthread_mutex_unlock(&g_slot_mutex);
276 if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) {
277 debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode);
279 return MM_ERROR_POLICY_INTERNAL;
284 /* Codec id WAV or MP3 */
285 g_slots[*slotid].pluginid = count;
286 g_slots[*slotid].callback = param->callback;
287 g_slots[*slotid].msgcallback = param->msgcallback;
288 g_slots[*slotid].msgdata = param->msgdata;
289 g_slots[*slotid].param = param->param; /* This arg is used callback data */
290 g_slots[*slotid].session_type = param->session_type;
291 g_slots[*slotid].session_options = param->session_options;
292 g_slots[*slotid].session_handle = param->session_handle;
293 g_slots[*slotid].enable_session = true;
295 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
297 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
298 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
299 if (err != MM_ERROR_NONE) {
300 debug_error("Plugin create fail : 0x%08X\n", err);
301 g_slots[*slotid].status = STATUS_IDLE;
302 pthread_mutex_unlock(&g_slot_mutex);
303 debug_warning("After Slot_mutex UNLOCK\n");
304 if (param->session_handle) {
305 need_asm_unregister = 1;
310 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
311 if (err != MM_ERROR_NONE) {
312 debug_error("Fail to play : 0x%08X\n", err);
313 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
314 if (param->session_handle) {
315 need_asm_unregister = 1;
319 pthread_mutex_unlock(&g_slot_mutex);
321 debug_msg("After Slot_mutex UNLOCK\n");
325 if(param->session_type != ASM_EVENT_CALL &&
326 param->session_type != ASM_EVENT_VIDEOCALL &&
327 param->session_type != ASM_EVENT_VOIP &&
328 param->session_type != ASM_EVENT_VOICE_RECOGNITION &&
329 param->enable_session &&
330 need_asm_unregister == 1) {
331 if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_STOP, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
332 debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode);
334 if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) {
335 debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode);
336 return MM_ERROR_POLICY_INTERNAL;
347 #define DTMF_PLUGIN_COUNT 2
348 int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
352 mmsound_codec_info_t info;
353 mmsound_codec_param_t codec_param;
354 int err = MM_ERROR_NONE;
356 int need_asm_unregister = 0;
362 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
364 codec_type = g_plugins[count].GetSupportTypes();
365 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
369 /*The count num means codec type DTMF */
370 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
372 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
373 debug_error("unsupported file type %d\n", count);
374 printf("unsupported file type %d\n", count);
375 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
380 debug_msg("Get New handle\n");
382 codec_param.keytone = 0;
384 err = _MMSoundMgrCodecGetEmptySlot(slotid);
385 if(err != MM_ERROR_NONE)
387 debug_error("Empty g_slot is not found\n");
391 codec_param.tone = param->tone;
392 codec_param.priority = 0;
393 codec_param.volume_config = param->volume_config;
394 codec_param.repeat_count = param->repeat_count;
395 codec_param.volume = param->volume;
396 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
397 codec_param.param = *slotid;
398 codec_param.pid = (int)param->param;
400 pthread_mutex_lock(&g_slot_mutex);
402 debug_msg("After Slot_mutex LOCK\n");
410 if (param->session_type != ASM_EVENT_CALL &&
411 param->session_type != ASM_EVENT_VIDEOCALL &&
412 param->session_type != ASM_EVENT_VOIP &&
413 param->session_type != ASM_EVENT_VOICE_RECOGNITION &&
414 param->enable_session) {
415 if(!ASM_register_sound_ex((int)param->param, (int *)(¶m->session_handle), param->session_type, ASM_STATE_NONE,
416 sound_codec_asm_callback, (void*)*slotid, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
417 debug_critical("ASM_register_sound_ex() failed 0x%X\n", errorcode);
418 pthread_mutex_unlock(&g_slot_mutex);
419 return MM_ERROR_POLICY_INTERNAL;
421 if(param->session_options) {
422 if(!ASM_set_session_option(param->session_handle, param->session_options, &errorcode)) {
423 debug_error("ASM_set_session_option() failed 0x%x\n", errorcode);
426 if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
427 debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode);
428 pthread_mutex_unlock(&g_slot_mutex);
429 if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) {
430 debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode);
432 return MM_ERROR_POLICY_INTERNAL;
436 g_slots[*slotid].pluginid = count;
437 g_slots[*slotid].callback = param->callback;
438 g_slots[*slotid].param = param->param; /* This arg is used callback data */
439 g_slots[*slotid].session_type = param->session_type;
440 g_slots[*slotid].session_options = param->session_options;
441 g_slots[*slotid].session_handle = param->session_handle;
442 g_slots[*slotid].enable_session = param->enable_session;
445 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
448 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
449 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
450 if (err != MM_ERROR_NONE) {
451 debug_error("Plugin create fail : 0x%08X\n", err);
452 g_slots[*slotid].status = STATUS_IDLE;
453 pthread_mutex_unlock(&g_slot_mutex);
454 debug_warning("After Slot_mutex UNLOCK\n");
455 need_asm_unregister = 1;
459 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
460 if (err != MM_ERROR_NONE) {
461 debug_error("Fail to play : 0x%08X\n", err);
462 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
463 need_asm_unregister = 1;
466 pthread_mutex_unlock(&g_slot_mutex);
468 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
470 debug_msg("After Slot_mutex UNLOCK\n")
474 if (param->session_type != ASM_EVENT_CALL &&
475 param->session_type != ASM_EVENT_VIDEOCALL &&
476 param->session_type != ASM_EVENT_VOIP &&
477 param->session_type != ASM_EVENT_VOICE_RECOGNITION &&
478 param->enable_session &&
479 need_asm_unregister == 1) {
480 if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) {
481 debug_error("Unregister sound failed 0x%X\n", errorcode);
482 return MM_ERROR_POLICY_INTERNAL;
494 int MMSoundMgrCodecStop(const int slotid)
496 int err = MM_ERROR_NONE;
498 debug_enter("(Slotid : [%d])\n", slotid);
500 if (slotid < 0 || MANAGER_HANDLE_MAX <= slotid) {
501 return MM_ERROR_INVALID_ARGUMENT;
504 pthread_mutex_lock (&g_slot_mutex);
506 debug_msg("After Slot_mutex LOCK\n");
508 if (g_slots[slotid].status == STATUS_IDLE) {
509 err = MM_ERROR_SOUND_INVALID_STATE;
510 debug_warning("The playing slots is not found, Slot ID : [%d]\n", slotid);
514 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
517 err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle);
518 if (err != MM_ERROR_NONE) {
519 debug_error("Fail to STOP Code : 0x%08X\n", err);
521 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
523 pthread_mutex_unlock(&g_slot_mutex);
525 debug_msg("After Slot_mutex UNLOCK\n");
527 debug_leave("(err : 0x%08X)\n", err);
532 static int _MMSoundMgrCodecStopCallback(int param)
534 int err = MM_ERROR_NONE;
536 debug_enter("(Slot : %d)\n", param);
538 pthread_mutex_lock(&g_slot_mutex);
539 debug_msg("[CODEC MGR] Slot_mutex lock done\n");
543 * Unregister ASM here
547 debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session);
549 if (g_slots[param].session_handle) {
550 if(g_slots[param].session_type != ASM_EVENT_CALL &&
551 g_slots[param].session_type != ASM_EVENT_VIDEOCALL &&
552 g_slots[param].session_type != ASM_EVENT_VOIP &&
553 g_slots[param].session_type != ASM_EVENT_VOICE_RECOGNITION &&
554 g_slots[param].enable_session ) {
555 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)) {
556 debug_error("[CODEC MGR] ASM_set_sound_state_ex() failed 0x%X\n", errorcode);
558 debug_msg("[CODEC MGR] ASM unregister\n");
559 if(!ASM_unregister_sound_ex(g_slots[param].session_handle, g_slots[param].session_type, &errorcode, __asm_process_message)) {
560 debug_error("[CODEC MGR] ASM_unregister_sound_ex() failed 0x%X\n", errorcode);
565 if (g_slots[param].msgcallback) {
566 debug_msg("[CODEC MGR] msgcallback : %p\n", g_slots[param].msgcallback);
567 debug_msg("[CODEC MGR] msg data : %p\n", g_slots[param].msgdata);
568 debug_msg("[CODEC MGR] mgr codec callback : %p\n", g_slots[param].callback);
569 g_slots[param].callback((int)g_slots[param].param, g_slots[param].msgcallback, g_slots[param].msgdata, param); /*param means client msg_type */
571 debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
572 debug_msg("Handle allocated handle : [0x%08X]\n", g_slots[param].plughandle);
573 err = g_plugins[g_slots[param].pluginid].Destroy(g_slots[param].plughandle);
575 debug_critical("[CODEC MGR] Fail to destroy slot number : [%d] err [0x%x]\n", param, err);
577 memset(&g_slots[param], 0, sizeof(__mmsound_mgr_codec_handle_t));
578 g_slots[param].status = STATUS_IDLE;
579 pthread_mutex_unlock(&g_slot_mutex);
580 debug_msg("[CODEC MGR] Slot_mutex done\n");
585 static int _MMSoundMgrCodecFindKeytoneSlot(int *slotid)
588 int err = MM_ERROR_NONE;
594 pthread_mutex_lock(&g_slot_mutex);
596 debug_warning("After Slot_mutex LOCK\n");
599 for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
600 if (g_slots[count].status == STATUS_KEYTONE) {
604 pthread_mutex_unlock(&g_slot_mutex);
606 debug_warning("After Slot_mutex UNLOCK\n");
608 if (count < MANAGER_HANDLE_MAX) {
609 debug_msg("Found keytone handle allocated (Slot : [%d])\n", count);
613 debug_warning("Handle is full handle [KEY TONE] : [%d]\n", count);
614 err = MM_ERROR_SOUND_INTERNAL;
624 static int _MMSoundMgrCodecFindLocaleSlot(int *slotid)
627 int err = MM_ERROR_NONE;
633 pthread_mutex_lock(&g_slot_mutex);
635 debug_warning("After Slot_mutex LOCK\n");
638 for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
639 if (g_slots[count].status == STATUS_LOCALE) {
643 pthread_mutex_unlock(&g_slot_mutex);
646 debug_warning("After Slot_mutex UNLOCK\n");
648 if (count < MANAGER_HANDLE_MAX) {
649 debug_msg("Found locale handle allocated (Slot : [%d])\n", count);
653 debug_warning("Handle is full handle [KEY TONE] \n");
654 err = MM_ERROR_SOUND_INTERNAL;
664 static int _MMSoundMgrCodecGetEmptySlot(int *slot)
667 int err = MM_ERROR_NONE;
672 debug_msg("Codec slot ID : [%d]\n", *slot);
673 pthread_mutex_lock(&g_slot_mutex);
675 debug_msg("After Slot_mutex LOCK\n");
678 for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
679 if (g_slots[count].status == STATUS_IDLE) {
680 g_slots[count].status = STATUS_SOUND;
684 pthread_mutex_unlock(&g_slot_mutex);
686 debug_msg("After Slot_mutex UNLOCK\n");
689 if (count < MANAGER_HANDLE_MAX) {
690 debug_msg("New handle allocated (codec slot ID : [%d])\n", count);
694 debug_warning("Handle is full handle : [%d]\n", count);
696 /* Temporal code for reset */
698 g_slots[count].status = STATUS_IDLE;
700 err = MM_ERROR_SOUND_INTERNAL;
710 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
712 int err = MM_ERROR_NONE;
714 void *getinterface = NULL;
720 /* find emptry slot */
721 for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) {
722 if (g_plugins[count].GetSupportTypes == NULL)
726 if (count == MM_SOUND_SUPPORTED_CODEC_NUM) {
727 debug_critical("The plugin support type is not valid\n");
728 return MM_ERROR_COMMON_OUT_OF_RANGE;
731 err = MMSoundPluginGetSymbol(plugin, CODEC_GET_INTERFACE_FUNC_NAME, &getinterface);
732 if (err != MM_ERROR_NONE) {
733 debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err);
736 debug_msg("interface[%s] empty_slot[%d]\n", (char*)getinterface, count);
738 err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]);
739 if (err != MM_ERROR_NONE) {
740 debug_error("Get interface fail : %x\n", err);
743 /* If error occur, clean interface */
744 memset(&g_plugins[count], 0, sizeof(mmsound_codec_interface_t));
746 if (g_plugins[count].SetThreadPool)
747 g_plugins[count].SetThreadPool(MMSoundThreadPoolRun);