Revise code 78/82178/12
authorSeungbae Shin <seungbae.shin@samsung.com>
Wed, 20 Jul 2016 13:03:37 +0000 (22:03 +0900)
committerJeongho Mok <jho.mok@samsung.com>
Tue, 28 Mar 2017 11:04:29 +0000 (20:04 +0900)
1. fix stop sync & no callback when stop
2. remove ogg tremolo code
3. use sndfile on wav plugin (support both .wav and .ogg...)
4. fix for coding rule
5. enable focus_integration
6. remove unused mm_source
7. revise shutdown logic
8. fix invalid path handling

Change-Id: Ia6bc8e167fd4f69ac6e68dda96633f37882ff530

21 files changed:
common/Makefile.am
common/mm_source.c [deleted file]
configure.ac
focus_server/mm_sound_focus_server.c
focus_server/mm_sound_mgr_focus_dbus.c
include/mm_source.h [deleted file]
packaging/libmm-sound.spec
server/include/mm_sound_mgr_codec.h
server/include/mm_sound_plugin_codec.h
server/include/mm_sound_thread_pool.h
server/mm_sound_mgr_codec.c
server/mm_sound_mgr_ipc.c
server/mm_sound_mgr_ipc_dbus.c
server/mm_sound_server.c
server/mm_sound_thread_pool.c
server/plugin/Makefile.am
server/plugin/ogg/Makefile.am [deleted file]
server/plugin/ogg/mm_sound_plugin_codec_ogg.c [deleted file]
server/plugin/tone/mm_sound_plugin_codec_tone.c
server/plugin/wav/Makefile.am
server/plugin/wav/mm_sound_plugin_codec_wave.c

index 73719c4..2b17948 100644 (file)
@@ -2,8 +2,7 @@ lib_LTLIBRARIES = libmmfsoundcommon.la
 
 libmmfsoundcommon_la_SOURCES = mm_ipc.c \
                                                        mm_sound_utils.c \
-                                                       mm_sound_dbus.c \
-                                                       mm_source.c
+                                                       mm_sound_dbus.c
 
 #libmmfsoundcommon_la_DEPENDENCIES = $(libdir)/libmmfcommon.la
 
diff --git a/common/mm_source.c b/common/mm_source.c
deleted file mode 100644 (file)
index 9931b9d..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "mm_types.h"
-#include "mm_debug.h"
-#include "mm_error.h"
-#include "mm_source.h"
-#include "mm_sound_common.h"
-
-static bool _is_drm_file(const char *filePath)
-{
-       char *p = NULL;
-
-       if(!filePath || filePath[0] == '\0') {
-               debug_error("invalid argument\n");
-               return false;
-       }
-
-       p = (char*) strrchr(filePath, '.');
-       if( p &&  ((strncasecmp(p, ".odf", 4) == 0) || (strncasecmp(p, ".dcf", 4) == 0) ||
-                       (strncasecmp(p, ".o4a", 4) == 0) || (strncasecmp(p, ".o4v", 4) == 0))) {
-       return true;
-       }
-       return false;
-}
-
-EXPORT_API
-int mm_source_open_file(const char *filename, MMSourceType *source, int drmsupport)
-{
-       struct stat finfo = {0, };
-       int fd = -1;
-       void *mmap_buf = NULL;
-       unsigned int mediaSize, offSet=0;
-       int readSize = 0;
-       char genStr[20];
-       int i;
-
-       if(filename == NULL) {
-               debug_error("filename is null\n");
-               return MM_ERROR_SOUND_INVALID_FILE;
-       }
-       if(drmsupport) {
-               if(_is_drm_file(filename)) {
-                       debug_error("%s is DRM contents\n", filename);
-                       return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
-               }
-       }
-
-       fd = open(filename, O_RDONLY);
-       if (fd == -1) {
-               char str_error[256];
-               strerror_r(errno, str_error, sizeof(str_error));
-               debug_error("file [%s] open fail [%s]\n", filename, str_error);
-               return MM_ERROR_SOUND_INTERNAL;
-       }
-       if (fstat(fd, &finfo) == -1) {
-               debug_error("file [%s] get info fail\n", filename);
-               close(fd);
-               return MM_ERROR_SOUND_INTERNAL;
-       }
-
-       mediaSize = (unsigned int)finfo.st_size;
-
-    /* get the extension (3 characters from last including NULL)*/
-       strncpy((void *)genStr,(void *)(filename+(strlen(filename)-2)),3);
-
-#if defined(_DEBUG_VERBOS_)
-       debug_log("Open file [%s] ext[%s]\n", filename, genStr);
-#endif
-
-       if(strcasecmp (genStr, "dm") == 0) {
-               debug_msg("It is DM file going ahead with special decoding\n");
-
-               /* Vlidation of the DM file */
-               readSize = read(fd,(void*)genStr,0x8);
-               if(readSize != 0x8)     {
-                       debug_error("Error in Reading the file Header %x/0x8\n",readSize);
-                       close(fd);
-                       return MM_ERROR_SOUND_INTERNAL;
-               }
-
-               genStr[readSize] ='\0';
-
-               debug_msg("Header details of DM file %s\n",genStr);
-
-               if(strcasecmp (genStr, "--random") != 0) {
-                       debug_error("It is not a valied DM file");
-                       close(fd);
-                       return MM_ERROR_SOUND_INTERNAL;
-               }
-
-               /*checking the Media Type */
-               readSize = lseek(fd, 0x32, SEEK_SET);
-               if(readSize != 0x32) {
-                       debug_error("Error in Seeking the file to offset %x/0x32\n",readSize);
-                       close(fd);
-                       return MM_ERROR_SOUND_INTERNAL;
-               }
-
-               readSize = read(fd,(void*)genStr,0xf);
-               if (readSize != 0xf) {
-                       debug_error("Error in Reading the file Header %x/0xf\n",readSize);
-                       close(fd);
-                       return MM_ERROR_SOUND_INTERNAL;
-               }
-               for(i=0;i<0xf;i++) {
-                       if(genStr[i] == (char)0xD) {
-                               genStr[i] ='\0';
-                               break;
-                       }
-               }
-
-               debug_msg("Header details of DM file %s\n",genStr);
-
-               /*Finding the Media Offset */
-
-               if(strcasecmp (genStr, "audio/mpeg") == 0) {
-                       offSet = 0x63;
-               } else if(strcasecmp (genStr, "audio/wav") == 0) {
-                       offSet = 0x62;
-               } else {
-                       debug_error("It is not MP3/Wav DM file \n");
-                       close(fd);
-                       return MM_ERROR_SOUND_INTERNAL;
-               }
-
-               /*Finding the Media Size */
-               mediaSize -= (offSet + 0x28);
-
-               /*Seeking the file to start */
-               readSize = lseek(fd, 0x0, SEEK_SET);
-
-               if( readSize != 0x0) {
-                       debug_error("Error in Seeking the file to offset %x/0x32\n",readSize);
-                       close(fd);
-                       return MM_ERROR_SOUND_INTERNAL;
-               }
-       }
-
-       mmap_buf  = mmap(0, finfo.st_size, PROT_READ, MAP_SHARED, fd,0);
-       if (mmap_buf == NULL) {
-               debug_error("MMAP fail\n");
-               close(fd);
-               return MM_ERROR_SOUND_INTERNAL;
-       }
-       source->ptr = mmap_buf+offSet;
-       source->medOffset = offSet;
-#if defined(_DEBUG_VERBOS_)
-       debug_log("source ptr[%p] med offset size[%d]\n", source->ptr, source->medOffset);
-#endif
-       source->tot_size = finfo.st_size;
-       source->cur_size = mediaSize;
-       source->type = MM_SOURCE_FILE;
-       source->fd = fd;
-
-       return MM_ERROR_NONE;
-}
-
-EXPORT_API
-int mm_source_open_full_memory(const void *ptr, int totsize, int alloc, MMSourceType *source)
-{
-       int err = MM_ERROR_NONE;
-       if (ptr == NULL) {
-               debug_error("PTR is NULL\n");
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
-
-       if (alloc) {
-               err = mm_source_open_memory(ptr, totsize, totsize, source);
-       } else {
-               source->ptr = (void *)ptr;
-               source->tot_size = totsize;
-               source->cur_size = totsize;
-               source->type = MM_SOURCE_MEMORY_NOTALLOC;
-               source->fd = -1;
-       }
-
-       return err;
-}
-
-EXPORT_API
-int mm_source_open_memory(const void *ptr, int totsize, int size, MMSourceType *source)
-{
-       source->ptr = (unsigned char*) malloc(totsize);
-       if (source->ptr == NULL) {
-               debug_error("memory alloc fail\n");
-               return MM_ERROR_SOUND_NO_FREE_SPACE;
-       }
-       source->tot_size = totsize;
-       source->cur_size = 0;
-       source->type = MM_SOURCE_MEMORY;
-       source->fd = -1;
-
-       return mm_source_append_memory(ptr, size, source);
-}
-
-EXPORT_API
-int mm_source_append_memory(const void *ptr, int size, MMSourceType *source)
-{
-       if (source->cur_size + size > source->tot_size) {
-               debug_error("memory too large\n");
-               return MM_ERROR_SOUND_NO_FREE_SPACE;
-       }
-
-       memcpy(source->ptr + source->cur_size, ptr, size);
-       source->cur_size += size;
-       return MM_ERROR_NONE;
-}
-
-EXPORT_API
-int mm_source_close(MMSourceType *source)
-{
-       if(source == NULL) {
-               debug_critical("source is null\n");
-               return MM_ERROR_CLASS;
-       }
-
-#if defined(_DEBUG_VERBOS_)
-       debug_log("Source type = %d\n", source->type);
-#endif
-       switch(source->type)
-       {
-       case MM_SOURCE_FILE:
-               if(source->ptr != NULL) {
-                       source->ptr -= source->medOffset;
-#if defined(_DEBUG_VERBOS_)
-                       debug_log("Med Offset Size : %d/%d",source->medOffset,source->tot_size);
-#endif
-                       if (munmap(source->ptr, source->tot_size) == -1) {
-                               debug_error("MEM UNMAP fail\n\n");
-                       }
-                 }
-               close(source->fd);
-               break;
-
-       case MM_SOURCE_MEMORY:
-               if(source->ptr != NULL)
-                       free(source->ptr);
-               break;
-
-       case MM_SOURCE_MEMORY_NOTALLOC:
-               break;
-
-       default:
-               debug_critical("Unknown Source\n");
-               break;
-       }
-       memset(source, 0, sizeof(MMSourceType));
-
-       return MM_ERROR_NONE;
-}
index f1f80bd..8dcc4f8 100644 (file)
@@ -54,6 +54,10 @@ PKG_CHECK_MODULES(VCONF, vconf)
 AC_SUBST(VCONF_CFLAGS)
 AC_SUBST(VCONF_LIBS)
 
+PKG_CHECK_MODULES(VCONF, sndfile)
+AC_SUBST(SNDFILE_CFLAGS)
+AC_SUBST(SNDFILE_LIBS)
+
 AC_ARG_ENABLE(pulse, AC_HELP_STRING([--enable-pulse], [enable pulseaudio client]),
 [
  case "${enableval}" in
@@ -72,21 +76,6 @@ AC_SUBST(PA_LIBS)
 fi
 AM_CONDITIONAL([USE_PULSE], [test "x$USE_PULSE" = "xyes"])
 
-AC_ARG_ENABLE(ogg, AC_HELP_STRING([--enable-ogg], [enable ogg client]),
-[
- case "${enableval}" in
-        yes) OGG_SUPPORT=yes ;;
-        no)  OGG_SUPPORT=no ;;
-        *)   AC_MSG_ERROR(bad value ${enableval} for --enable-ogg) ;;
- esac
- ],[OGG_SUPPORT=no])
-if test "x$OGG_SUPPORT" = "xyes"; then
-PKG_CHECK_MODULES(TREMOLO, libtremolo)
-AC_SUBST(TREMOLO_CFLAGS)
-AC_SUBST(TREMOLO_LIBS)
-fi
-AM_CONDITIONAL([OGG_SUPPORT], [test "x$OGG_SUPPORT" = "xyes"])
-
 AC_ARG_ENABLE(lwipc, AC_HELP_STRING([--enable-lwipc], [enable light weight ipc]),
 [
  case "${enableval}" in
@@ -154,7 +143,6 @@ Makefile
 server/Makefile
 server/plugin/Makefile
 server/plugin/wav/Makefile
-server/plugin/ogg/Makefile
 server/plugin/tone/Makefile
 focus_server/Makefile
 pkgconfig/Makefile
index 4a70e8a..b50063e 100644 (file)
@@ -64,9 +64,9 @@ static void _mainloop_run()
        g_main_loop_run(g_mainloop);
 }
 
-static sem_t* _sem_create_n_wait()
+static sem_t * _sem_create_n_wait()
 {
-       sem_tsem = NULL;
+       sem_t *sem = NULL;
 
        if ((sem = sem_open("booting-sound", O_CREAT, 0660, 0)) == SEM_FAILED) {
                debug_error("error creating sem : %d", errno);
@@ -142,7 +142,7 @@ static void _generate_ready_file(const char *path)
 
 int main(int argc, char **argv)
 {
-       sem_tsem = NULL;
+       sem_t *sem = NULL;
        server_arg serveropt;
 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
        int pid;
index 2a242c8..d14658c 100644 (file)
@@ -511,7 +511,7 @@ static void handle_method_call(GDBusConnection *connection,
                debug_error("Parameter Null");
                return;
        }
-       debug_log("Method Call, obj : %s, intf : %s, method : %s", object_path, interface_name, method_name);
+       debug_msg("Method Call, obj : %s, intf : %s, method : %s", object_path, interface_name, method_name);
 
        for (method_idx = AUDIO_METHOD_GET_UNIQUE_ID; method_idx < AUDIO_METHOD_MAX; method_idx++) {
                if (!g_strcmp0(method_name, methods[method_idx].info.name)) {
diff --git a/include/mm_source.h b/include/mm_source.h
deleted file mode 100644 (file)
index 1cf09db..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.
- *
- */
-
-#ifndef __MM_SOURCE_H__
-#define __MM_SOURCE_H__
-
-enum {
-    MM_SOURCE_NONE = 0,
-    MM_SOURCE_FILE,
-    MM_SOURCE_MEMORY,
-    MM_SOURCE_MEMORY_NOTALLOC,
-    MM_SOURCE_NUM,
-};
-
-enum {
-       MM_SOURCE_NOT_DRM_CONTENTS = 0,
-       MM_SOURCE_CHECK_DRM_CONTENTS
-};
-
-typedef struct {
-    int             type;           /**< source type (file or memory) */
-    void            *ptr;           /**< pointer to buffer */
-    unsigned int    cur_size;       /**< size of current memory */
-    unsigned int    tot_size;       /**< size of current memory */
-    int             fd;             /**< file descriptor for file */
-       unsigned int    medOffset;              /**Media Offset */
-} MMSourceType;
-
-#define MMSourceIsUnUsed(psource) \
-    ((psource)->type == MM_SOUND_SOURCE_NONE)
-
-#define MMSourceIsFile(psource) \
-    ((psource)->type == MM_SOUND_SOURCE_FILE)
-
-#define MMSourceIsMemory(psource) \
-    ((psource)->type == MM_SOUND_SOURCE_MEMORY)
-
-#define MMSourceGetPtr(psource) \
-    ((psource)->ptr)
-
-#define MMSourceGetCurSize(psource) \
-    ((psource)->cur_size)
-
-#define MMSourceGetTotSize(psource) \
-    ((psource)->tot_size)
-
-int mm_source_open_file(const char *filename, MMSourceType* source, int drmsupport);
-int mm_source_open_full_memory(const void *ptr, int totsize, int alloc, MMSourceType *source);
-int mm_source_open_memory(const void *ptr, int totsize, int size, MMSourceType *source);
-int mm_source_append_memory(const void *ptr, int size, MMSourceType *source);
-int mm_source_close(MMSourceType *source);
-
-#endif  /* __MM_SOURCE_H__ */
-
index c50bd49..78cea47 100644 (file)
@@ -23,12 +23,12 @@ BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(vconf)
 BuildRequires: pkgconfig(libpulse)
+BuildRequires: pkgconfig(sndfile)
 %if "%{?TIZEN_PRODUCT_TV}" == "1"
 BuildRequires: pkgconfig(lwipc)
 %endif
 %ifarch %{arm}
 %endif
-BuildRequires: pkgconfig(libtremolo)
 
 %description
 MMSound Package contains client lib and sound_server binary for sound system
@@ -62,7 +62,6 @@ MMSound utility package - contians mm_sound_testsuite, sound_check for sound sys
 %setup -q
 
 %build
-%define tizen_audio_feature_ogg_enable 1
 
 CFLAGS="%{optflags} -fvisibility=hidden -D_TIZEN_PUBLIC_ -DMM_DEBUG_FLAG -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\"" ;export CFLAGS
 
@@ -72,10 +71,7 @@ CFLAGS="%{optflags} -fvisibility=hidden -D_TIZEN_PUBLIC_ -DMM_DEBUG_FLAG -DEXPOR
 
 ./autogen.sh
 %configure \
-%if 0%{?tizen_audio_feature_ogg_enable}
-       --enable-ogg \
        --with-plugindir=%{_libdir}/soundplugins/ \
-%endif
 %if "%{?TIZEN_PRODUCT_TV}" == "1"
        --enable-prelink \
        --enable-lwipc \
@@ -125,9 +121,6 @@ ln -sf ../focus-server.path %{buildroot}%{_unitdir}/multi-user.target.wants/focu
 %{_libdir}/libmmfbootsound.so.*
 %{_libdir}/libsoundplugintone.so*
 %{_libdir}/libsoundpluginwave.so*
-%if 0%{?tizen_audio_feature_ogg_enable}
-%{_libdir}/libsoundplugintremoloogg.so*
-%endif
 %{_libdir}/soundplugins/libsoundplugintone.so
 %{_libdir}/soundplugins/libsoundpluginwave.so
 %if 0%{?tizen_audio_feature_ogg_enable}
index ce7344a..e15062e 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <stdbool.h>
 
-#include <mm_source.h>
 #include <mm_sound_stream.h>
 #include "../../include/mm_sound.h"
 
@@ -43,7 +42,7 @@ typedef struct {
        void *msgcallback;              /* Client callback function */
        void *msgdata;                  /* Client callback data */
        void *param;
-       MMSourceType *source; /* Will free plugin */
+       char *pfilename;
        int samplerate;
        int channels;
        int volume_config;
@@ -58,7 +57,7 @@ enum
        MM_SOUND_CODEC_OP_SOUND,
 };
 
-int MMSoundMgrCodecInit(const char *targetdir);
+int MMSoundMgrCodecInit(const char *targetdir, GSourceFunc _shutdown_cb);
 int MMSoundMgrCodecFini(void);
 
 int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param);
index a419978..5c04a2c 100644 (file)
 #define __MM_SOUND_PLUGIN_CODEC_H__
 
 #include "mm_sound_plugin.h"
-#include <mm_source.h>
 #include <mm_types.h>
 
 #define MM_SOUND_STREAM_TYPE_LEN 64
+#define MM_SOUND_MAX_FILENAME 256
 
 enum MMSoundSupportedCodec {
        MM_SOUND_SUPPORTED_CODEC_INVALID = -1,  /**< Invalid codec type */
        MM_SOUND_SUPPORTED_CODEC_WAVE,                  /**< WAVE codec         */
-       MM_SOUND_SUPPORTED_CODEC_OGG,           /**< OGG codec          */
        MM_SOUND_SUPPORTED_CODEC_DTMF,                  /**< DTMF codec         */
-       MM_SOUND_SUPPORTED_CODEC_MP3,                   /**< MP3 codec          */
        MM_SOUND_SUPPORTED_CODEC_NUM,                   /**< Number of audio codec type */
 };
 
@@ -56,7 +54,7 @@ typedef struct {
        double volume;
        int volume_config;
        int keytone;
-       MMSourceType *source;
+       char *pfilename;
        char stream_type[MM_SOUND_STREAM_TYPE_LEN];
        int stream_index;
        pthread_mutex_t *codec_wave_mutex;
@@ -65,9 +63,8 @@ typedef struct {
 typedef struct {
     int* (*GetSupportTypes)(void);
     int (*SetThreadPool) (int (*)(void*, void (*)(void*)));
-    int (*Parse)(MMSourceType*, mmsound_codec_info_t*);
+    int (*Parse)(const char*, mmsound_codec_info_t*);
     int (*Create)(mmsound_codec_param_t*, mmsound_codec_info_t*, MMHandleType*);
-    int (*Play_wav)(mmsound_codec_param_t *, mmsound_codec_info_t *, MMHandleType );
     int (*Play)(MMHandleType);
     int (*Stop)(MMHandleType);
     int (*Destroy)(MMHandleType);
index 8084040..69db759 100644 (file)
@@ -26,7 +26,6 @@
 
 int MMSoundThreadPoolDump(int fulldump);
 int MMSoundThreadPoolInit(void);
-gboolean IsMMSoundThreadPoolRunning(void);
 int MMSoundThreadPoolRun(void *param, void (*func)(void*));
 int MMSoundThreadPoolFini(void);
 
index 5c50d97..c604cf3 100644 (file)
 #include <stdio.h>
 #include <string.h>
 #include <pthread.h>
+#include <unistd.h>
+#include <errno.h>
 
-#include <mm_source.h>
 #include <mm_error.h>
 #include <mm_types.h>
 #include <mm_debug.h>
 #include <mm_ipc.h>
 #include <mm_session.h>
 
+#include <glib.h>
+
 #include "include/mm_sound_mgr_common.h"
 #include "include/mm_sound_mgr_codec.h"
 #include "include/mm_sound_mgr_ipc.h"
 #include "../include/mm_sound_common.h"
 #include "../include/mm_sound_focus.h"
 
-#define _ENABLE_KEYTONE        /* Temporal test code */
-
+#define SHUTDOWN_TIMEOUT_SEC 10
+#define STATUS_IDLE 0
+#define STATUS_SOUND 3
+#define SOUND_SLOT_START 0
 #define FOCUS_INTEGRATION
 
 typedef struct {
@@ -63,6 +68,7 @@ typedef struct {
        unsigned int subs_id;
        mm_sound_focus_type_e current_focus_type;
 #endif
+       bool stop_by_user;
 
        bool enable_session;
  } __mmsound_mgr_codec_handle_t;
@@ -71,125 +77,191 @@ 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 _MMSoundMgrCodecGetEmptySlot(int *slotid);
-static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin);
+GSourceFunc g_shutdown_cb;
+guint g_timer_id = 0;
 
-#define STATUS_IDLE 0
-#define STATUS_SOUND 3
+#define SLOT_LOCK() do { pthread_mutex_lock(&g_slot_mutex); /* debug_msg("After Slot_mutex LOCK\n"); */ } while (0)
+#define SLOT_UNLOCK() do { pthread_mutex_unlock(&g_slot_mutex); /* debug_msg("After Slot_mutex UNLOCK\n"); */ } while (0)
+
+static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin);
+static int _MMSoundMgrCodecStopCallback(int param);
 
-#define SOUND_SLOT_START 0
 
 #ifdef FOCUS_INTEGRATION
 
-void sound_codec_focus_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state, const char *reason_for_change, int option, const char *ext_info, void *user_data)
+static void _handle_focus_event(int slotid, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state, bool is_watch)
 {
-
-       int slotid = (int)user_data;
        int result = MM_ERROR_NONE;
 
-       debug_warning ("focus callback called -> focus_stae(%d), reasoun_for_change(%s)", focus_state, reason_for_change ? reason_for_change : "N/A");
-
-       if(g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE){
-               debug_warning ("session option is UNINTERRUPTIBLE, nothing to do with focus");
+       if (g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
+               debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
                return;
        }
+
        if (focus_state == FOCUS_IS_RELEASED) {
-               g_slots[slotid].current_focus_type = FOCUS_FOR_BOTH&(~focus_type);
-               debug_warning ("focus is released -> stop playing");
-               result = MMSoundMgrCodecStop(slotid);
-               if (result != MM_ERROR_NONE) {
-                       debug_log("result error %d\n", result);
-               }
+               if (!is_watch)
+                       g_slots[slotid].current_focus_type = FOCUS_FOR_BOTH & (~focus_type);
+               debug_warning("focus is released -> stop playing");
 
+               result = MMSoundMgrCodecStop(slotid);
+               if (result != MM_ERROR_NONE)
+                       debug_error("result error 0x%X", result);
        }
-       return;
 }
 
-void sound_codec_focus_watch_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state, const char *reason_for_change, const char* ext_info, void *user_data)
+static void _sound_codec_focus_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state,
+                                                                               const char *reason_for_change, int option, const char *ext_info, void *user_data)
+{
+       debug_warning("focus callback called -> focus_state(%d), reason_for_change(%s)",
+                       focus_state, reason_for_change ? reason_for_change : "N/A");
+
+       _handle_focus_event((int)user_data, focus_type, focus_state, false);
+}
+
+static void _sound_codec_focus_watch_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state,
+                                                                                       const char *reason_for_change, const char *ext_info, void *user_data)
+{
+       debug_warning("focus watch callback called -> focus_state(%d), reason_for_change(%s)",
+                               focus_state, reason_for_change ? reason_for_change : "N/A");
+
+       _handle_focus_event((int)user_data, focus_type, focus_state, true);
+}
+
+static void _sound_codec_device_connected_callback(MMSoundDevice_t device, bool is_connected, void *user_data)
 {
        int slotid = (int)user_data;
        int result = MM_ERROR_NONE;
+       mm_sound_device_type_e type;
 
-       debug_warning ("focus callback called -> focus_stae(%d), reasoun_for_change(%s)", focus_state, reason_for_change ? reason_for_change : "N/A");
+       debug_warning ("device_connected_callback called : handle[%p], connected[%d], slotid[%d]", device, is_connected, slotid);
 
-       if(g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE){
-               debug_warning ("session option is UNINTERRUPTIBLE, nothing to do with focus");
+       if (mm_sound_get_device_type (device, &type) != MM_ERROR_NONE) {
+               debug_error("getting device type failed");
                return;
        }
-       if (focus_state == FOCUS_IS_ACQUIRED) {
-               debug_warning ("focus is released -> stop playing");
-               result = MMSoundMgrCodecStop(slotid);
-               if (result != MM_ERROR_NONE) {
-                       debug_log("result error %d\n", result);
-               }
 
+       switch (type) {
+               case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
+               case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
+               case MM_SOUND_DEVICE_TYPE_HDMI:
+               case MM_SOUND_DEVICE_TYPE_MIRRORING:
+               case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
+                       if (!is_connected) {
+                               debug_warning("sound device unplugged");
+                               result = MMSoundMgrCodecStop(slotid);
+                               if (result != MM_ERROR_NONE)
+                                       debug_error("MMSoundMgrCodecStop error %d\n", result);
+
+                               result = mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id);
+                               if (result != MM_ERROR_NONE)
+                                       debug_error("mm_sound_remove_device_connected_callback error %d\n", result);
+                       }
+                       break;
+
+               default:
+                       break;
        }
-       return;
 }
+#endif
+
+/* FIXME : critical section for g_timer_id? */
+static void _mm_sound_mgr_codec_shutdown_timer_start()
+{
+       if (g_timer_id > 0) {
+               debug_error("Already active timer [%d] exists", g_timer_id);
+               return;
+       }
 
+       if (g_shutdown_cb) {
+               g_timer_id = g_timeout_add_seconds(SHUTDOWN_TIMEOUT_SEC, g_shutdown_cb, NULL);
+               debug_error("TIMER : new timer [%d]", g_timer_id);
+       } else {
+               debug_warning("No Timer started due to invalid shutdown callback");
+       }
+}
 
-void sound_codec_device_connected_callback(MMSoundDevice_t device, bool is_connected, void *user_data)
+static void _mm_sound_mgr_codec_shutdown_timer_stop()
 {
-       int slotid = (int)user_data;
-       int result = MM_ERROR_NONE;
-       mm_sound_device_type_e type;
+       if (g_timer_id > 0) {
+               debug_error("TIMER : remove timer id [%d]", g_timer_id);
+               g_source_remove(g_timer_id);
+               g_timer_id = 0;
+       } else {
+               debug_log("No Timer to stop...");
+       }
+}
 
-       debug_warning ("device_connected_callback called");
+static int _mm_sound_mgr_codec_slot_get_empty(int *slot)
+{
+       int slotid = 0;
+       int err = MM_ERROR_NONE;
+
+       SLOT_LOCK();
+
+       for (slotid = SOUND_SLOT_START; slotid < MANAGER_HANDLE_MAX ; slotid++) {
+               if (g_slots[slotid].status == STATUS_IDLE) {
+                       g_slots[slotid].status = STATUS_SOUND;
+                       break;
+               }
+       }
+
+       if (slotid < MANAGER_HANDLE_MAX) {
+               debug_msg("New handle allocated (codec slot ID : [%d])\n", slotid);
+               *slot = slotid;
+
+               _mm_sound_mgr_codec_shutdown_timer_stop();
 
-       if (mm_sound_get_device_type (device, &type) != MM_ERROR_NONE) {
-               debug_error("getting device type failed");
        } else {
-               switch (type) {
-                       case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
-                       case MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP:
-                       case MM_SOUND_DEVICE_TYPE_BLUETOOTH_SCO:
-                       case MM_SOUND_DEVICE_TYPE_HDMI:
-                       case MM_SOUND_DEVICE_TYPE_MIRRORING:
-                       case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
-                               if (!is_connected) {
-                                       debug_warning("sound device unplugged");
-                                       result = MMSoundMgrCodecStop(slotid);
-                                       if (result != MM_ERROR_NONE) {
-                                               debug_error("MMSoundMgrCodecStop error %d\n", result);
-                                       }
-                                       result = mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id);
-                                       if (result != MM_ERROR_NONE) {
-                                               debug_error("mm_sound_remove_device_connected_callback error %d\n", result);
-                                       }
-                               }
-                               break;
-                       default:
-                               break;
+               debug_warning("Handle is full handle : [%d]\n", slotid);
+               *slot = -1;
+               /* Temporal code for reset */
+               while (slotid--) {
+                       g_slots[slotid].status = STATUS_IDLE;
                }
+               err = MM_ERROR_SOUND_INTERNAL;
        }
+
+       SLOT_UNLOCK();
+
+       return err;
 }
-#endif
 
-int MMSoundMgrCodecInit(const char *targetdir)
+static gboolean _mm_sound_mgr_codec_slot_is_empty()
 {
-       int loop = 0;
-       int count = 0;
+       int slotid = 0;
 
-       debug_enter("\n");
+       for (slotid = SOUND_SLOT_START; slotid < MANAGER_HANDLE_MAX ; slotid++) {
+               if (g_slots[slotid].status == STATUS_SOUND)
+                       break;
+       }
 
-       memset (g_slots, 0, sizeof(g_slots));
+       return (slotid == MANAGER_HANDLE_MAX) ? TRUE : FALSE;
+}
 
-       if(pthread_mutex_init(&g_slot_mutex, NULL)) {
-               debug_error("pthread_mutex_init failed\n");
-               return MM_ERROR_SOUND_INTERNAL;
-       }
+static void _mm_sound_mgr_codec_slot_clear(int slotid)
+{
+       memset(&g_slots[slotid], 0, sizeof(__mmsound_mgr_codec_handle_t));
+       g_slots[slotid].status = STATUS_IDLE;
+
+       debug_error("SlotID [%d] cleared", slotid);
+}
+
+int MMSoundMgrCodecInit(const char *targetdir, GSourceFunc _shutdown_cb)
+{
+       int loop = 0;
+       int slotid = 0;
 
-       if(pthread_mutex_init(&codec_wave_mutex, NULL)) {
+       debug_enter();
+
+       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;
        }
 
-       for (count = 0; count < MANAGER_HANDLE_MAX; count++) {
-               g_slots[count].status = STATUS_IDLE;
-               g_slots[count].plughandle = 0;
-       }
+       for (slotid = 0; slotid < MANAGER_HANDLE_MAX; slotid++)
+               _mm_sound_mgr_codec_slot_clear(slotid);
 
        if (g_codec_plugins) {
                debug_warning("Please Check Init twice\n");
@@ -203,59 +275,78 @@ int MMSoundMgrCodecInit(const char *targetdir)
                }
        }
 
-       debug_leave("\n");
+       if (_shutdown_cb)
+               g_shutdown_cb = _shutdown_cb;
+       else
+               debug_warning("shutdown callback is NULL");
+
+       debug_leave();
        return MM_ERROR_NONE;
 }
 
 int MMSoundMgrCodecFini(void)
 {
-       debug_enter("\n");
+       debug_enter();
 
        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");
+
+       debug_leave();
        return MM_ERROR_NONE;
 }
 
+static int _MMSoundMgrCodecFindCodecPluginID(enum MMSoundSupportedCodec codec_to_find)
+{
+       int plugin_id = 0;
+       int *codec_type;
+
+       for (plugin_id = 0; plugin_id < MM_SOUND_SUPPORTED_CODEC_NUM; plugin_id++) {
+               if (g_plugins[plugin_id].GetSupportTypes) {
+                       codec_type = g_plugins[plugin_id].GetSupportTypes();
+                       if (codec_type[0] == codec_to_find)
+                               return plugin_id;
+               }
+       }
+
+       return -1;
+}
 
 int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
 {
-       int count = 0;
+       int plugin_id = 0;
        mmsound_codec_info_t info;
        mmsound_codec_param_t codec_param;
        int err = MM_ERROR_NONE;
+
 #ifdef FOCUS_INTEGRATION
        int need_focus_unregister = 0;
 #endif
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
-
-       for (count = 0; g_plugins[count].GetSupportTypes; count++) {
-               /* Find codec */
-               if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
-                       break;
+       plugin_id = _MMSoundMgrCodecFindCodecPluginID(MM_SOUND_SUPPORTED_CODEC_WAVE);
+       if (plugin_id == -1) {
+               debug_error("Could not find proper codec plugin!!!");
+               err = MM_ERROR_SOUND_INTERNAL;
+               goto cleanup;
        }
 
-       /*The count num means codec type WAV, MP3 */
-       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d], session(type[%d],option[%d])\n",
-               param->tone, param->repeat_count, param->volume, count, param->session_type, param->session_options);
-
-       if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
-               debug_error("unsupported file type %d\n", count);
-               err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
+       err = g_plugins[plugin_id].Parse(param->pfilename, &info);
+       if (err != MM_ERROR_NONE) {
+               debug_error("Could not parse file [%s] by plugin[%d]\n", param->pfilename, plugin_id);
                goto cleanup;
        }
 
+       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, plugin_id);
+
 #ifdef DEBUG_DETAIL
        debug_msg("Get New handle\n");
 #endif
 
-       err = _MMSoundMgrCodecGetEmptySlot(slotid);
+       err = _mm_sound_mgr_codec_slot_get_empty(slotid);
        if (err != MM_ERROR_NONE || *slotid < 0) {
                debug_error("Empty g_slot is not found\n");
                goto cleanup;
@@ -265,17 +356,13 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
        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.pfilename = param->pfilename;
        codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
        codec_param.param = *slotid;
        codec_param.pid = (int)param->param;
-       codec_param.codec_wave_mutex = &codec_wave_mutex;
        codec_param.stream_index = param->stream_index;
        MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
+       SLOT_LOCK();
 
 #ifdef FOCUS_INTEGRATION
        /*
@@ -290,28 +377,33 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
 
                unsigned int subs_id = 0;
 
-               err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG, (mm_sound_device_connected_cb)sound_codec_device_connected_callback, (void*) *slotid, &subs_id);
+               err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG,
+                                                                                                       (mm_sound_device_connected_cb)_sound_codec_device_connected_callback,
+                                                                                                       (void*) *slotid, &subs_id);
                if (err) {
                        debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
-                       pthread_mutex_unlock(&g_slot_mutex);
+                       SLOT_UNLOCK();
                        return MM_ERROR_POLICY_INTERNAL;
                }
                g_slots[*slotid].subs_id = subs_id;
 
-               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
+               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                       param->session_type == MM_SESSION_TYPE_ALARM ||
+                       param->session_type == MM_SESSION_TYPE_NOTIFY ||
+                       param->session_type == MM_SESSION_TYPE_EMERGENCY) {
                        debug_warning("session option is PAUSE_OTHERS -> acquire focus");
                        err = mm_sound_focus_get_id((int *)(&param->focus_handle));
-                       err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
+                       err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", _sound_codec_focus_callback, (void*)*slotid);
                        if (err) {
                                debug_error("mm_sound_register_focus_for_session failed [0x%x]", err);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                        err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
                        if (err) {
                                debug_error("mm_sound_acquire_focus failed [0x%x]", err);
                                err = mm_sound_unregister_focus(param->focus_handle);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                        g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
@@ -320,10 +412,11 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
                        debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
                } else {
                        debug_warning("need to set focus watch callback");
-                       err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, sound_codec_focus_watch_callback, (void*)*slotid, (int *)(&param->focus_wcb_id));
+                       err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, _sound_codec_focus_watch_callback,
+                                                                                                                               (void*)*slotid, (int *)(&param->focus_wcb_id));
                        if (err) {
                                debug_error("mm_sound_set_focus_watch_callback_for_session failed [0x%x]", err);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                }
@@ -332,7 +425,7 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
 #endif
 
        /* Codec id WAV or MP3 */
-       g_slots[*slotid].pluginid = count;
+       g_slots[*slotid].pluginid = plugin_id;
        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;
@@ -351,8 +444,7 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
        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");
+               SLOT_UNLOCK();
 #ifdef FOCUS_INTEGRATION
                if (param->focus_handle) {
                        need_focus_unregister = 1;
@@ -372,23 +464,26 @@ int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
 #endif
        }
 
-       pthread_mutex_unlock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex UNLOCK\n");
-#endif
+       SLOT_UNLOCK();
 
 cleanup:
+       if (_mm_sound_mgr_codec_slot_is_empty())
+               _mm_sound_mgr_codec_shutdown_timer_start();
+
 #ifdef FOCUS_INTEGRATION
-       if(param->session_type != MM_SESSION_TYPE_CALL &&
+       if (param->session_type != MM_SESSION_TYPE_CALL &&
                param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
                param->session_type != MM_SESSION_TYPE_VOIP &&
                param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
                param->enable_session &&
                need_focus_unregister == 1) {
 
-               if (param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
+               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                       param->session_type == MM_SESSION_TYPE_ALARM ||
+                       param->session_type == MM_SESSION_TYPE_NOTIFY ||
+                       param->session_type == MM_SESSION_TYPE_EMERGENCY) {
                        err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
-                       if(mm_sound_unregister_focus(param->focus_handle) || err) {
+                       if (mm_sound_unregister_focus(param->focus_handle) || err) {
                                debug_error("focus cleaning up failed[0x%x]", err);
                                return MM_ERROR_POLICY_INTERNAL;
                        }
@@ -402,8 +497,9 @@ cleanup:
        }
 #endif
 
+
 #ifdef DEBUG_DETAIL
-       debug_leave("\n");
+       debug_leave();
 #endif
 
        return err;
@@ -411,31 +507,28 @@ cleanup:
 
 int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
 {
-       int count = 0;
+       int plugin_id = 0;
        mmsound_codec_info_t info;
        mmsound_codec_param_t codec_param;
        int err = MM_ERROR_NONE;
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
-
-       for (count = 0; g_plugins[count].GetSupportTypes; count++) {
-               /* Find codec */
-               if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
-                       break;
+       plugin_id = _MMSoundMgrCodecFindCodecPluginID(MM_SOUND_SUPPORTED_CODEC_WAVE);
+       if (plugin_id == -1) {
+               debug_error("Could not find proper codec plugin!!!");
+               err = MM_ERROR_SOUND_INTERNAL;
+               goto cleanup;
        }
 
-       /*The count num means codec type WAV, MP3 */
-       debug_msg("Repeat[%d] Volume[%f] plugin_codec[%d]\n", 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;
+       err = g_plugins[plugin_id].Parse(param->pfilename, &info);
+       if (err != MM_ERROR_NONE) {
+               debug_error("Could not parse file [%s] by plugin[%d]\n", param->pfilename, plugin_id);
                goto cleanup;
        }
 
-       err = _MMSoundMgrCodecGetEmptySlot(slotid);
+       err = _mm_sound_mgr_codec_slot_get_empty(slotid);
        if (err != MM_ERROR_NONE || *slotid < 0) {
                debug_error("Empty g_slot is not found\n");
                goto cleanup;
@@ -444,31 +537,26 @@ int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param
        codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
        codec_param.repeat_count = param->repeat_count;
        codec_param.volume = param->volume;
-       codec_param.source = param->source;
+       codec_param.pfilename = param->pfilename;
        codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
        codec_param.param = *slotid;
        codec_param.pid = (int)param->param;
-       codec_param.codec_wave_mutex = &codec_wave_mutex;
        codec_param.stream_index = param->stream_index;
        MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
+       SLOT_LOCK();
 
        /* Codec id WAV or MP3 */
-       g_slots[*slotid].pluginid = count;
+       g_slots[*slotid].pluginid = plugin_id;
        g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
 
        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);
+       debug_msg("Created audio handle : [%p]\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");
+               SLOT_UNLOCK();
                goto cleanup;
        }
 
@@ -478,15 +566,14 @@ int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param
                g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
        }
 
-       pthread_mutex_unlock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex UNLOCK\n");
-#endif
+       SLOT_UNLOCK();
 
 cleanup:
+       if (_mm_sound_mgr_codec_slot_is_empty())
+               _mm_sound_mgr_codec_shutdown_timer_start();
 
 #ifdef DEBUG_DETAIL
-       debug_leave("\n");
+       debug_leave();
 #endif
 
        return err;
@@ -496,7 +583,7 @@ cleanup:
 #define DTMF_PLUGIN_COUNT 2
 int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
 {
-       int count = 0;
+       int plugin_id = 0;
        int *codec_type;
        mmsound_codec_info_t info;
        mmsound_codec_param_t codec_param;
@@ -506,22 +593,22 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
 #endif
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
 
-       for (count = 0; g_plugins[count].GetSupportTypes; count++) {
+       for (plugin_id = 0; g_plugins[plugin_id].GetSupportTypes; plugin_id++) {
                /* Find codec */
-               codec_type = g_plugins[count].GetSupportTypes();
-               if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
+               codec_type = g_plugins[plugin_id].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);
+       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, plugin_id);
 
-       if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
-               debug_error("unsupported file type %d\n", count);
-               printf("unsupported file type %d\n", count);
+       if (g_plugins[plugin_id].GetSupportTypes == NULL) {     /* Codec not found */
+               debug_error("unsupported file type %d\n", plugin_id);
+               printf("unsupported file type %d\n", plugin_id);
                err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
                goto cleanup;
        }
@@ -530,9 +617,8 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
        debug_msg("Get New handle\n");
 #endif
 
-       err = _MMSoundMgrCodecGetEmptySlot(slotid);
-       if(err != MM_ERROR_NONE || *slotid < 0)
-       {
+       err = _mm_sound_mgr_codec_slot_get_empty(slotid);
+       if (err != MM_ERROR_NONE || *slotid < 0) {
                debug_error("Empty g_slot is not found\n");
                goto cleanup;
        }
@@ -546,11 +632,7 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
        codec_param.pid = (int)param->param;
        codec_param.stream_index = param->stream_index;
        MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
-
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
+       SLOT_LOCK();
 
 #ifdef FOCUS_INTEGRATION
        //
@@ -566,28 +648,33 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
 
                unsigned int subs_id = 0;
 
-               err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG, (mm_sound_device_connected_cb)sound_codec_device_connected_callback, (void*) *slotid, &subs_id);
+               err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG,
+                                                                                                       (mm_sound_device_connected_cb)_sound_codec_device_connected_callback,
+                                                                                                       (void*) *slotid, &subs_id);
                if (err) {
                        debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
-                       pthread_mutex_unlock(&g_slot_mutex);
+                       SLOT_UNLOCK();
                        return MM_ERROR_POLICY_INTERNAL;
                }
                g_slots[*slotid].subs_id = subs_id;
 
-               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
+               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                       param->session_type == MM_SESSION_TYPE_ALARM ||
+                       param->session_type == MM_SESSION_TYPE_NOTIFY ||
+                       param->session_type == MM_SESSION_TYPE_EMERGENCY) {
                        debug_warning("session option is PAUSE_OTHERS -> acquire focus");
                        err = mm_sound_focus_get_id((int *)(&param->focus_handle));
-                       err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
+                       err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", _sound_codec_focus_callback, (void*)*slotid);
                        if (err) {
                                debug_error("mm_sound_register_focus failed [0x%x]", err);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                        err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
                        if (err) {
                                debug_error("mm_sound_acquire_focus failed [0x%x]", err);
                                err = mm_sound_unregister_focus(param->focus_handle);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                        g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
@@ -596,17 +683,18 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
                        debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
                } else {
                        debug_warning("need to set focus watch callback");
-                       err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, sound_codec_focus_watch_callback, (void*)*slotid, (int *)(&param->focus_wcb_id));
+                       err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, _sound_codec_focus_watch_callback,
+                                                                                                                               (void*)*slotid, (int *)(&param->focus_wcb_id));
                        if (err) {
                                debug_error("mm_sound_set_focus_watch_callback failed [0x%x]", err);
-                               pthread_mutex_unlock(&g_slot_mutex);
+                               SLOT_UNLOCK();
                                return MM_ERROR_POLICY_INTERNAL;
                        }
                }
        }
 #endif
 
-       g_slots[*slotid].pluginid = count;
+       g_slots[*slotid].pluginid = plugin_id;
        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;
@@ -626,8 +714,7 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
        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");
+               SLOT_UNLOCK();
 #ifdef FOCUS_INTEGRATION
                need_focus_unregister = 1;
 #endif
@@ -643,12 +730,8 @@ int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
 #endif
        }
 
-       pthread_mutex_unlock(&g_slot_mutex);
-
+       SLOT_UNLOCK();
        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:
 #ifdef FOCUS_INTEGRATION
@@ -659,9 +742,12 @@ cleanup:
                param->enable_session &&
                need_focus_unregister == 1) {
 
-               if (param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
+               if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                       param->session_type == MM_SESSION_TYPE_ALARM ||
+                       param->session_type == MM_SESSION_TYPE_NOTIFY ||
+                       param->session_type == MM_SESSION_TYPE_EMERGENCY) {
                        err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
-                       if(mm_sound_unregister_focus(param->focus_handle) || err) {
+                       if (mm_sound_unregister_focus(param->focus_handle) || err) {
                                debug_error("focus cleaning up failed[0x%x]", err);
                                return MM_ERROR_POLICY_INTERNAL;
                        }
@@ -676,7 +762,7 @@ cleanup:
 #endif
 
 #ifdef DEBUG_DETAIL
-       debug_leave("\n");
+       debug_leave();
 #endif
 
        return err;
@@ -684,29 +770,29 @@ cleanup:
 
 int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
 {
-       int count = 0;
+       int plugin_id = 0;
        int *codec_type;
        mmsound_codec_info_t info;
        mmsound_codec_param_t codec_param;
        int err = MM_ERROR_NONE;
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
 
-       for (count = 0; g_plugins[count].GetSupportTypes; count++) {
+       for (plugin_id = 0; g_plugins[plugin_id].GetSupportTypes; plugin_id++) {
                /* Find codec */
-               codec_type = g_plugins[count].GetSupportTypes();
-               if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
+               codec_type = g_plugins[plugin_id].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);
+       debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, plugin_id);
 
-       if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
-               debug_error("unsupported file type %d\n", count);
-               printf("unsupported file type %d\n", count);
+       if (g_plugins[plugin_id].GetSupportTypes == NULL) { /* Codec not found */
+               debug_error("unsupported file type %d\n", plugin_id);
+               printf("unsupported file type %d\n", plugin_id);
                err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
                goto cleanup;
        }
@@ -715,8 +801,8 @@ int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_p
        debug_msg("Get New handle\n");
 #endif
 
-       err = _MMSoundMgrCodecGetEmptySlot(slotid);
-       if(err != MM_ERROR_NONE || *slotid < 0)
+       err = _mm_sound_mgr_codec_slot_get_empty(slotid);
+       if (err != MM_ERROR_NONE || *slotid < 0)
        {
                debug_error("Empty g_slot is not found\n");
                goto cleanup;
@@ -731,48 +817,40 @@ int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_p
        codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
        codec_param.stream_index = param->stream_index;
        MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
+       SLOT_LOCK();
 
-       pthread_mutex_lock(&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
-               g_slots[*slotid].pluginid = count;
-               g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
-               g_slots[*slotid].enable_session = param->enable_session;
+       g_slots[*slotid].pluginid = plugin_id;
+       g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
+       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);
+       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");
-                       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);
-               }
+       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;
+               SLOT_UNLOCK();
+               goto cleanup;
+       }
 
-               pthread_mutex_unlock(&g_slot_mutex);
+       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);
+       }
 
-               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
+       SLOT_UNLOCK();
+       debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
 
-       cleanup:
+cleanup:
 #ifdef DEBUG_DETAIL
-               debug_leave("\n");
+       debug_leave();
 #endif
 
-               return err;
+       return err;
 
 }
 
@@ -786,10 +864,7 @@ int MMSoundMgrCodecStop(const int slotid)
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       pthread_mutex_lock (&g_slot_mutex);
-#ifdef DEBUG_DETAIL
-       debug_msg("After Slot_mutex LOCK\n");
-#endif
+       SLOT_LOCK();
        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);
@@ -799,16 +874,15 @@ int MMSoundMgrCodecStop(const int slotid)
        debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
 #endif
 
+       g_slots[slotid].stop_by_user = true;
+
        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
+       SLOT_UNLOCK();
        debug_leave("(err : 0x%08X)\n", err);
 
        return err;
@@ -821,22 +895,25 @@ int MMSoundMgrCodecClearFocus(int pid)
 
        debug_enter("(pid : [%d])\n", pid);
 
-       pthread_mutex_lock (&g_slot_mutex);
+       SLOT_LOCK();
 
        for (slotid = 0 ; slotid < MANAGER_HANDLE_MAX ; slotid++) {
                if (g_slots[slotid].pid == pid) {
                        if (g_slots[slotid].focus_handle || g_slots[slotid].focus_wcb_id) {
-                               if(g_slots[slotid].session_type != MM_SESSION_TYPE_CALL &&
+                               if (g_slots[slotid].session_type != MM_SESSION_TYPE_CALL &&
                                        g_slots[slotid].session_type != MM_SESSION_TYPE_VIDEOCALL &&
                                        g_slots[slotid].session_type != MM_SESSION_TYPE_VOIP &&
                                        g_slots[slotid].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
                                        g_slots[slotid].enable_session ) {
-                                       if ((g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || g_slots[slotid].session_type == MM_SESSION_TYPE_ALARM || g_slots[slotid].session_type == MM_SESSION_TYPE_NOTIFY || g_slots[slotid].session_type == MM_SESSION_TYPE_EMERGENCY) {
+                                       if ((g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                                               g_slots[slotid].session_type == MM_SESSION_TYPE_ALARM ||
+                                               g_slots[slotid].session_type == MM_SESSION_TYPE_NOTIFY ||
+                                               g_slots[slotid].session_type == MM_SESSION_TYPE_EMERGENCY) {
                                                err = mm_sound_release_focus(g_slots[slotid].focus_handle, FOCUS_FOR_BOTH, NULL);
                                                if (err) {
                                                        debug_error("mm_sound_release_focus failed [0x%x]", err);
                                                }
-                                               if(mm_sound_unregister_focus(g_slots[slotid].focus_handle) || err) {
+                                               if (mm_sound_unregister_focus(g_slots[slotid].focus_handle) || err) {
                                                        debug_error("Focus clean up failed [0x%x]", err);
                                                        err = MM_ERROR_POLICY_INTERNAL;
                                                        goto cleanup;
@@ -850,7 +927,7 @@ int MMSoundMgrCodecClearFocus(int pid)
                                                }
                                        }
                                }
-                               if(mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id) != MM_ERROR_NONE)
+                               if (mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id) != MM_ERROR_NONE)
                                        debug_error("mm_sound_remove_device_connected_callback() failed");
                                g_slots[slotid].focus_handle = 0;
                                g_slots[slotid].focus_wcb_id = 0;
@@ -860,7 +937,7 @@ int MMSoundMgrCodecClearFocus(int pid)
        }
 
 cleanup:
-       pthread_mutex_unlock(&g_slot_mutex);
+       SLOT_UNLOCK();
        debug_leave("(err : 0x%08X)\n", err);
 
        return err;
@@ -878,8 +955,9 @@ static int _MMSoundMgrCodecStopCallback(int param)
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       pthread_mutex_lock(&g_slot_mutex);
-       debug_msg("[CODEC MGR] Slot_mutex lock done\n");
+       if (g_slots[param].stop_by_user == false) {
+               SLOT_LOCK();
+       }
 
 #ifdef FOCUS_INTEGRATION
        /*
@@ -888,116 +966,83 @@ static int _MMSoundMgrCodecStopCallback(int param)
        debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session);
 
        if (g_slots[param].focus_handle || g_slots[param].focus_wcb_id) {
-               if(g_slots[param].session_type != MM_SESSION_TYPE_CALL &&
+               if (g_slots[param].session_type != MM_SESSION_TYPE_CALL &&
                        g_slots[param].session_type != MM_SESSION_TYPE_VIDEOCALL &&
                        g_slots[param].session_type != MM_SESSION_TYPE_VOIP &&
                        g_slots[param].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
                        g_slots[param].enable_session ) {
-                       if ((g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || g_slots[param].session_type == MM_SESSION_TYPE_ALARM || g_slots[param].session_type == MM_SESSION_TYPE_NOTIFY || g_slots[param].session_type == MM_SESSION_TYPE_EMERGENCY) {
-                               if(g_slots[param].current_focus_type != FOCUS_NONE) {
+                       if ((g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+                               g_slots[param].session_type == MM_SESSION_TYPE_ALARM ||
+                               g_slots[param].session_type == MM_SESSION_TYPE_NOTIFY ||
+                               g_slots[param].session_type == MM_SESSION_TYPE_EMERGENCY) {
+                               if (g_slots[param].current_focus_type != FOCUS_NONE) {
                                        err = mm_sound_release_focus(g_slots[param].focus_handle, g_slots[param].current_focus_type, NULL);
                                        if (err) {
                                                debug_error("mm_sound_release_focus failed [0x%x]", err);
                                        }
                                }
-                               if(mm_sound_unregister_focus(g_slots[param].focus_handle) || err) {
+                               if (mm_sound_unregister_focus(g_slots[param].focus_handle) || err) {
                                        debug_error("Focus clean up failed [0x%x]", err);
-                                       pthread_mutex_unlock(&g_slot_mutex);
-                                       return MM_ERROR_POLICY_INTERNAL;
+                                       err = MM_ERROR_POLICY_INTERNAL;
+                                       goto finish;
                                }
                        } else if (~(g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
                                err = mm_sound_unset_focus_watch_callback(g_slots[param].focus_wcb_id);
                                if (err) {
                                        debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
-                                       pthread_mutex_unlock(&g_slot_mutex);
-                                       return MM_ERROR_POLICY_INTERNAL;
+                                       err = MM_ERROR_POLICY_INTERNAL;
+                                       goto finish;
                                }
                        }
                }
-               if(mm_sound_remove_device_connected_callback(g_slots[param].subs_id) != MM_ERROR_NONE)
+               if (mm_sound_remove_device_connected_callback(g_slots[param].subs_id) != MM_ERROR_NONE)
                        debug_error("mm_sound_remove_device_connected_callback() failed");
        }
 #endif
 
-       __mm_sound_mgr_ipc_notify_play_file_end(param);
+       if (g_slots[param].stop_by_user == false) {
+               __mm_sound_mgr_ipc_notify_play_file_end(param);
+               debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
+       }
 
-       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 ) {
+       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 _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
+       _mm_sound_mgr_codec_slot_clear(param);
+       if (_mm_sound_mgr_codec_slot_is_empty())
+               _mm_sound_mgr_codec_shutdown_timer_start();
 
-       for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
-               if (g_slots[count].status == STATUS_IDLE) {
-                       g_slots[count].status = STATUS_SOUND;
-                       break;
-               }
+finish:
+       if (g_slots[param].stop_by_user == false) {
+               SLOT_UNLOCK();
        }
-       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
+       debug_fleave();
 
        return err;
 }
 
+
+
 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
 {
        int err = MM_ERROR_NONE;
-       int count = 0;
+       int plugin_id = 0;
        void *getinterface = NULL;
 
 #ifdef DEBUG_DETAIL
-       debug_enter("\n");
+       debug_enter();
 #endif
 
        /* find emptry slot */
-       for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) {
-               if (g_plugins[count].GetSupportTypes == NULL)
+       for (plugin_id = 0; plugin_id < MM_SOUND_SUPPORTED_CODEC_NUM; plugin_id++) {
+               if (g_plugins[plugin_id].GetSupportTypes == NULL)
                        break;
        }
 
-       if (count == MM_SOUND_SUPPORTED_CODEC_NUM) {
+       if (plugin_id == MM_SOUND_SUPPORTED_CODEC_NUM) {
                debug_critical("The plugin support type is not valid\n");
                return MM_ERROR_COMMON_OUT_OF_RANGE;
        }
@@ -1007,22 +1052,22 @@ static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
                debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err);
                goto cleanup;
        }
-       debug_msg("interface[%p] empty_slot[%d]\n", getinterface, count);
+       debug_msg("interface[%p] empty_slot[%d]\n", getinterface, plugin_id);
 
-       err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]);
+       err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[plugin_id]);
        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));
+               memset(&g_plugins[plugin_id], 0, sizeof(mmsound_codec_interface_t));
        } else {
-               if (g_plugins[count].SetThreadPool)
-                       g_plugins[count].SetThreadPool(MMSoundThreadPoolRun);
+               if (g_plugins[plugin_id].SetThreadPool)
+                       g_plugins[plugin_id].SetThreadPool(MMSoundThreadPoolRun);
        }
 
 #ifdef DEBUG_DETAIL
-       debug_leave("\n");
+       debug_leave();
 #endif
 
        return err;
index 89017fe..ec7ac6c 100644 (file)
@@ -49,25 +49,8 @@ int _MMSoundMgrIpcPlayFile(char* filename,int tone, int repeat, int volume, int
                           int *codechandle, char *stream_type, int stream_index)
 {
        mmsound_mgr_codec_param_t param = {0,};
-       MMSourceType *source = NULL;
        int ret = MM_ERROR_NONE;
 
-       /* Set source */
-       source = (MMSourceType*)malloc(sizeof(MMSourceType));
-       if (!source) {
-               debug_error("malloc fail!!\n");
-               return MM_ERROR_OUT_OF_MEMORY;
-       }
-
-       ret = mm_source_open_file(filename, source, MM_SOURCE_CHECK_DRM_CONTENTS);
-       if(ret != MM_ERROR_NONE) {
-               debug_error("Fail to open file\n");
-               if (source) {
-                       free(source);
-               }
-               return ret;
-       }
-
        /* Set sound player parameter */
        param.tone = tone;
        param.repeat_count = repeat;
@@ -76,7 +59,7 @@ int _MMSoundMgrIpcPlayFile(char* filename,int tone, int repeat, int volume, int
        param.session_type = session_type;
        param.session_options = session_options;
        param.param = (void*)client_pid;
-       param.source = source;
+       param.pfilename = filename;
        param.enable_session = enable_session;
        param.stream_index = stream_index;
        MMSOUND_STRNCPY(param.stream_type, stream_type, MM_SOUND_STREAM_TYPE_LEN);
@@ -91,11 +74,6 @@ int _MMSoundMgrIpcPlayFile(char* filename,int tone, int repeat, int volume, int
        ret = MMSoundMgrCodecPlay(codechandle, &param);
        if (ret != MM_ERROR_NONE) {
                debug_error("Will be closed a sources, codechandle : 0x%08X\n", *codechandle);
-               mm_source_close(source);
-               if (source) {
-                       free(source);
-                       source = NULL;
-               }
                return ret;
        }
 
@@ -132,45 +110,23 @@ int _MMSoundMgrIpcClearFocus(int pid)
 }
 #endif
 
-int _MMSoundMgrIpcPlayFileWithStreamInfo(charfilename, int repeat, int volume,
+int _MMSoundMgrIpcPlayFileWithStreamInfo(char *filename, int repeat, int volume,
                           int client_pid, int *codechandle, char *stream_type, int stream_index)
 {
        mmsound_mgr_codec_param_t param = {0,};
-       MMSourceType *source = NULL;
        int ret = MM_ERROR_NONE;
 
-       /* Set source */
-       source = (MMSourceType*)malloc(sizeof(MMSourceType));
-       if (!source) {
-               debug_error("malloc fail!!\n");
-               return MM_ERROR_OUT_OF_MEMORY;
-       }
-
-       ret = mm_source_open_file(filename, source, MM_SOURCE_CHECK_DRM_CONTENTS);
-       if(ret != MM_ERROR_NONE) {
-               debug_error("Fail to open file\n");
-               if (source) {
-                       free(source);
-               }
-               return ret;
-       }
-
        /* Set sound player parameter */
        param.repeat_count = repeat;
        param.volume = volume;
        param.param = (void*)client_pid;
-       param.source = source;
+       param.pfilename = filename;
        param.stream_index = stream_index;
        MMSOUND_STRNCPY(param.stream_type, stream_type, MM_SOUND_STREAM_TYPE_LEN);
 
        ret = MMSoundMgrCodecPlayWithStreamInfo(codechandle, &param);
        if (ret != MM_ERROR_NONE) {
                debug_error("Will be closed a sources, codechandle : 0x%08X\n", *codechandle);
-               mm_source_close(source);
-               if (source) {
-                       free(source);
-                       source = NULL;
-               }
                return ret;
        }
 
index 145e85e..7bf2242 100644 (file)
@@ -226,14 +226,14 @@ static int _get_sender_pid(GDBusMethodInvocation* invocation)
        connection = g_dbus_method_invocation_get_connection(invocation);
        sender = g_dbus_method_invocation_get_sender(invocation);
 
-       debug_error("connection = %p, sender = %s", connection, sender);
+       debug_log("connection = %p, sender = %s", connection, sender);
 
        value = g_dbus_connection_call_sync(connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
                                                                                "org.freedesktop.DBus", "GetConnectionUnixProcessID",
                                                                                g_variant_new("(s)", sender, NULL), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
        if (value) {
                g_variant_get(value, "(u)", &pid);
-               debug_msg("Sender PID = [%d]", pid);
+               debug_log("Sender PID = [%d]", pid);
                g_variant_unref(value);
        } else {
                debug_error("err code = %d, err msg = %s", err->code, err->message);
index 8b15095..615d399 100644 (file)
@@ -29,6 +29,8 @@
 #include <mm_error.h>
 #include <mm_debug.h>
 
+#include <glib.h>
+
 #include "../include/mm_sound_common.h"
 #include "include/mm_sound_thread_pool.h"
 #include "include/mm_sound_mgr_run.h"
@@ -40,7 +42,6 @@
 #define PLUGIN_ENV "MM_SOUND_PLUGIN_PATH"
 #define PLUGIN_MAX 30
 #define MAX_PLUGIN_DIR_PATH_LEN        256
-#define SHUTDOWN_TIMEOUT_SEC 10
 
 #define USE_SYSTEM_SERVER_PROCESS_MONITORING
 
@@ -63,16 +64,12 @@ static void _exit_handler(int sig);
 
 GMainLoop *g_mainloop;
 
-static gboolean _shutdown_timer_cb(gpointer user_data)
+static gboolean _shutdown_cb(gpointer user_data)
 {
-       if (!IsMMSoundThreadPoolRunning()) {
-               debug_warning("Thread pool is not running..quit mainloop now!");
-               g_main_loop_quit(g_mainloop);
-               return FALSE;
-       }
+       debug_warning("TIMER : quit mainloop now!");
+       g_main_loop_quit(g_mainloop);
 
-       debug_warning("still running......keep timer...");
-       return TRUE;
+       return FALSE;
 }
 
 static void _mainloop_run()
@@ -80,10 +77,9 @@ static void _mainloop_run()
        g_mainloop = g_main_loop_new(NULL, TRUE);
        if (g_mainloop == NULL) {
                debug_error("g_main_loop_new() failed\n");
+               return;
        }
 
-       g_timeout_add_seconds(SHUTDOWN_TIMEOUT_SEC, _shutdown_timer_cb, NULL);
-
        g_main_loop_run(g_mainloop);
 }
 
@@ -217,9 +213,9 @@ int main(int argc, char **argv)
                if ((pid = fork()) < 0) {
                        fprintf(stderr, "Sub Fork Error\n");
                        return 2;
-               } else if(pid == 0) {
+               } else if (pid == 0) {
                        break;
-               } else if(pid > 0) {
+               } else if (pid > 0) {
                        wait(&ret);
                        fprintf(stderr, "Killed by signal [%05X]\n", ret);
                        fprintf(stderr, "Daemon is run againg\n");
@@ -235,7 +231,7 @@ int main(int argc, char **argv)
                MMSoundMgrDbusInit();
                MMSoundThreadPoolInit();
                MMSoundMgrRunInit(serveropt.plugdir);
-               MMSoundMgrCodecInit(serveropt.plugdir);
+               MMSoundMgrCodecInit(serveropt.plugdir, _shutdown_cb);
        }
 
        debug_warning("sound_server [%d] initialization complete...now, start running!!\n", getpid());
index 5b5df31..7434a2c 100644 (file)
 #include <mm_debug.h>
 #include <mm_sound_thread_pool.h>
 
-#define USE_G_THREAD_POOL
-#ifdef USE_G_THREAD_POOL
 #include <glib.h>
-GThreadPool* g_pool;
 
-#define MAX_UNUSED_THREADS_IN_THREADPOOL       10
+GThreadPool *g_pool;
 
-#define MIN_RUNNING_THREAD 0
+#define MAX_UNUSED_THREADS_IN_THREADPOOL       10
 
 typedef struct __THREAD_INFO
 {
@@ -42,68 +39,62 @@ typedef struct __THREAD_INFO
        void *param;
 } THREAD_INFO;
 
-static void __DummyWork (void* param)
+static void __DummyWork(void *param)
 {
-       debug_msg ("thread index = %d\n", (int)param);
-       sleep (1);
+       debug_msg("thread index = %d\n", (int)param);
+       sleep(1);
 }
 
 static void __ThreadWork(gpointer data, gpointer user_data)
 {
-       THREAD_INFO* info = (THREAD_INFO*)data;
+       THREAD_INFO *info = (THREAD_INFO *)data;
        if (info) {
-                if (info->func) {
-                               debug_log ("Calling [%p] with param [%p]\n", info->func, info->param);
-                               info->func (info->param);
-                } else {
-                               debug_warning ("No func to call....\n");
-                }
+               if (info->func) {
+                       debug_log("Calling [%p] with param [%p]\n", info->func, info->param);
+                       info->func(info->param);
+               } else {
+                       debug_warning("No func to call....\n");
+               }
 
-                /* Info was allocated by MMSoundThreadPoolRun().
+               /* Info was allocated by MMSoundThreadPoolRun().
                        The actual content of info should be  freed whether inside func or outside (if handle) */
-                debug_log ("free [%p]\n", info);
-                free (info);
-                info = NULL;
+               debug_log ("free [%p]\n", info);
+               free(info);
+               info = NULL;
        } else {
-               debug_warning ("No valid thread info...Nothing to do...\n");
+               debug_warning("No valid thread info...Nothing to do...\n");
        }
 }
 
 int MMSoundThreadPoolDump(int fulldump)
 {
        if (g_pool == NULL) {
-               debug_error ("No thread pool initialized....\n");
+               debug_error("No thread pool initialized....\n");
                return MM_ERROR_SOUND_INTERNAL;
        }
 
        if (fulldump) {
-               debug_log ("##### [ThreadPool] max threads=[%d], max unused=[%d], max idle time=[%d]\n",
+               debug_log("##### [ThreadPool] max threads=[%d], max unused=[%d], max idle time=[%d]\n",
                                g_thread_pool_get_max_threads (g_pool),
                                g_thread_pool_get_max_unused_threads(),
-                               g_thread_pool_get_max_idle_time()       );
+                               g_thread_pool_get_max_idle_time());
        }
-       debug_log ("***** [ThreadPool] running=[%d], unused=[%d]\n",
+       debug_log("***** [ThreadPool] running=[%d], unused=[%d]\n",
                        g_thread_pool_get_num_threads (g_pool),
-                       g_thread_pool_get_num_unused_threads() );
+                       g_thread_pool_get_num_unused_threads());
 
        return MM_ERROR_NONE;
 }
 
-gboolean IsMMSoundThreadPoolRunning(void)
-{
-       MMSoundThreadPoolDump(FALSE);
-       return (g_thread_pool_get_num_threads(g_pool) > MIN_RUNNING_THREAD);
-}
-
 int MMSoundThreadPoolInit()
 {
        int i=0;
-       GErrorerror = NULL;
+       GError *error = NULL;
 
        /* Create thread pool (non-exclude mode with infinite max threads) */
-       g_pool = g_thread_pool_new (__ThreadWork, NULL, -1, FALSE, &error);
+       g_pool = g_thread_pool_new(__ThreadWork, NULL, -1, FALSE, &error);
        if (g_pool == NULL && error != NULL) {
-               debug_error ("thread pool created failed : %s\n", error->message);
+               debug_error("thread pool created failed : %s\n", error->message);
                g_error_free (error);
                return MM_ERROR_SOUND_INTERNAL;
        }
@@ -114,40 +105,40 @@ int MMSoundThreadPoolInit()
        /* Thread pool setting : this will maintain at least 10 unused threads and this will be reused. */
        /* If no unused thread left, new thread will be created, but always maintain 10 unused thread */
        debug_msg ("thread pool set max unused threads to %d\n", MAX_UNUSED_THREADS_IN_THREADPOOL);
-       g_thread_pool_set_max_unused_threads (MAX_UNUSED_THREADS_IN_THREADPOOL);
+       g_thread_pool_set_max_unused_threads(MAX_UNUSED_THREADS_IN_THREADPOOL);
 
-       /* To reserve unused threads, let's start some threads for beggining
-          This dummy thread will be remained unused as soon as it started */
-       debug_msg ("run threads to reserve minimum thread\n");
-       for (i=0; i<MAX_UNUSED_THREADS_IN_THREADPOOL; i++) {
-               MMSoundThreadPoolRun ((void *)i, __DummyWork);
+       /* To reserve unused threads, let's start some threads for beginning
+               his dummy thread will be remained unused as soon as it started */
+       debug_msg("run threads to reserve minimum thread\n");
+       for (i = 0; i < MAX_UNUSED_THREADS_IN_THREADPOOL; i++) {
+               MMSoundThreadPoolRun((void *)i, __DummyWork);
        }
 
        MMSoundThreadPoolDump(TRUE);
 
-     return MM_ERROR_NONE;
+       return MM_ERROR_NONE;
 }
 
 int MMSoundThreadPoolRun(void *param, void (*func)(void*))
 {
-       GErrorerror = NULL;
+       GError *error = NULL;
 
        /* Dump current thread pool */
        MMSoundThreadPoolDump(FALSE);
 
        /* Create thread info structure.
           This thread info data will be free in __ThreadWork(), after use. */
-       THREAD_INFO* thread_info = (THREAD_INFO*)malloc (sizeof(THREAD_INFO));
+       THREAD_INFO *thread_info = (THREAD_INFO *)malloc(sizeof(THREAD_INFO));
        if (thread_info) {
                thread_info->func = func;
                thread_info->param = param;
-               debug_log ("alloc thread_info = %p\n", thread_info);
+               debug_log("alloc thread_info = %p\n", thread_info);
 
                /* Add thread to queue of thread pool */
-               g_thread_pool_push (g_pool, thread_info, &error);
+               g_thread_pool_push(g_pool, thread_info, &error);
                if (error) {
-                       debug_error ("g_thread_pool_push failed : %s\n", error->message);
-                       g_error_free (error);
+                       debug_error("g_thread_pool_push failed : %s\n", error->message);
+                       g_error_free(error);
                        free(thread_info);
                        return MM_ERROR_SOUND_INTERNAL;
                }
@@ -168,200 +159,9 @@ int MMSoundThreadPoolFini(void)
 
        If wait_ is TRUE, the functions does not return before all tasks to be processed
        (dependent on immediate, whether all or only the currently running) are ready.
-       Otherwise the function returns immediately.     */
-       debug_msg ("thread pool will be free\n");
-       g_thread_pool_free (g_pool, TRUE, FALSE);
+       Otherwise the function returns immediately. */
+       debug_msg("thread pool will be free\n");
+       g_thread_pool_free(g_pool, TRUE, FALSE);
 
        return MM_ERROR_NONE;
 }
-
-#else // USE_G_THREAD_POOL
-
-#define THREAD_POOL_MAX 10
-
-struct __control_t
-{
-       pthread_t threadid;
-       pthread_cond_t condition;
-       int stopflag;
-       void *param;
-       void (*func)(void *);
-};
-
-static int threadmap[THREAD_POOL_MAX];
-static struct __control_t control[THREAD_POOL_MAX];
-
-static pthread_cond_t startcond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t startsync = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t controlsync = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t funcsync = PTHREAD_MUTEX_INITIALIZER;
-
-static int __GetEmptyPool(void)
-{
-       int count = 0;
-       while ((count < THREAD_POOL_MAX) && threadmap[count] == 1)
-               ++count;
-       return count == THREAD_POOL_MAX ? -1 : count;
-}
-
-static void __SetPool(int n)
-{
-    threadmap[n] = 1;
-}
-
-static void __ResetPool(int n)
-{
-    threadmap[n] = 0;
-}
-
-static void __InitPool(void)
-{
-    int count = 0;
-    for (count = 0; count < THREAD_POOL_MAX; count++)
-    {
-        threadmap[count] = 0;
-        if (pthread_cond_init(&control[count].condition, NULL) != 0)
-            perror("Make Thread Condition");
-    }
-}
-
-static void __DestroyPool(void)
-{
-    int count = 0;
-    for (count = 0; count < THREAD_POOL_MAX; count++)
-    {
-        if (pthread_cond_destroy(&control[count].condition) != 0)
-        {
-            perror("Remove Thread Condition");
-            exit(0);
-        }
-    }
-}
-
-static void* __ThreadWork(void *param)
-{
-    int myid = -1;
-
-    myid = (int)param;
-
-    pthread_mutex_lock(&startsync);
-    pthread_cond_signal(&startcond);
-    pthread_mutex_unlock(&startsync);
-
-    while(1)
-    {
-        pthread_mutex_lock(&controlsync);
-        pthread_cond_wait(&control[myid].condition, &controlsync);
-        pthread_mutex_unlock(&controlsync);
-
-        if (control[myid].func != NULL)
-            control[myid].func(control[myid].param);
-/*        if (control[myid].param != NULL)
-            free(control[myid].param);*/
-
-        control[myid].func = NULL;
-        control[myid].param = NULL;
-        pthread_mutex_lock(&startsync);
-        __ResetPool(myid);
-        pthread_mutex_unlock(&startsync);
-
-        if (control[myid].stopflag) {
-            pthread_exit(0);
-        }
-    }
-}
-
-int MMSoundThreadPoolDump(void)
-{
-       int count = 0;
-       int ret = MM_ERROR_NONE;
-
-       fprintf(stdout, "================================================================================\n");
-       fprintf(stdout, "                              Thread States                                     \n");
-       fprintf(stdout, "--------------------------------------------------------------------------------\n");
-       for (count = 0; count < THREAD_POOL_MAX; count ++)
-       {
-               fprintf(stdout, "Thread %d\n", control[count].threadid);
-               fprintf(stdout, "Current State is \"%s\"\n", threadmap[count] ? "Running" : "Ready");
-               if (threadmap[count])
-               {
-                       fprintf(stdout, "Running function address %p\n", control[count].func);
-               }
-               else
-               {
-                       fprintf(stdout, "Threadmap is NULL\n");
-                       ret = MM_ERROR_SOUND_INTERNAL;
-               }
-       }
-       fprintf(stdout, "================================================================================\n");
-       return ret;
-}
-
-int MMSoundThreadPoolInit(void)
-{
-    volatile int count = 0;
-    pthread_mutex_lock(&funcsync);
-
-    __InitPool();
-
-    for (count = 0; count < THREAD_POOL_MAX; count++)
-    {
-        control[count].stopflag = 0;
-        pthread_mutex_lock(&startsync);
-        if (pthread_create(&control[count].threadid, NULL, __ThreadWork, (void*)count) < 0)
-        {
-            perror("Make Thread Fail");
-            exit(0);
-        }
-        pthread_cond_wait(&startcond, &startsync);
-        pthread_mutex_unlock(&startsync);
-        usleep(100); /* Delay for thread init */
-    }
-    pthread_mutex_unlock(&funcsync);
-    return MM_ERROR_NONE;
-}
-
-int MMSoundThreadPoolRun(void *param, void (*func)(void*))
-{
-    int poolnum = -1;
-
-    pthread_mutex_lock(&funcsync);
-    pthread_mutex_lock(&startsync);
-    poolnum = __GetEmptyPool();
-    if (poolnum < 0) {
-        pthread_mutex_unlock(&startsync);
-        pthread_mutex_unlock(&funcsync);
-        return MM_ERROR_COMMON_NO_FREE_SPACE;
-    }
-    __SetPool(poolnum);
-    pthread_mutex_unlock(&startsync);
-    control[poolnum].param = param;
-    control[poolnum].func = func;
-    pthread_cond_signal(&control[poolnum].condition);
-    pthread_mutex_unlock(&funcsync);
-
-    return MM_ERROR_NONE;
-}
-
-int MMSoundThreadPoolFini(void)
-{
-    int count = 0;
-
-    pthread_mutex_lock(&funcsync);
-    for (count = 0; count < THREAD_POOL_MAX; count++)
-    {
-        control[count].stopflag = 1;
-        pthread_cond_signal(&control[count].condition);
-        if (pthread_join(control[count].threadid, NULL) < 0)
-        {
-            perror("Join Fail");
-            exit(0);
-        }
-    }
-    __DestroyPool();
-    pthread_mutex_unlock(&funcsync);
-
-    return MM_ERROR_NONE;
-}
-#endif // USE_G_THREAD_POOL
-
index f6a7133..f8bb216 100644 (file)
@@ -1,6 +1 @@
-if OGG_SUPPORT
-SUBDIRS = wav tone ogg
-else
 SUBDIRS = wav tone
-endif
-
diff --git a/server/plugin/ogg/Makefile.am b/server/plugin/ogg/Makefile.am
deleted file mode 100644 (file)
index f478fac..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-lib_LTLIBRARIES = libsoundplugintremoloogg.la
-
-libsoundplugintremoloogg_la_SOURCES = \
-                                mm_sound_plugin_codec_ogg.c
-
-libsoundplugintremoloogg_la_CFLAGS  = \
-                               $(MMCOMMON_CFLAGS) \
-                               $(TREMOLO_CFLAGS) \
-                               -I$(srcdir)/ \
-                               -I$(srcdir)/../../include \
-                               -I$(srcdir)/../../../include \
-                               $(PA_CFLAGS) \
-                               $(MMLOGSVR_CFLAGS) -DMMF_LOG_OWNER=0x002 -DMMF_DEBUG_PREFIX=\"MMF-SOUND\"
-
-libsoundplugintremoloogg_la_LIBADD = $(MMCOMMON_LIBS) \
-                               $(MMLOGSVR_LIBS) \
-                               $(TREMOLO_LIBS) \
-                               $(PA_LIBS) \
-                               $(srcdir)/../../../libmmfsound.la \
-                               $(srcdir)/../../../common/libmmfsoundcommon.la
-
-install-exec-hook:
-       mkdir -p $(DESTDIR)$(libdir)/soundplugins
-       ln -sf ../libsoundplugintremoloogg.so $(DESTDIR)$(libdir)/soundplugins/libsoundplugintremoloogg.so
diff --git a/server/plugin/ogg/mm_sound_plugin_codec_ogg.c b/server/plugin/ogg/mm_sound_plugin_codec_ogg.c
deleted file mode 100644 (file)
index 805c7a6..0000000
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <semaphore.h>
-#include <pthread.h>
-
-#include <mm_error.h>
-#include <mm_debug.h>
-#include <tremolo_vorbisdec_api.h>
-
-#include "../../include/mm_sound.h"
-#include "../../include/mm_sound_plugin_codec.h"
-#include "../../../include/mm_sound_pa_client.h"
-
-#define OGG_DEC_BUF_SIZE 4096
-#define OGG_FILE_SAMPLE_PLAY_DURATION 290
-
-#define TIME_MSEC (1000)
-#define SILENT_SND_MIN_VALUE (90)
-#define CODEC_OGG_LOCK(LOCK) do { pthread_mutex_lock(LOCK); } while (0)
-#define CODEC_OGG_UNLOCK(LOCK) do { pthread_mutex_unlock(LOCK); } while (0)
-
-int MMSoundPlugCodecOggStop(MMHandleType handle);
-
-enum {
-   STATE_NONE = 0,
-   STATE_READY,
-   STATE_BEGIN,
-   STATE_PLAY,
-   STATE_ENDOFDECORD,
-   STATE_STOP,
-};
-
-typedef struct {
-       /* thread controls */
-       sem_t                   start_wave_signal; /* control start of pcm write thread */
-       sem_t                   start_ogg_signal; /* control start of ogg decord thread*/
-       pthread_mutex_t         mutex;
-
-     /* Codec infomations */
-       void                    *decoder;
-       char* pcm_out_buf;
-       int                     offset;
-       int     period;
-       int gain, out, in, option;
-       mm_sound_device_in device_in;
-       mm_sound_device_out device_out;
-       unsigned int volume_value;
-
-     /* Audio Infomations */
-       int                             transper_size; /* audio open return */
-       int                             handle;
-
-     /* control Informations */
-       int                             repeat_count;
-       int                             (*stop_cb)(int);
-       int                             cb_param;
-       int                             state;
-       MMSourceType         *source;
-       int codec;
-       int NumberOfChannels;
-       int SamplingFrequency;
-       int format;
-       int Duration;
-       int BitRate;
-       int BufferSize;
-} ogg_info_t;
-
-static int (*g_thread_pool_func)(void*, void (*)(void*)) = NULL;
-
-static void _reset_ogg_decoder(ogg_info_t *p)
-{
-       int err, used_size, skipsize;
-       OGG_DEC_INFO ogg_info;
-
-       err = OGGDEC_ResetDecode(p->decoder);
-       if (err != OGGDEC_SUCCESS) {
-               debug_error("Failed to RESET decoder!");
-               return;
-       }
-
-       err = OGGDEC_InitDecode(p->decoder, (unsigned char*)p->source->ptr, p->BufferSize, &skipsize);
-       if (err != OGGDEC_SUCCESS) {
-               debug_error("Failed to INIT decoder!");
-               return;
-       }
-
-       err = OGGDEC_InfoDecode(p->decoder, p->source->ptr + skipsize, &used_size, &ogg_info);
-       if (err != OGGDEC_SUCCESS) {
-               debug_error("Failed to INFO decoder!");
-               return;
-       }
-}
-
-void _pcm_out_func(void *data)
-{
-       ogg_info_t *p = (ogg_info_t *)data;
-       int used_size = 0;
-       int decoded_len = 0;
-       unsigned char* ogg_buf = NULL;
-       int err = 0;
-
-       debug_enter();
-
-       if (!p) {
-               debug_error("Invalid ogg_info_t...");
-               return;
-       }
-
-       sem_wait(&p->start_wave_signal);
-
-       while (((p->repeat_count == -1) ? (1) : (p->repeat_count--)) && p->state == STATE_PLAY) {
-               ogg_buf = MMSourceGetPtr(p->source) + p->offset;
-
-               while (p->state == STATE_PLAY) {
-                       decoded_len = 0;
-                       err = OGGDEC_FrameDecode(p->decoder, ogg_buf, &used_size, p->pcm_out_buf, &decoded_len);
-                       if (decoded_len <= 0) {
-                               debug_error("decoded len = %d", decoded_len);
-                               break;
-                       }
-
-                       mm_sound_pa_write(p->handle, p->pcm_out_buf, decoded_len);
-                       ogg_buf += used_size;
-
-                       if (err != OGGDEC_SUCCESS)
-                               break;
-               }
-
-               debug_error("decode done = [%d], repeat_count = [%d]", err, p->repeat_count);
-               if (err == OGGDEC_FAIL || p->repeat_count == 0)
-                       MMSoundPlugCodecOggStop((MMHandleType)p);
-               else
-                       _reset_ogg_decoder(p);
-       }
-
-       mm_sound_pa_drain(p->handle);
-       mm_sound_pa_close(p->handle);
-
-       /* Notice */
-       /* OggDestory is called by stop_cb func */
-       /* INDEED the stop_cb must be called, after end of all progress */
-       if (p->stop_cb)
-               p->stop_cb(p->cb_param);
-
-       debug_leave();
-}
-
-int MMSoundPlugCodecOggSetThreadPool(int (*func)(void*, void (*)(void*)))
-{
-       debug_enter("(func : %p)\n", func);
-       g_thread_pool_func = func;
-       debug_leave("\n");
-       return MM_ERROR_NONE;
-}
-
-int* MMSoundPlugCodecOggGetSupportTypes(void)
-{
-       debug_enter("\n");
-       static int suported[2] = {MM_SOUND_SUPPORTED_CODEC_OGG, 0};
-       debug_leave("\n");
-       return suported;
-}
-
-int MMSoundPlugCodecOggParse(MMSourceType *source, mmsound_codec_info_t *info)
-{
-       unsigned char *ptr = NULL;
-       unsigned int size = 0;
-       int err;
-       OGG_DEC_INFO ogg_info;
-
-       debug_enter("\n");
-
-       ptr = (unsigned char*)MMSourceGetPtr(source);
-       size = MMSourceGetCurSize(source);
-       debug_msg("[CODEC OGG] source ptr :[0x%08X] ::: source size :[0x%d]\n", ptr, size);
-
-       err = OGGDEC_PreparseDecode(ptr, size, &ogg_info);
-       if (err != OGGDEC_SUCCESS) {
-               debug_error("Not valid Ogg data format");
-               return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
-       }
-
-       info->format = 16;
-       info->channels = ogg_info.channels;
-       info->samplerate = ogg_info.samplerate;
-       info->duration = ogg_info.duration;
-       info->codec = MM_AUDIO_CODEC_OGG;
-       debug_msg("[CODEC OGG]Channels %d  Samplerate %d\n", ogg_info.channels, ogg_info.samplerate);
-       debug_leave("\n");
-
-       return MM_ERROR_NONE;
-}
-
-int MMSoundPlugCodecOggCreate(mmsound_codec_param_t *param, mmsound_codec_info_t *info, MMHandleType *handle)
-{
-       ogg_info_t* p = NULL;
-       MMSourceType *source = NULL;
-       OGG_DEC_INFO ogg_info;
-       int err, used_size, skipsize;
-       int ret = MM_ERROR_NONE;
-
-       pa_sample_spec ss;
-       int size = 0;
-       int mode = HANDLE_MODE_OUTPUT_LOW_LATENCY;
-
-       debug_enter("\n");
-
-       if (g_thread_pool_func == NULL) {
-               debug_error("Need thread pool!\n");
-               return MM_ERROR_SOUND_INTERNAL;
-       }
-
-       source = param->source;
-       debug_msg("[CODEC OGG]Param source p 0x08%X\n", param->source);
-
-       p = (ogg_info_t *) malloc(sizeof(ogg_info_t));
-       if (p == NULL) {
-               debug_error("[CODEC OGG]Memory allocation Fail\n");
-               return MM_ERROR_OUT_OF_MEMORY;
-       }
-
-       memset(p, 0, sizeof(ogg_info_t));
-       p->source = param->source;
-       p->BufferSize = MMSourceGetCurSize(source);
-
-       pthread_mutex_init(&p->mutex, NULL);
-
-       err = sem_init(&p->start_ogg_signal, 0, 0);
-       if (err == -1) {
-               debug_error("[CODEC OGG]Semaphore init fail\n");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto error_before_create;
-       }
-
-       err = sem_init(&p->start_wave_signal, 0, 0);
-       if (err == -1) {
-               debug_error("[CODEC OGG]Semaphore init fail\n");
-               sem_destroy(&p->start_ogg_signal);
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto error_before_create;
-       }
-
-       err = OGGDEC_CreateDecode(&p->decoder);
-       if (err != OGGDEC_SUCCESS) {
-               debug_error("[CODEC OGG]Fail to Create ogg decoder\n");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto error_before_create;
-       }
-       p->pcm_out_buf = (char *)malloc(sizeof(char)*OGG_DEC_BUF_SIZE);
-       if (p->pcm_out_buf == NULL) {
-               debug_error("[CODEC OGG]Memory allocation fail\n");
-               ret = MM_ERROR_SOUND_NO_FREE_SPACE;
-               goto error_after_create;
-       }
-       err = OGGDEC_InitDecode(p->decoder, (unsigned char*)p->source->ptr, p->BufferSize, &skipsize);
-       if (err != OGGDEC_SUCCESS) {
-               debug_error("Fail to init ogg decoder\n");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto error_after_buffer;
-       }
-       p->offset = skipsize;
-
-       err = OGGDEC_InfoDecode(p->decoder, p->source->ptr+p->offset, &used_size, &ogg_info);
-       if (err != OGGDEC_SUCCESS) {
-               debug_error("[CODEC OGG]Fail to get ogg info\n");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto error_after_buffer;
-       }
-       p->offset += used_size;
-       p->Duration = info->duration;
-       p->format = info->format = 16;
-       info->channels = ogg_info.channels;
-       info->samplerate = ogg_info.samplerate;
-
-       /* Temporal code for debug */
-       /*
-       debug_msg("([CODEC OGG]handle %x)\n", p);
-       debug_msg("[CODEC OGG]Type %s\n", info->codec == MM_AUDIO_CODEC_OGG ? "OGG" : "Unknown");
-       debug_msg("[CODEC OGG]channels   : %d\n", info->channels);
-       debug_msg("[CODEC OGG]format     : %d\n", info->format);
-       debug_msg("[CODEC OGG]samplerate : %d\n", info->samplerate);
-       debug_msg("[CODEC OGG]doffset    : %d\n", info->doffset);
-       debug_msg("[CODEC OGG]repeat : %d\n", param->repeat_count);
-       debug_msg("[CODEC OGG]volume : %d\n", param->volume);
-       debug_msg("[CODEC OGG]callback : %08x\n", param->stop_cb);
-       */
-       debug_msg("Audio duration [%d]", info->duration);
-       p->repeat_count = param ->repeat_count;
-       p->stop_cb = param->stop_cb;
-       p->cb_param = param->param;
-
-       if(info->duration < OGG_FILE_SAMPLE_PLAY_DURATION) {
-               mode = HANDLE_MODE_OUTPUT_LOW_LATENCY;
-       } else {
-               mode = HANDLE_MODE_OUTPUT;
-       }
-
-       switch(info->format)
-       {
-       case 8:
-               ss.format = PA_SAMPLE_U8;
-               break;
-       case 16:
-               ss.format =  PA_SAMPLE_S16LE;
-               break;
-       default:
-               ss.format =  PA_SAMPLE_S16LE;
-               break;
-       }
-       ss.channels = info->channels;
-       ss.rate = info->samplerate;
-
-       debug_msg("[CODEC OGG] PARAM mode:[%d] channels:[%d] samplerate:[%d] format:[%d] volume type:[%x]\n",
-               mode, ss.channels, ss.rate, ss.format, param->volume_config);
-
-       p->handle = mm_sound_pa_open(HANDLE_MODE_OUTPUT_LOW_LATENCY, param->volume_config, &ss, NULL, &size, param->stream_type, param->stream_index);
-       if(!p->handle) {
-               debug_error("[CODEC OGG] Can not open audio handle\n");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto error_after_buffer;
-       }
-
-       pthread_mutex_lock(&p->mutex);
-       p->state = STATE_READY;
-       pthread_mutex_unlock(&p->mutex);
-       *handle = p;
-
-       err = g_thread_pool_func(p, _pcm_out_func);
-       if (err) {
-               debug_error("[CODEC OGG]pthread_create() fail in pcm thread\n");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto error_after_buffer;
-       }
-
-       debug_leave("\n");
-       return MM_ERROR_NONE;
-
-error_after_buffer:
-       free(p->pcm_out_buf);
-
-error_after_create:
-       sem_destroy(&p->start_ogg_signal);
-       sem_destroy(&p->start_wave_signal);
-       OGGDEC_ResetDecode(p->decoder);
-       OGGDEC_DeleteDecode(p->decoder);
-
-error_before_create:
-       free(p);
-       return ret;
-}
-
-int MMSoundPlugCodecOggPlay(MMHandleType handle)
-{
-       ogg_info_t *p = (ogg_info_t *) handle;
-       debug_enter("(handle %x)\n", handle);
-
-       if (p->BufferSize <= 0) {
-           debug_error("[CODEC OGG]End of file\n");
-           return MM_ERROR_END_OF_FILE;
-       }
-       pthread_mutex_lock(&p->mutex);
-       p->state = STATE_PLAY;
-       pthread_mutex_unlock(&p->mutex);
-       sem_post(&p->start_wave_signal);
-
-       debug_leave("\n");
-       return MM_ERROR_NONE;
-}
-
-int MMSoundPlugCodecOggStop(MMHandleType handle)
-{
-       ogg_info_t *p = (ogg_info_t *) handle;
-       debug_enter("(handle %x)\n", handle);
-       pthread_mutex_lock(&p->mutex);
-       p->state = STATE_STOP;
-       pthread_mutex_unlock(&p->mutex);
-       debug_leave("\n");
-
-       return MM_ERROR_NONE;
-}
-
-int MMSoundPlugCodecOggDestroy(MMHandleType handle)
-{
-       ogg_info_t *p = (ogg_info_t*) handle;
-       int err;
-
-       debug_enter("(handle %x)\n", handle);
-
-       if (!p) {
-               debug_critical("Confirm the hadle (is NULL)\n");
-               err = MM_ERROR_SOUND_INTERNAL;
-               return err;
-       }
-
-       if(p->source) {
-               mm_source_close(p->source);
-               free(p->source); p->source = NULL;
-       }
-
-       err = OGGDEC_ResetDecode(p->decoder);
-       if (err != OGGDEC_SUCCESS) {
-               debug_error("[CODEC OGG]Codec Reset fail\n");
-               err = MM_ERROR_SOUND_INTERNAL;
-       }
-
-       err = OGGDEC_DeleteDecode(p->decoder);
-       if (err != OGGDEC_SUCCESS)      {
-               debug_error("[CODEC OGG]Delete Decode fail\n");
-               err = MM_ERROR_SOUND_INTERNAL;
-       }
-
-       sem_destroy(&p->start_wave_signal);
-       sem_destroy(&p->start_ogg_signal);
-
-       if(p->pcm_out_buf) {
-               free(p->pcm_out_buf);
-               p->pcm_out_buf = NULL;
-       }
-
-       if (p) {
-               free (p);
-               p = NULL;
-       }
-
-       debug_leave("\n");
-       return err;
-}
-
-EXPORT_API
-int MMSoundGetPluginType(void)
-{
-       debug_enter("\n");
-       debug_leave("\n");
-       return MM_SOUND_PLUGIN_TYPE_CODEC;
-}
-
-EXPORT_API
-int MMSoundPlugCodecGetInterface(mmsound_codec_interface_t *intf)
-{
-       debug_enter("\n");
-       if (!intf) {
-               debug_critical("Confirm the codec interface struct (is NULL)\n");
-               return MM_ERROR_SOUND_INTERNAL;
-       }
-
-       intf->GetSupportTypes   = MMSoundPlugCodecOggGetSupportTypes;
-       intf->Parse             = MMSoundPlugCodecOggParse;
-       intf->Create            = MMSoundPlugCodecOggCreate;
-       intf->Destroy           = MMSoundPlugCodecOggDestroy;
-       intf->Play              = MMSoundPlugCodecOggPlay;
-       intf->Stop              = MMSoundPlugCodecOggStop;
-       intf->SetThreadPool     = MMSoundPlugCodecOggSetThreadPool;
-
-       debug_leave("\n");
-       return MM_ERROR_NONE;
-}
index 856cbbd..dd427f5 100644 (file)
@@ -756,14 +756,6 @@ int* MMSoundPlugCodecToneGetSupportTypes(void)
     return suported;
 }
 
-int MMSoundPlugCodecToneParse(MMSourceType *source, mmsound_codec_info_t *info)
-{
-       debug_enter("\n");
-       // do nothing
-       debug_leave("\n");
-       return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
-}
-
 int MMSoundPlugCodecToneCreate(mmsound_codec_param_t *param, mmsound_codec_info_t *info, MMHandleType *handle)
 {
        tone_info_t *toneInfo;
@@ -1235,7 +1227,6 @@ int MMSoundPlugCodecGetInterface(mmsound_codec_interface_t *intf)
     debug_enter("\n");
 
     intf->GetSupportTypes   = MMSoundPlugCodecToneGetSupportTypes;
-    intf->Parse             = MMSoundPlugCodecToneParse;
     intf->Create            = MMSoundPlugCodecToneCreate;
     intf->Destroy           = MMSoundPlugCodecToneDestroy;
     intf->Play              = MMSoundPlugCodecTonePlay;
index 435778b..859d085 100644 (file)
@@ -1,19 +1,21 @@
 lib_LTLIBRARIES = libsoundpluginwave.la
 
-libsoundpluginwave_la_SOURCES = mm_sound_plugin_codec_wave.c 
+libsoundpluginwave_la_SOURCES = mm_sound_plugin_codec_wave.c
 
 libsoundpluginwave_la_CFLAGS  = \
                                $(MMCOMMON_CFLAGS) \
-                              -I$(srcdir)/../../../include \
-                              -I$(srcdir)/../../include \
+                               -I$(srcdir)/../../../include \
+                               -I$(srcdir)/../../include \
                                $(PA_CFLAGS) \
+                               $(SNDFILE_CFLAGS) \
                                $(MMLOGSVR_CFLAGS) -DMMF_LOG_OWNER=0x002 -DMMF_DEBUG_PREFIX=\"MMF-SOUND\"
 
 libsoundpluginwave_la_LIBADD  = $(MMCOMMON_LIBS) \
                                $(MMLOGSVR_LIBS) \
                                $(PA_LIBS) \
+                               $(SNDFILE_LIBS) \
                                $(srcdir)/../../../libmmfsound.la \
-                               $(srcdir)/../../../common/libmmfsoundcommon.la 
+                               $(srcdir)/../../../common/libmmfsoundcommon.la
 
 install-exec-hook:
        mkdir -p $(DESTDIR)$(libdir)/soundplugins
index 7fd61b0..2b67cef 100644 (file)
 #include <string.h>
 #include <stdint.h>
 
-#include <semaphore.h>
 
 #include <mm_error.h>
 #include <mm_debug.h>
-#include <pthread.h>
 #include <mm_sound_pa_client.h>
 
 #include "../../include/mm_sound_plugin_codec.h"
 #include "../../../include/mm_sound_common.h"
 #include <unistd.h>
 
-#define SAMPLE_COUNT   128
-#define WAV_FILE_SAMPLE_PLAY_DURATION          350                     /*Unit: ms*/
-enum {
-       WAVE_CODE_UNKNOWN                               = 0,
-       WAVE_CODE_PCM                                   = 1,
-       WAVE_CODE_ADPCM                         = 2,
-       WAVE_CODE_G711                                  = 3,
-       WAVE_CODE_IMA_ADPCM                             = 17,
-       WAVE_CODE_G723_ADPCM                    = 20,
-       WAVE_CODE_GSM                                   = 49,
-       WAVE_CODE_G721_ADPCM                    = 64,
-       WAVE_CODE_MPEG                                  = 80,
-};
-
-#define MAKE_FOURCC(a, b, c, d)                ((a) | (b) << 8) | ((c) << 16 | ((d) << 24))
-#define RIFF_CHUNK_ID                          ((uint32_t) MAKE_FOURCC('R', 'I', 'F', 'F'))
-#define RIFF_CHUNK_TYPE                        ((uint32_t) MAKE_FOURCC('W', 'A', 'V', 'E'))
-#define FMT_CHUNK_ID                           ((uint32_t) MAKE_FOURCC('f', 'm', 't', ' '))
-#define DATA_CHUNK_ID                          ((uint32_t) MAKE_FOURCC('d', 'a', 't', 'a'))
-
-#define CODEC_WAVE_LOCK(LOCK) do { pthread_mutex_lock(LOCK); } while (0)
-#define CODEC_WAVE_UNLOCK(LOCK) do { pthread_mutex_unlock(LOCK); } while (0)
-
-enum {
-   STATE_NONE = 0,
-   STATE_READY,
-   STATE_BEGIN,
-   STATE_PLAY,
-   STATE_STOP,
-};
+#include <sndfile.h>
+#include <pulse/pulseaudio.h>
 
 typedef struct
 {
-       char *ptr_current;
-       int size;
-       int transper_size;
        int handle;
-       int period;
-       int tone;
-       int keytone;
        int repeat_count;
        int (*stop_cb)(int);
-       int cb_param; // slotid
-       int state;
-       pthread_mutex_t mutex;
-       pthread_mutex_t *codec_wave_mutex;
-       int mode;
-       int volume_config;
-       int channels;
-       int samplerate;
-       int format;
-       MMSourceType *source;
-       char buffer[48000 / 1000 * SAMPLE_COUNT * 2 *2];//segmentation fault when above 22.05KHz stereo
-       int gain, out, in, option;
+       char filename[MM_SOUND_MAX_FILENAME];
+       int cb_param;
        char stream_type[MM_SOUND_STREAM_TYPE_LEN];
        int stream_index;
+
+       pa_threaded_mainloop *m;
+       pa_context *c;
+       pa_stream* s;
+       pa_sample_spec spec;
+       SNDFILE* sf;
+       SF_INFO si;
 } wave_info_t;
 
-static void _runing(void *param);
+static int _sound_prepare(wave_info_t *h)
+{
+       memset(&h->si, 0, sizeof(SF_INFO));
+
+       h->sf = sf_open(h->filename, SFM_READ, &h->si);
+       if (!h->sf) {
+               debug_error("sf_open error. path(%s), error(%d,%s)", h->filename, sf_error(h->sf), sf_strerror(h->sf));
+               return (sf_error(h->sf) == SF_ERR_SYSTEM) ? MM_ERROR_SOUND_INTERNAL : MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
+       }
+
+       h->spec.rate = h->si.samplerate;
+       h->spec.channels = h->si.channels;
+       h->spec.format = PA_SAMPLE_S16LE;
 
-static int (*g_thread_pool_func)(void*, void (*)(void*)) = NULL;
+       debug_msg("SF_INFO : frames = %lld, samplerate = %d, channels = %d, format = 0x%X, sections = %d, seekable = %d",
+                       h->si.frames, h->si.samplerate, h->si.channels, h->si.format, h->si.sections, h->si.seekable);
 
-int MMSoundPlugCodecWaveSetThreadPool(int (*func)(void*, void (*)(void*)))
+       return 0;
+}
+
+static int _sound_rewind(wave_info_t *h)
 {
-    debug_enter("(func : %p)\n", func);
-    g_thread_pool_func = func;
-    debug_leave("\n");
-    return MM_ERROR_NONE;
+       return (sf_seek(h->sf, 0, SEEK_SET) != -1) ? 0 : -1;
 }
 
-int* MMSoundPlugCodecWaveGetSupportTypes(void)
+static int _sound_is_rewind_needed(wave_info_t *h)
 {
-    debug_enter("\n");
-    static int suported[2] = {MM_SOUND_SUPPORTED_CODEC_WAVE, 0};
-    debug_leave("\n");
-    return suported;
+       return (h->repeat_count == -1 || h->repeat_count > 1);
 }
 
-int MMSoundPlugCodecWaveParse(MMSourceType *source, mmsound_codec_info_t *info)
+static void _sound_unprepare(wave_info_t *h)
 {
-       struct __riff_chunk
-       {
-               uint32_t chunkid;
-               uint32_t chunksize;
-               uint32_t rifftype;
-       };
-
-       struct __wave_chunk
-       {
-               uint32_t chunkid;
-               uint32_t chunksize;
-               uint16_t compression;
-               uint16_t channels;
-               uint32_t samplerate;
-               uint32_t avgbytepersec;
-               uint16_t blockkalign;
-               uint16_t bitspersample;
-       };
-
-       struct __data_chunk
-       {
-               uint32_t chunkid;
-               uint32_t chunkSize;
-       };
-
-       struct __riff_chunk *priff = NULL;
-       struct __wave_chunk *pwav = NULL;
-       struct __data_chunk *pdata = NULL;
-//     struct __fmt_chunk *pfmt = NULL;
-
-       int datalen = -1;
-       char *data = NULL;
-       unsigned int tSize;
-
-       debug_enter("\n");
-
-       data = MMSourceGetPtr(source);
-       debug_msg("[CODEC WAV] source ptr :[%p]\n", data);
-
-       datalen = MMSourceGetCurSize(source);
-       debug_msg("[CODEC WAV] source size :[0x%08X]\n", datalen);
-
-       priff = (struct __riff_chunk *) data;
-
-       /* Must be checked, Just for wav or not */
-       if (priff->chunkid != RIFF_CHUNK_ID ||priff->rifftype != RIFF_CHUNK_TYPE)
-               return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
-
-       if(priff->chunksize != datalen -8)
-               priff->chunksize = (datalen-8);
-
-       if (priff->chunkid != RIFF_CHUNK_ID ||priff->chunksize != datalen -8 ||priff->rifftype != RIFF_CHUNK_TYPE) {
-               debug_msg("[CODEC WAV] This contents is not RIFF file\n");
-               debug_msg("[CODEC WAV] cunkid : %ld, chunksize : %ld, rifftype : 0x%lx\n", priff->chunkid, priff->chunksize, priff->rifftype);
-               //debug_msg("[CODEC WAV] cunkid : %ld, chunksize : %d, rifftype : 0x%lx\n", RIFF_CHUNK_ID, datalen-8, RIFF_CHUNK_TYPE);
-               return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
+       if (h->sf) {
+               sf_close(h->sf);
+               h->sf = NULL;
        }
+}
 
-       debug_msg("[CODEC WAV] cunkid : %ld, chunksize : %ld, rifftype : 0x%lx\n", priff->chunkid, priff->chunksize, priff->rifftype);
-       //debug_msg("[CODEC WAV] cunkid : %ld, chunksize : %d, rifftype : 0x%lx\n", RIFF_CHUNK_ID, datalen-8, RIFF_CHUNK_TYPE);
-
-       tSize = sizeof(struct __riff_chunk);
-       pdata = (struct __data_chunk*)(data+tSize);
+/* Context Callbacks */
+static void _pa_context_state_callback(pa_context *c, void *userdata) {
+       pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
+       assert(c);
+
+       switch (pa_context_get_state(c)) {
+               case PA_CONTEXT_CONNECTING:
+               case PA_CONTEXT_AUTHORIZING:
+               case PA_CONTEXT_SETTING_NAME:
+                       debug_log("context(%p), state(%d)", c, pa_context_get_state(c));
+                       break;
+
+               case PA_CONTEXT_READY:
+               case PA_CONTEXT_TERMINATED:
+               case PA_CONTEXT_FAILED:
+                       debug_warning("context(%p), state(%d)", c, pa_context_get_state(c));
+                       pa_threaded_mainloop_signal(m, 0);
+                       break;
+
+               default:
+                       break;
+       }
+}
 
-       while (pdata->chunkid != FMT_CHUNK_ID && tSize < datalen) {
-               tSize += (pdata->chunkSize+8);
+static void _pa_context_drain_complete_callback(pa_context *c, void *userdata)
+{
+       pa_context_disconnect(c);
+}
 
-               if (tSize >= datalen) {
-                       debug_warning("[CODEC WAV] Parsing finished : unable to find the Wave Format chunk\n");
-                       return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
-               } else {
-                       pdata = (struct __data_chunk*)(data+tSize);
-               }
-       }
-       pwav = (struct __wave_chunk*)(data+tSize);
-
-       if (pwav->chunkid != FMT_CHUNK_ID ||
-           pwav->compression != WAVE_CODE_PCM ||       /* Only supported PCM */
-           pwav->avgbytepersec != pwav->samplerate * pwav->blockkalign ||
-           pwav->blockkalign != (pwav->bitspersample >> 3)*pwav->channels) {
-               debug_msg("[CODEC WAV] This contents is not supported wave file\n");
-               debug_msg("[CODEC WAV] chunkid : 0x%lx, comp : 0x%x, av byte/sec : %lu, blockalign : %d\n", pwav->chunkid, pwav->compression, pwav->avgbytepersec, pwav->blockkalign);
-               return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
+/* Stream Callbacks */
+static void _pa_stream_state_callback(pa_stream *s, void *userdata)
+{
+       pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
+
+       assert(s);
+
+       switch (pa_stream_get_state(s)) {
+               case PA_STREAM_CREATING:
+                       debug_log("stream(%p), state(%d)", s, pa_stream_get_state(s));
+                       break;
+               case PA_STREAM_READY:
+               case PA_STREAM_FAILED:
+               case PA_STREAM_TERMINATED:
+                       debug_warning("stream(%p), state(%d)", s, pa_stream_get_state(s));
+                       pa_threaded_mainloop_signal(m, 0);
+                       break;
+               default:
+                       break;
        }
+}
 
-       /* Only One data chunk support */
+static void _pa_stream_drain_complete_callback(pa_stream* s, int success, void *userdata)
+{
+       pa_operation *o = NULL;
+       wave_info_t *h = (wave_info_t *)userdata;
 
-       tSize += (pwav->chunksize+8);
-       pdata = (struct __data_chunk *)(data+tSize);
+       debug_msg("drain complete : %p, %d", s, success);
 
-       while (pdata->chunkid != DATA_CHUNK_ID && tSize < datalen) {
-               tSize += (pdata->chunkSize+8);
-               if (tSize >= datalen) {
-                       debug_warning("[CODEC WAV] Parsing finished : unable to find the data chunk\n");
-                       return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
-               } else {
-                       pdata = (struct __data_chunk*)(data+tSize);
-               }
+       if (!success) {
+               debug_error("drain failed. s(%p), success(%d)", s, success);
+               //pa_threaded_mainloop_signal(h->m, 0);
        }
 
-       info->codec = MM_SOUND_SUPPORTED_CODEC_WAVE;
-       info->channels = pwav->channels;
-       info->format = pwav->bitspersample;
-       info->samplerate = pwav->samplerate;
-       info->doffset = (tSize+8);
-       info->size = pdata->chunkSize;
-       info->duration = ((info->size)*1000)/pwav->avgbytepersec;
-       debug_msg("info->size:%d info->duration: %d\n", info->size, info->duration);
-
-       debug_leave("\n");
-       return MM_ERROR_NONE;
+       pa_stream_disconnect(h->s);
+       pa_stream_unref(h->s);
+       h->s = NULL;
+
+       if (!(o = pa_context_drain(h->c, _pa_context_drain_complete_callback, h)))
+               pa_context_disconnect(h->c);
+       else
+               pa_operation_unref(o);
+
+       debug_msg("Call stop callback(%p, %p) of mgr_codec", h->stop_cb, h->cb_param);
+       if (h->stop_cb)
+               h->stop_cb(h->cb_param);
 }
 
+static void _pa_stream_moved_callback(pa_stream *s, void *userdata)
+{
+       assert(s);
+       debug_msg("stream moved callback : %p", s);
+}
 
+static void _pa_stream_underflow_callback(pa_stream *s, void *userdata)
+{
+       wave_info_t *h = (wave_info_t *)userdata;
+       assert(s);
+
+       debug_msg("stream underflow callback : %p, file(%s)", s, h->filename);
+}
 
-int MMSoundPlugCodecWaveCreate(mmsound_codec_param_t *param, mmsound_codec_info_t *info, MMHandleType *handle)
+static void _pa_stream_buffer_attr_callback(pa_stream *s, void *userdata)
 {
-       wave_info_t* p = NULL;
-       MMSourceType *source;
-       static int keytone_period = 0;
+       assert(s);
+       debug_msg("stream underflow callback : %p", s);
+}
 
-#ifdef DEBUG_DETAIL
-       debug_enter("\n");
-#endif
+static void _pa_stream_write_callback(pa_stream *s, size_t length, void *userdata)
+{
+       sf_count_t bytes = 0;
+       void *data = NULL;
+       size_t data_length = 0;
+       size_t frame_size;
+       pa_operation *o = NULL;
+       wave_info_t *h = (wave_info_t *)userdata;
+
+       if (!s || length <= 0) {
+               debug_error("write error. stream(%p), length(%d)", s, length);
+               return;
+       }
 
-       debug_msg("period[%d] type[%s] ch[%d] format[%d] rate[%d] doffset[%d] repeat[%d] volume[%f] callback[%p]\n",
-                       keytone_period, (info->codec == MM_SOUND_SUPPORTED_CODEC_WAVE) ? "Wave" : "Unknown",
-                       info->channels, info->format, info->samplerate, info->doffset, param->repeat_count,
-                       param->volume, param->stop_cb);
-       source = param->source;
+       frame_size = pa_frame_size(&h->spec);
+       data_length = length;
 
-       if (g_thread_pool_func == NULL) {
-               debug_error("[CODEC WAV] Need thread pool!\n");
-               return MM_ERROR_SOUND_INTERNAL;
+       if (pa_stream_begin_write(s, &data, &data_length) < 0) {
+               debug_error("failed to pa_stream_begin_write()");
+               return;
        }
 
-       p = (wave_info_t *) malloc(sizeof(wave_info_t));
+       if ((bytes = sf_readf_short(h->sf, data, (sf_count_t)(data_length / frame_size))) > 0)
+               bytes *= (sf_count_t)frame_size;
 
-       if (p == NULL) {
-               debug_error("[CODEC WAV] memory allocation failed\n");
-               return MM_ERROR_OUT_OF_MEMORY;
+       debug_log("=== %lld / %d ===",bytes, data_length);
+
+       if (bytes > 0)
+               pa_stream_write(s, data, (size_t)bytes, NULL, 0, PA_SEEK_RELATIVE);
+       else
+               pa_stream_cancel_write(s);
+
+       /* If No more data, drain stream */
+       if (bytes < (sf_count_t)data_length) {
+               debug_msg("EOS!!!!! %lld/%d", bytes, data_length);
+
+               /* Handle loop */
+               if (_sound_is_rewind_needed(h)) {
+                       debug_msg("repeat count = %d", h->repeat_count);
+                       h->repeat_count--;
+
+                       if (_sound_rewind(h) == 0)
+                               return;
+
+                       debug_error("REWIND failed....");
+                       /* can't loop anymore, fallback and do drain */
+               }
+
+               /* EOS callback will be notified after drain is completed */
+               pa_stream_set_write_callback(s, NULL, NULL);
+               o = pa_stream_drain(s, _pa_stream_drain_complete_callback, h);
+               if (o)
+                       pa_operation_unref(o);
        }
+}
 
-       memset(p, 0, sizeof(wave_info_t));
-       p->handle = 0;
+static int _pa_context_connect(wave_info_t *h)
+{
+       pa_threaded_mainloop *m = NULL;
+       pa_context *c = NULL;
 
-       p->ptr_current = MMSourceGetPtr(source) + info->doffset;
+       /* Mainloop */
+       if (!(m = pa_threaded_mainloop_new())) {
+               debug_error("mainloop create failed");
+               goto error;
+       }
 
-       p->size = info->size;
-       p->transper_size = info->samplerate / 1000 * SAMPLE_COUNT * (info->format >> 3) * info->channels;
+       /* Context */
+       if (!(c = pa_context_new(pa_threaded_mainloop_get_api(m), NULL))) {
+               debug_error("context create failed");
+               goto error;
+       }
 
-       p->tone = param->tone;
-       p->repeat_count = param ->repeat_count;
-       p->stop_cb = param->stop_cb;
-       p->cb_param = param->param;
-       p->source = source;
-       p->codec_wave_mutex = param->codec_wave_mutex;
-       p->stream_index = param->stream_index;
-       MMSOUND_STRNCPY(p->stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
-       //      pthread_mutex_init(&p->mutex, NULL);
+       pa_context_set_state_callback(c, _pa_context_state_callback, m);
 
-       debug_msg("[CODEC WAV] transper_size : %d\n", p->transper_size);
-       debug_msg("[CODEC WAV] size : %d\n", p->size);
+       pa_threaded_mainloop_lock(m);
 
-       if(info->duration < WAV_FILE_SAMPLE_PLAY_DURATION) {
-               p->mode = HANDLE_MODE_OUTPUT_LOW_LATENCY;
-       } else {
-               p->mode = HANDLE_MODE_OUTPUT;
+       if (pa_threaded_mainloop_start(m) < 0) {
+               debug_error("mainloop start failed");
+               goto error;
        }
 
-       p->volume_config = param->volume_config;
-       p->channels = info->channels;
-       p->samplerate = info->samplerate;
-
-       switch(info->format)
-       {
-       case 8:
-               p->format =  PA_SAMPLE_U8;
-               break;
-       case 16:
-               p->format =  PA_SAMPLE_S16LE;
-               break;
-       default:
-               p->format =  PA_SAMPLE_S16LE;
-               break;
+       if (pa_context_connect(c, NULL, 0, NULL) < 0) {
+               debug_error("context connect failed");
+               goto error;
        }
 
-       debug_msg("[CODEC WAV] PARAM mode : [%d]\n", p->mode);
-       debug_msg("[CODEC WAV] PARAM channels : [%d]\n", p->channels);
-       debug_msg("[CODEC WAV] PARAM samplerate : [%d]\n", p->samplerate);
-       debug_msg("[CODEC WAV] PARAM format : [%d]\n", p->format);
-       debug_msg("[CODEC WAV] PARAM volume type : [%x]\n", p->volume_config);
+       for (;;) {
+               pa_context_state_t state = pa_context_get_state(c);
+               if (state == PA_CONTEXT_READY)
+                       break;
 
-       p->state = STATE_READY;
+               if (!PA_CONTEXT_IS_GOOD(state)) {
+                       debug_error("Context error!!!! %d", pa_context_errno(c));
+                       goto error;
+               }
 
-       g_thread_pool_func(p, _runing);
-       debug_msg("[CODEC WAV] Thread pool start\n");
-       *handle = (MMHandleType)p;
+               pa_threaded_mainloop_wait(m);
+       }
 
-#ifdef DEBUG_DETAIL
-       debug_leave("\n");
-#endif
+       h->m = m;
+       h->c = c;
 
-       return MM_ERROR_NONE;
-}
+       pa_threaded_mainloop_unlock(m);
+
+       return 0;
 
+error:
+       if (c)
+               pa_context_unref(c);
 
-int MMSoundPlugCodecWavePlay(MMHandleType handle)
+       pa_threaded_mainloop_unlock(m);
+
+       if (m)
+               pa_threaded_mainloop_free(m);
+
+       return -1;
+}
+
+static int _pa_stream_connect(wave_info_t *h)
 {
-       wave_info_t *p = (wave_info_t *) handle;
+       pa_stream *s = NULL;
+       pa_proplist *proplist = NULL;
+       pa_stream_state_t state;
+
+       proplist = pa_proplist_new();
+       if (!proplist)
+               return -1;
+       if (h->stream_type)
+               pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, h->stream_type);
+       if (h->stream_index != -1)
+               pa_proplist_setf(proplist, PA_PROP_MEDIA_PARENT_ID, "%d", h->stream_index);
+
+       pa_threaded_mainloop_lock(h->m);
+
+       s = pa_stream_new_with_proplist(h->c, "wav-player", &h->spec, NULL, proplist);
+       pa_proplist_free(proplist);
+       if (!s) {
+               debug_error("pa_stream_new failed. file(%s)", h->filename);
+               goto error;
+       }
+
+       pa_stream_set_state_callback(s, _pa_stream_state_callback, h->m);
+       pa_stream_set_write_callback(s, _pa_stream_write_callback, h);
+       pa_stream_set_moved_callback(s, _pa_stream_moved_callback, h);
+       pa_stream_set_underflow_callback(s, _pa_stream_underflow_callback, h);
+       pa_stream_set_buffer_attr_callback(s, _pa_stream_buffer_attr_callback, h);
 
-       debug_enter("(handle %x)\n", handle);
+       pa_stream_connect_playback(s, NULL, NULL,
+                                                       PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE,
+                                                       NULL, NULL);
+       for (;;) {
+               state = pa_stream_get_state(s);
 
-       if (p->size <= 0) {
-               debug_error("[CODEC WAV] end of file\n");
-               return MM_ERROR_END_OF_FILE;
+               if (state == PA_STREAM_READY)
+                       break;
+
+               if (!PA_STREAM_IS_GOOD(state)) {
+                       debug_error("Stream error!!!! %d", state);
+                       goto error;
+               }
+
+               /* Wait until the stream is ready */
+               pa_threaded_mainloop_wait(h->m);
        }
-       debug_msg("[CODEC WAV] send start signal\n");
-       p->state = STATE_BEGIN;
 
-       debug_leave("\n");
+       h->s = s;
 
-       return MM_ERROR_NONE;
+       pa_threaded_mainloop_unlock(h->m);
+
+       return 0;
+
+error:
+       if (s)
+               pa_stream_unref(s);
+
+       pa_threaded_mainloop_unlock(h->m);
+
+       return -1;
 }
 
-static void _runing(void *param)
+static void _pa_stream_uncork(wave_info_t *h)
 {
-       wave_info_t *p = (wave_info_t*) param;
-       int nread = 0;
-       char *org_cur = NULL;
-       int org_size = 0;
-       char *dummy = NULL;
-       int size;
+       pa_operation *o = NULL;
 
-       pa_sample_spec ss;
+       assert(h);
+       assert(h->m);
+       assert(h->s);
 
-       if (p == NULL) {
-               debug_error("[CODEC WAV] param is null\n");
-               return;
+       pa_threaded_mainloop_lock(h->m);
+
+       if ((o = pa_stream_cork(h->s, 0, NULL, NULL)))
+               pa_operation_unref(o);
+       else
+               debug_error("stream uncork failed");
+
+       pa_threaded_mainloop_unlock(h->m);
+}
+
+static int _pa_stream_stop_disconnect(wave_info_t *h)
+{
+       assert(h);
+       assert(h->m);
+
+       pa_threaded_mainloop_lock(h->m);
+       if (h->s) {
+               pa_stream_disconnect(h->s);
+               pa_stream_unref(h->s);
+               h->s = NULL;
        }
+       if (h->c) {
+               pa_context_unref(h->c);
+               h->c = NULL;
+       }
+       pa_threaded_mainloop_unlock(h->m);
 
-       debug_enter("[CODEC WAV] (Slot ID %d)\n", p->cb_param);
-       CODEC_WAVE_LOCK(p->codec_wave_mutex);
-
-       ss.rate = p->samplerate;
-       ss.channels = p->channels;
-       ss.format = p->format;
-       p->period = pa_sample_size(&ss) * ((ss.rate * 25) / 1000);
-       p->handle = mm_sound_pa_open(p->mode, p->volume_config, &ss, NULL, &size, p->stream_type, p->stream_index);
-       if(!p->handle) {
-               debug_critical("[CODEC WAV] Can not open audio handle\n");
-               CODEC_WAVE_UNLOCK(p->codec_wave_mutex);
-               return;
+       pa_threaded_mainloop_free(h->m);
+       h->m = NULL;
+
+       return 0;
+}
+
+static int* _mm_sound_plug_codec_wave_get_supported_types(void)
+{
+       static int suported[2] = { MM_SOUND_SUPPORTED_CODEC_WAVE, 0 };
+       return suported;
+}
+
+static int _mm_sound_plug_codec_wave_parse(const char *filename, mmsound_codec_info_t *info)
+{
+       SNDFILE* sf = NULL;
+       SF_INFO si;
+
+       if (!filename || !info) {
+               debug_error("filename(%p) or info(%p) is invalid...", filename, info);
+               return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       if (p->handle == 0) {
-               debug_critical("[CODEC WAV] audio_handle is not created !! \n");
-               CODEC_WAVE_UNLOCK(p->codec_wave_mutex);
-               free(p);
-               p = NULL;
-               return;
+       /* FIXME : following sndfile code should be encapsulated */
+       memset(&si, 0, sizeof(SF_INFO));
+       sf = sf_open(filename, SFM_READ, &si);
+       if (!sf) {
+               debug_error("sf_open error. path(%s), error(%d, %s)", filename, sf_error(sf), sf_strerror(sf));
+               if (sf_error(sf) == SF_ERR_SYSTEM)
+                       return MM_ERROR_SOUND_INTERNAL;
+               else
+                       return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
        }
 
-       /* Set the thread schedule */
-       org_cur = p->ptr_current;
-       org_size = p->size;
+       info->codec = MM_SOUND_SUPPORTED_CODEC_WAVE;
+       info->channels = si.channels;
+       info->samplerate = si.samplerate;
 
-       dummy = malloc(p->period);
-       if(!dummy) {
-               debug_error("[CODEC WAV] not enough memory");
-               CODEC_WAVE_UNLOCK(p->codec_wave_mutex);
-               return;
-       }
-       memset(dummy, 0, p->period);
-       p->transper_size = p->period;
-       /* stop_size = org_size > p->period ? org_size : p->period; */
+       debug_msg("filename = %s, frames[%lld], samplerate[%d], channels[%d], format[%x], sections[%d], seekable[%d]",
+                       filename, si.frames, si.samplerate, si.channels, si.format, si.sections, si.seekable);
+       sf_close(sf);
 
-       debug_msg("[CODEC WAV] Wait start signal\n");
+       return MM_ERROR_NONE;
+}
 
-       while(p->state == STATE_READY) {
-               usleep(4);
+static int _mm_sound_plug_codec_wave_create(mmsound_codec_param_t *param, mmsound_codec_info_t *info, MMHandleType *handle)
+{
+       wave_info_t* p = NULL;
+       int ret = 0;
+
+#ifdef DEBUG_DETAIL
+       debug_enter();
+#endif
+
+       p = (wave_info_t *) malloc(sizeof(wave_info_t));
+       if (p == NULL) {
+               debug_error("memory allocation failed");
+               return MM_ERROR_OUT_OF_MEMORY;
        }
 
-       debug_msg("[CODEC WAV] Recv start signal\n");
-       debug_msg("[CODEC WAV] repeat : %d\n", p->repeat_count);
-       debug_msg("[CODEC WAV] transper_size : %d\n", p->transper_size);
+       memset(p, 0, sizeof(wave_info_t));
+       p->handle = 0;
+       p->repeat_count = param ->repeat_count;
+       p->stop_cb = param->stop_cb;
+       p->cb_param = param->param;
+       MMSOUND_STRNCPY(p->filename, param->pfilename, MM_SOUND_MAX_FILENAME);
+       p->stream_index = param->stream_index;
+       MMSOUND_STRNCPY(p->stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
 
-       if (p->state != STATE_STOP) {
-               debug_msg("[CODEC WAV] Play start\n");
-               p->state = STATE_PLAY;
-       } else {
-               debug_warning ("[CODEC WAV] state is already STATE_STOP\n");
+       ret = _sound_prepare(p);
+       if (ret < 0) {
+               debug_error("failed to prepare sound");
+               goto error;
        }
 
-       while (((p->repeat_count == -1)?(1):(p->repeat_count--)) && p->state == STATE_PLAY) {
-               while (p->state == STATE_PLAY && p->size > 0) {
-                       if (p->size >= p->transper_size) {
-                               nread = p->transper_size;
-                               memcpy(p->buffer, p->ptr_current, nread);
-                               mm_sound_pa_write(p->handle, p->buffer, nread);
-                               p->ptr_current += nread;
-                               p->size -= nread;
-                               debug_msg("[CODEC WAV] Playing, nRead_data : %d Size : %d \n", nread, p->size);
-                       } else {
-                               /* Write remain size */
-                               nread = p->size;
-                               memcpy(p->buffer, p->ptr_current, nread);
-                               mm_sound_pa_write(p->handle, p->buffer, nread);
-                               mm_sound_pa_write(p->handle, dummy, (p->transper_size-nread));
-                               p->ptr_current += nread;
-                               p->size = 0;
-                       }
-               }
-               p->ptr_current = org_cur;
-               p->size = org_size;
+       ret = _pa_context_connect(p);
+       if (ret < 0) {
+               debug_error("failed to connect context...");
+               goto error;
        }
 
-       debug_msg("[CODEC WAV] End playing\n");
-       p->state = STATE_STOP;
-
-       if (p->handle == 0) {
-               usleep(200000);
-               debug_warning("[CODEC WAV] audio already unrealize !!\n");
-       } else {
-               /* usleep(75000); */
-               if(MM_ERROR_NONE != mm_sound_pa_drain(p->handle))
-                       debug_error("mm_sound_pa_drain() failed\n");
-
-               if(MM_ERROR_NONE != mm_sound_pa_close(p->handle)) {
-                       debug_error("[CODEC WAV] Can not close audio handle\n");
-               } else {
-                       p->handle = 0;
-               }
+       ret = _pa_stream_connect(p);
+       if (ret < 0) {
+               debug_error("failed to connect stream...");
+               goto error;
        }
-       CODEC_WAVE_UNLOCK(p->codec_wave_mutex);
 
-       p->handle = 0;
+       *handle = (MMHandleType)p;
 
-       p->state = STATE_NONE;
+#ifdef DEBUG_DETAIL
+       debug_leave("%p", p);
+#endif
+       return MM_ERROR_NONE;
 
-       free(dummy); dummy = NULL;
-       if (p->stop_cb)
-       {
-               debug_msg("[CODEC WAV] Play is finished, Now start callback\n");
-               p->stop_cb(p->cb_param);
-       }
-       debug_leave("\n");
+error:
+       free(p);
+       return MM_ERROR_SOUND_INTERNAL;
 }
 
 
-int MMSoundPlugCodecWaveStop(MMHandleType handle)
+static int _mm_sound_plug_codec_wave_play(MMHandleType handle)
+{
+       wave_info_t *p = (wave_info_t *) handle;
+
+       debug_msg("Start handle %p", p);
+       _pa_stream_uncork(p);
+
+       return MM_ERROR_NONE;
+}
+
+static int _mm_sound_plug_codec_wave_stop(MMHandleType handle)
 {
+       int ret = 0;
        wave_info_t *p = (wave_info_t*) handle;
 
        if (!p) {
-               debug_error("The handle is null\n");
+               debug_error("The handle is null");
                return MM_ERROR_SOUND_INTERNAL;
        }
-       debug_msg("[CODEC WAV] Current state is state %d\n", p->state);
-       debug_msg("[CODEC WAV] Handle 0x%08X stop requested\n", handle);
 
-       p->state = STATE_STOP;
+       debug_msg("Handle %p stop requested", p);
+
+       ret = _pa_stream_stop_disconnect(p);
+
+       if (p->stop_cb)
+               p->stop_cb(p->cb_param);
 
-    return MM_ERROR_NONE;
+       return (ret == 0) ? MM_ERROR_NONE : MM_ERROR_SOUND_INTERNAL;
 }
 
-int MMSoundPlugCodecWaveDestroy(MMHandleType handle)
+static int _mm_sound_plug_codec_wave_destroy(MMHandleType handle)
 {
-       wave_info_t *p = (wave_info_t*) handle;
+       wave_info_t *p = (wave_info_t *)handle;
 
        if (!p) {
-               debug_warning("Can not destroy handle :: handle is invalid");
+               debug_error("Can not destroy handle :: handle is invalid");
                return MM_ERROR_SOUND_INVALID_POINTER;
        }
 
-       if(p->source) {
-               mm_source_close(p->source);
-               free(p->source); p->source = NULL;
-       }
+       _sound_unprepare(p);
 
-       free(p); p = NULL;
+       free(p);
+       p = NULL;
 
        return MM_ERROR_NONE;
 }
 
 EXPORT_API
-int MMSoundGetPluginType(void)
+int MMSoundPlugCodecGetInterface(mmsound_codec_interface_t *intf)
 {
-    return MM_SOUND_PLUGIN_TYPE_CODEC;
+       assert(intf);
+
+       intf->GetSupportTypes   = _mm_sound_plug_codec_wave_get_supported_types;
+       intf->Parse             = _mm_sound_plug_codec_wave_parse;
+       intf->Create            = _mm_sound_plug_codec_wave_create;
+       intf->Play              = _mm_sound_plug_codec_wave_play;
+       intf->Stop              = _mm_sound_plug_codec_wave_stop;
+       intf->Destroy           = _mm_sound_plug_codec_wave_destroy;
+       intf->SetThreadPool     = NULL;
+
+       return MM_ERROR_NONE;
 }
 
 EXPORT_API
-int MMSoundPlugCodecGetInterface(mmsound_codec_interface_t *intf)
+int MMSoundGetPluginType(void)
 {
-    intf->GetSupportTypes   = MMSoundPlugCodecWaveGetSupportTypes;
-    intf->Parse             = MMSoundPlugCodecWaveParse;
-    intf->Create            = MMSoundPlugCodecWaveCreate;
-    intf->Destroy           = MMSoundPlugCodecWaveDestroy;
-    intf->Play              = MMSoundPlugCodecWavePlay;
-    intf->Stop              = MMSoundPlugCodecWaveStop;
-    intf->SetThreadPool     = MMSoundPlugCodecWaveSetThreadPool;
-
-    return MM_ERROR_NONE;
+       return MM_SOUND_PLUGIN_TYPE_CODEC;
 }