Enhance log format for dlog & enhance pcm dump, remove unused code 07/120007/5
authorHyunseok Lee <hs7388.lee@samsung.com>
Tue, 10 Jan 2017 00:52:30 +0000 (09:52 +0900)
committerJeongho Mok <jho.mok@samsung.com>
Tue, 28 Mar 2017 09:42:34 +0000 (18:42 +0900)
[Version] 5.0.113
[Profile] Common
[Issue Type] Enhancement

Change-Id: If84343458933c04b3f2d85cf22c381724db557c9

23 files changed:
configure.ac
packaging/pulseaudio.spec
src/Makefile.am
src/map-file
src/pulse/introspect.c
src/pulse/introspect.h
src/pulse/simple.c
src/pulse/simple.h
src/pulsecore/core.c
src/pulsecore/core.h
src/pulsecore/log.c
src/pulsecore/native-common.h
src/pulsecore/pdispatch.c
src/pulsecore/protocol-native.c
src/pulsecore/sink-input.c
src/pulsecore/sink-input.h
src/pulsecore/sink.c
src/pulsecore/sink.h
src/pulsecore/source-output.c
src/pulsecore/source-output.h
src/pulsecore/source.c
src/pulsecore/source.h
src/utils/pactl.c

index b309ded..4f4e59a 100644 (file)
@@ -1405,6 +1405,18 @@ else
     USE_PER_USER_ESOUND_SOCKET=0
 fi
 
+dnl use pcm-dump --------------------------------------------------------------------------
+AC_ARG_ENABLE(pcm-dump, AC_HELP_STRING([--enable-pcm-dump], [using pcm-dump]),
+ [
+       case "${enableval}" in
+               yes) ENABLE_PCM_DUMP=yes ;;
+               no)  ENABLE_PCM_DUMP=no ;;
+               *)   AC_MSG_ERROR(bad value ${enableval} for --enable-pcm-dump) ;;
+       esac
+],[ENABLE_PCM_DUMP=no])
+AM_CONDITIONAL(ENABLE_PCM_DUMP, test "x$ENABLE_PCM_DUMP" = "xyes")
+dnl end --------------------------------------------------------------------
+
 #### Cynara ####
 dnl use security ---------------------------------------------------------------
 AC_ARG_ENABLE(security, AC_HELP_STRING([--enable-security], [using security]),
index c03ddbc..dac33b3 100644 (file)
@@ -4,6 +4,7 @@
 %bcond_without pulseaudio_udev_with_usb_only
 %bcond_with pulseaudio_with_bluez5
 %bcond_with x
+%bcond_without pcm_dump
 
 %define udev_dir %{_prefix}/lib/udev
 %define upgrade_script_dir %{_datadir}/upgrade/scripts
@@ -11,7 +12,7 @@
 Name:             pulseaudio
 Summary:          Improved Linux sound server
 Version:          5.0
-Release:          112
+Release:          113
 Group:            Multimedia/Audio
 License:          LGPL-2.1
 URL:              http://pulseaudio.org
@@ -261,6 +262,9 @@ NOCONFIGURE=yes ./bootstrap.sh
 %if %{with pulseaudio_udev_with_usb_only}
         --enable-udev-with-usb-only \
 %endif
+%if %{with pcm_dump}
+        --enable-pcm-dump \
+%endif
 %if "%{?TIZEN_PRODUCT_TV}" == "1"
         --enable-prelink \
         --enable-lwipc \
index 78a4f26..12af807 100644 (file)
@@ -233,6 +233,11 @@ pactl_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la $(LIBSND
 pactl_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) -fPIC -pie
 pactl_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
+if ENABLE_PCM_DUMP
+pactl_CFLAGS += $(VCONF_CFLAGS) -DENABLE_PCM_DUMP
+pactl_LDADD += $(VCONF_LIBS)
+endif
+
 pasuspender_SOURCES = utils/pasuspender.c
 pasuspender_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 pasuspender_CFLAGS = $(AM_CFLAGS)
@@ -1007,6 +1012,10 @@ libpulse_la_CFLAGS += $(DBUS_CFLAGS)
 libpulse_la_LIBADD += $(DBUS_LIBS)
 endif
 
+if ENABLE_PCM_DUMP
+libpulse_la_CFLAGS += -DENABLE_PCM_DUMP
+endif
+
 libpulse_simple_la_SOURCES = pulse/simple.c pulse/simple.h
 libpulse_simple_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
 libpulse_simple_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
@@ -1149,6 +1158,10 @@ if HAVE_SIMPLEDB
 libpulsecore_@PA_MAJORMINOR@_la_SOURCES += pulsecore/database-simple.c
 endif
 
+if ENABLE_PCM_DUMP
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS += -DENABLE_PCM_DUMP
+endif
+
 # We split the foreign code off to not be annoyed by warnings we don't care about
 noinst_LTLIBRARIES += libpulsecore-foreign.la
 
@@ -1234,6 +1247,9 @@ endif
 if USE_SECURITY
 libprotocol_native_la_SOURCES += pulsecore/cynara.c pulsecore/cynara.h
 endif
+if ENABLE_PCM_DUMP
+libprotocol_native_la_CFLAGS += -DENABLE_PCM_DUMP
+endif
 
 libtunnel_manager_la_SOURCES = \
                modules/tunnel-manager/remote-device.c modules/tunnel-manager/remote-device.h \
index 99dc287..dec0a35 100644 (file)
@@ -92,6 +92,8 @@ pa_context_set_default_sink;
 pa_context_set_default_source;
 pa_context_set_event_callback;
 pa_context_set_name;
+pa_context_set_pcm_dump;
+pa_context_set_pcm_dump_option;
 pa_context_set_sink_input_mute;
 pa_context_set_sink_input_volume;
 pa_context_set_sink_input_volume_ramp;
index a72020a..27184cb 100644 (file)
@@ -2260,3 +2260,50 @@ pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, in
 
     return o;
 }
+
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+pa_operation* pa_context_set_pcm_dump(pa_context *c, uint32_t dump_type, int dump_type_enable, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_PCM_DUMP, &tag);
+    pa_tagstruct_putu32(t, dump_type);
+    pa_tagstruct_put_boolean(t, dump_type_enable);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_set_pcm_dump_option(pa_context *c, uint32_t dump_option, int dump_option_enable, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_PCM_DUMP_OPTION, &tag);
+    pa_tagstruct_putu32(t, dump_option);
+    pa_tagstruct_put_boolean(t, dump_option_enable);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+#endif
+
index 127cade..c4763b5 100644 (file)
@@ -558,6 +558,11 @@ pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char*name
 /** Set the latency offset of a port. \since 3.0 */
 pa_operation* pa_context_set_port_latency_offset(pa_context *c, const char *card_name, const char *port_name, int64_t offset, pa_context_success_cb_t cb, void *userdata);
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+pa_operation* pa_context_set_pcm_dump(pa_context *c, uint32_t dump_type, int dump_type_enable, pa_context_success_cb_t cb, void *userdata);
+pa_operation* pa_context_set_pcm_dump_option(pa_context *c, uint32_t dump_option, int dump_option_enable, pa_context_success_cb_t cb, void *userdata);
+#endif
+
 /** @} */
 
 /** @{ \name Sink Inputs */
index af2dd7f..fbcaf2b 100644 (file)
 #include <pulse/thread-mainloop.h>
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/native-common.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
 #include "simple.h"
-#include "internal.h"
 
 struct pa_simple {
     pa_threaded_mainloop *mainloop;
@@ -104,24 +102,6 @@ static void context_state_cb(pa_context *c, void *userdata) {
     }
 }
 
-static void stream_success_context_cb(pa_stream *s, int success, void *userdata) {
-    pa_simple *p = userdata;
-    pa_assert(s);
-    pa_assert(p);
-
-    p->operation_success = success;
-    pa_threaded_mainloop_signal(p->mainloop, 0);
-}
-
-static void success_context_cb(pa_context *c, int success, void *userdata) {
-    pa_simple *p = userdata;
-    pa_assert(c);
-    pa_assert(p);
-
-    p->operation_success = success;
-    pa_threaded_mainloop_signal(p->mainloop, 0);
-}
-
 static void stream_state_cb(pa_stream *s, void * userdata) {
     pa_simple *p = userdata;
     pa_assert(s);
@@ -271,6 +251,7 @@ fail:
     return NULL;
 }
 
+#ifdef __TIZEN__
 pa_simple* pa_simple_new_proplist(
         const char *server,
         const char *name,
@@ -387,6 +368,8 @@ fail:
     pa_simple_free(p);
     return NULL;
 }
+#endif
+
 void pa_simple_free(pa_simple *s) {
     pa_assert(s);
 
@@ -588,6 +571,7 @@ unlock_and_fail:
     return -1;
 }
 
+#ifdef __TIZEN__
 int pa_simple_get_stream_index(pa_simple *p, unsigned int *idx, int *rerror) {
     pa_assert(p);
     CHECK_VALIDITY_RETURN_ANY(rerror, idx != NULL, PA_ERR_INVALID, -1);
@@ -605,6 +589,7 @@ unlock_and_fail:
     pa_threaded_mainloop_unlock(p->mainloop);
     return -1;
 }
+#endif
 
 pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) {
     pa_usec_t t;
index 8fc021a..0dfbc69 100644 (file)
 #include <pulse/cdecl.h>
 #include <pulse/version.h>
 
+#ifdef __TIZEN__
 #include <pulse/proplist.h>
+#endif
+
 /** \page simple Simple API
  *
  * \section overv_sec Overview
@@ -130,6 +133,7 @@ pa_simple* pa_simple_new(
     int *error                          /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */
     );
 
+#ifdef __TIZEN__
 /** Create a new connection to the server with proplist */
 pa_simple* pa_simple_new_proplist(
     const char *server,                 /**< Server name, or NULL for default */
@@ -143,6 +147,8 @@ pa_simple* pa_simple_new_proplist(
     pa_proplist *proplist,              /**< Properties, or NULL for default */
     int *error                          /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */
     );
+#endif
+
 /** Close and free the connection to the server. The connection object becomes invalid when this is called. */
 void pa_simple_free(pa_simple *s);
 
@@ -170,8 +176,10 @@ pa_usec_t pa_simple_get_latency(pa_simple *s, int *error);
 /** Flush the playback or record buffer. This discards any audio in the buffer. */
 int pa_simple_flush(pa_simple *s, int *error);
 
+#ifdef __TIZEN__
 /** Get stream index */
 int pa_simple_get_stream_index(pa_simple *p, unsigned int *idx, int *rerror);
+#endif
 
 PA_C_DECL_END
 
index b6c65ec..2bccac5 100644 (file)
@@ -167,12 +167,9 @@ pa_core* pa_core_new(pa_mainloop_api *m, bool shared, size_t shm_size) {
     pa_core_check_idle(c);
 
 #ifdef __TIZEN__
-    c->dump_sink = false;
-    c->dump_sink_input = false;
-    c->dump_source = false;
-    c->dump_source_output = false;
-
     c->zero_pop_threshold = 10;
+    c->pcm_dump = 0;
+    c->pcm_dump_option = 0;
 #endif
 
     c->state = PA_CORE_RUNNING;
index 6d29382..e383b17 100644 (file)
@@ -135,6 +135,33 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_MAX
 } pa_core_hook_t;
 
+
+#ifdef __TIZEN__
+#define PA_PCM_DUMP_PATH_PREFIX "/tmp/pcm"
+#define PA_PCM_DUMP_VCONF_KEY "memory/private/sound/pcm_dump"
+
+enum {
+    PA_PCM_DUMP_GST_DECODER_OUT     = 0x00000001U,
+    PA_PCM_DUMP_GST_RESAMPLER_IN    = 0x00000008U,
+    PA_PCM_DUMP_GST_RESAMPLER_OUT   = 0x00000010U,
+    PA_PCM_DUMP_GST_AUDIO_SINK_IN   = 0x00000400U,
+    PA_PCM_DUMP_PA_STREAM_WRITE     = 0x00000800U,
+    PA_PCM_DUMP_PA_SINK_INPUT       = 0x00002000U,
+    PA_PCM_DUMP_PA_SINK             = 0x00004000U,
+    PA_PCM_DUMP_PA_SOURCE           = 0x00020000U,
+    PA_PCM_DUMP_PA_SOURCE_OUTPUT    = 0x00040000U,
+    PA_PCM_DUMP_PA_STREAM_READ      = 0x00100000U,
+    PA_PCM_DUMP_GST_AUDIO_SRC_OUT   = 0x00200000U,
+    PA_PCM_DUMP_GST_ENCODER_IN      = 0x80000000U,
+};
+
+enum {
+    PA_PCM_DUMP_OPTION_SEPARATED    = 0x0001U,
+    PA_PCM_DUMP_OPTION_MONITOR      = 0x0002U,
+};
+#endif
+
+
 /* The core structure of PulseAudio. Every PulseAudio daemon contains
  * exactly one of these. It is used for storing kind of global
  * variables for the daemon. */
@@ -201,12 +228,9 @@ struct pa_core {
     pa_hook hooks[PA_CORE_HOOK_MAX];
 
 #ifdef __TIZEN__
-    bool dump_sink;
-    bool dump_sink_input;
-    bool dump_source;
-    bool dump_source_output;
-
     int zero_pop_threshold;
+    uint32_t pcm_dump;
+    uint32_t pcm_dump_option;
 #endif
 };
 
index 5156375..26fb8b5 100644 (file)
@@ -432,6 +432,12 @@ void pa_log_levelv_meta(
 
     pa_vsnprintf(text, sizeof(text), format, ap);
 
+#ifdef USE_DLOG
+    if ((_target == PA_LOG_DLOG) && file && line > 0 && func)
+        pa_snprintf(location, sizeof(location), "%s: %s(%i) > [%s] ",
+                    pa_path_get_filename(file), func, line, pa_thread_get_name(pa_thread_self()));
+    else
+#endif
     if ((_flags & PA_LOG_PRINT_META) && file && line > 0 && func)
         pa_snprintf(location, sizeof(location), "[%s][%s:%i %s()] ",
                     pa_strnull(pa_thread_get_name(pa_thread_self())), file, line, func);
@@ -599,24 +605,23 @@ void pa_log_levelv_meta(
                 if ((local_t = pa_utf8_to_locale(t)))
                     t = local_t;
 
-                switch (level)
-                {
-                                       case PA_LOG_DEBUG:
-                                               SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s",  timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_INFO:
-                                       case PA_LOG_NOTICE: /* no notice category in dlog, use info instead */
-                                               SLOG (LOG_INFO, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_WARN:
-                                               SLOG (LOG_WARN, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_ERROR:
-                                               SLOG (LOG_ERROR, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       default:
-                                               SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
+                switch (level) {
+                    case PA_LOG_DEBUG:
+                        print_system_log(DLOG_DEBUG, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_INFO:
+                    case PA_LOG_NOTICE: /* no notice category in dlog, use info instead */
+                        print_system_log(DLOG_INFO, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_WARN:
+                        print_system_log(DLOG_WARN, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_ERROR:
+                        print_system_log(DLOG_ERROR, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
+                    default:
+                        print_system_log(DLOG_DEBUG, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
                 }
 
                 pa_xfree(local_t);
@@ -624,37 +629,36 @@ void pa_log_levelv_meta(
                 break;
             }
             case PA_LOG_DLOG_COLOR: {
-                               char *local_t;
-
-                               openlog(ident, LOG_PID, LOG_USER);
-
-                               if ((local_t = pa_utf8_to_locale(t)))
-                                       t = local_t;
-
-                               switch (level)
-                               {
-                                       case PA_LOG_DEBUG:
-                                               SLOG (LOG_DEBUG, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_GREEN, timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_INFO:
-                                       case PA_LOG_NOTICE: /* no notice category in dlog, use info instead */
-                                               SLOG (LOG_INFO, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_BLUE, timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_WARN:
-                                               SLOG (LOG_WARN, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_MAGENTA, timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_ERROR:
-                                               SLOG (LOG_ERROR, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_RED, timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       default:
-                                               SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
-                               }
-
-                               pa_xfree(local_t);
-
-                               break;
-                       }
+                char *local_t;
+
+                openlog(ident, LOG_PID, LOG_USER);
+
+                if ((local_t = pa_utf8_to_locale(t)))
+                    t = local_t;
+
+                switch (level) {
+                    case PA_LOG_DEBUG:
+                        print_system_log(DLOG_DEBUG, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_GREEN, location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_INFO:
+                    case PA_LOG_NOTICE: /* no notice category in dlog, use info instead */
+                        print_system_log(DLOG_INFO, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_BLUE, location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_WARN:
+                        print_system_log(DLOG_WARN, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_MAGENTA, location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_ERROR:
+                        print_system_log(DLOG_ERROR, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_RED, location, timestamp, t, pa_strempty(bt));
+                        break;
+                    default:
+                        print_system_log(DLOG_DEBUG, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_GREEN, location, timestamp, t, pa_strempty(bt));
+                        break;
+                }
+
+                pa_xfree(local_t);
+
+                break;
+            }
 
 #endif
             case PA_LOG_NULL:
index b467096..6a8526a 100644 (file)
@@ -78,18 +78,10 @@ enum {
     PA_COMMAND_SET_SOURCE_MUTE,
 
     PA_COMMAND_CORK_PLAYBACK_STREAM,
-#ifdef __TIZEN__
-    PA_COMMAND_CORK_PLAYBACK_STREAM_ALL,
-#endif
     PA_COMMAND_FLUSH_PLAYBACK_STREAM,
     PA_COMMAND_TRIGGER_PLAYBACK_STREAM,
 
     PA_COMMAND_SET_DEFAULT_SINK,
-#ifdef __TIZEN__
-    PA_COMMAND_SET_DEFAULT_SINK_BY_API_BUS,
-    PA_COMMAND_SET_DEFAULT_SINK_FOR_USB,
-    PA_COMMAND_UNLOAD_HDMI,
-#endif
     PA_COMMAND_SET_DEFAULT_SOURCE,
 
     PA_COMMAND_SET_PLAYBACK_STREAM_NAME,
@@ -191,6 +183,11 @@ enum {
     PA_COMMAND_CHECK_PRIVILEGE,
 #endif
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    PA_COMMAND_SET_PCM_DUMP,
+    PA_COMMAND_SET_PCM_DUMP_OPTION,
+#endif
+
     PA_COMMAND_MAX
 };
 
index 1171862..8643378 100644 (file)
@@ -100,9 +100,6 @@ static const char *command_names[PA_COMMAND_MAX] = {
     [PA_COMMAND_CORK_PLAYBACK_STREAM] = "CORK_PLAYBACK_STREAM",
 
     [PA_COMMAND_SET_DEFAULT_SINK] = "SET_DEFAULT_SINK",
-#ifdef __TIZEN__
-    [PA_COMMAND_SET_DEFAULT_SINK_BY_API_BUS] = "SET_DEFAULT_SINK_BY_API_BUS",
-#endif
     [PA_COMMAND_SET_DEFAULT_SOURCE] = "SET_DEFAULT_SOURCE",
 
     [PA_COMMAND_SET_PLAYBACK_STREAM_NAME] = "SET_PLAYBACK_STREAM_NAME",
index 3871cfe..2c5b828 100644 (file)
@@ -310,6 +310,10 @@ static void command_set_volume_ramp(pa_pdispatch *pd, uint32_t command, uint32_t
 #ifdef USE_SECURITY
 static void command_check_privilege(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 #endif
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+static void command_set_pcm_dump(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+static void command_set_pcm_dump_option(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+#endif
 
 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_ERROR] = NULL,
@@ -418,6 +422,10 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
 #ifdef __TIZEN__
     [PA_COMMAND_CHECK_PRIVILEGE] = command_check_privilege,
 #endif
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    [PA_COMMAND_SET_PCM_DUMP] = command_set_pcm_dump,
+    [PA_COMMAND_SET_PCM_DUMP_OPTION] = command_set_pcm_dump_option,
+#endif
 
     [PA_COMMAND_EXTENSION] = command_extension
 };
@@ -667,8 +675,8 @@ static int update_buffer_attr(pa_proplist* proplist, pa_buffer_attr* ret_attr, b
         pa_log_error("failed to get %s", PA_PROP_BUFFER_ATTR_MAXLENGTH);
         return -1;
     }
-    if (pa_atoi(_propStr, &ret_attr->maxlength)) {
-        pa_log_error("failed to pa_atoi for maxlength");
+    if (pa_atou(_propStr, &ret_attr->maxlength)) {
+        pa_log_error("failed to pa_atou for maxlength");
         return -1;
     }
 
@@ -678,8 +686,8 @@ static int update_buffer_attr(pa_proplist* proplist, pa_buffer_attr* ret_attr, b
             pa_log_error("failed to get %s", PA_PROP_BUFFER_ATTR_TLENGTH);
             return -1;
         }
-        if (pa_atoi(_propStr, &ret_attr->tlength)) {
-            pa_log_error("failed to pa_atoi for tlength");
+        if (pa_atou(_propStr, &ret_attr->tlength)) {
+            pa_log_error("failed to pa_atou for tlength");
             return -1;
         }
 
@@ -687,8 +695,8 @@ static int update_buffer_attr(pa_proplist* proplist, pa_buffer_attr* ret_attr, b
             pa_log_error("failed to get %s", PA_PROP_BUFFER_ATTR_PREBUF);
             return -1;
         }
-        if (pa_atoi(_propStr, &ret_attr->prebuf)) {
-            pa_log_error("failed to pa_atoi for prebuf");
+        if (pa_atou(_propStr, &ret_attr->prebuf)) {
+            pa_log_error("failed to pa_atou for prebuf");
             return -1;
         }
 
@@ -696,8 +704,8 @@ static int update_buffer_attr(pa_proplist* proplist, pa_buffer_attr* ret_attr, b
             pa_log_error("failed to get %s", PA_PROP_BUFFER_ATTR_MINREQ);
             return -1;
         }
-        if (pa_atoi(_propStr, &ret_attr->minreq)) {
-            pa_log_error("failed to pa_atoi for minreq");
+        if (pa_atou(_propStr, &ret_attr->minreq)) {
+            pa_log_error("failed to pa_atou for minreq");
             return -1;
         }
 
@@ -710,8 +718,8 @@ static int update_buffer_attr(pa_proplist* proplist, pa_buffer_attr* ret_attr, b
             pa_log_error("failed to get %s", PA_PROP_BUFFER_ATTR_FRAGSIZE);
             return -1;
         }
-        if (pa_atoi(_propStr, &ret_attr->fragsize)) {
-            pa_log_error("failed to pa_atoi for fragsize");
+        if (pa_atou(_propStr, &ret_attr->fragsize)) {
+            pa_log_error("failed to pa_atou for fragsize");
             return -1;
         }
 
@@ -4642,134 +4650,6 @@ static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t comman
     pa_pstream_send_simple_ack(c->pstream, tag);
 }
 
-#ifdef __TIZEN__
-static void command_set_default_sink_by_api_bus(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
-    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
-    pa_sink *sink;
-    bool found = false;
-    const char *api, *bus;
-    const char *api_string, *bus_string, *form_factor;
-    uint32_t idx;
-
-    pa_native_connection_assert_ref(c);
-    pa_assert(t);
-
-    if (pa_tagstruct_gets(t, &api) < 0 ||
-            pa_tagstruct_gets(t, &bus) < 0 ||
-            !pa_tagstruct_eof(t)) {
-        protocol_error(c);
-        return;
-    }
-
-    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
-    CHECK_VALIDITY(c->pstream, !api || pa_utf8_valid(api), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, !bus || pa_utf8_valid(bus), tag, PA_ERR_INVALID);
-
-    pa_assert(command == PA_COMMAND_SET_DEFAULT_SINK_BY_API_BUS);
-
-    PA_IDXSET_FOREACH(sink, c->protocol->core->sinks, idx) {
-        if (sink && sink->proplist) {
-        api_string = pa_proplist_gets(sink->proplist, "device.api");
-        if (api_string) {
-            pa_log_debug("Found api = [%s]\n", api_string);
-            if (!strcmp(api, api_string)) {
-                bus_string = pa_proplist_gets(sink->proplist, "device.bus");
-                if (bus_string) {
-                    pa_log_debug("Found bus = [%s]\n", bus_string);
-                    if(!strcmp(bus, bus_string)) {
-                        pa_log_debug("  ** FOUND!!! set default sink to [%s]\n", sink->name);
-                        found = true;
-                        break;
-                    } else {
-                        pa_log_debug("No string [%s] match, match with form_factor = internal\n", bus);
-                        form_factor = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_FORM_FACTOR );
-                        if (form_factor) {
-                            if(!strcmp(form_factor, "internal")) {
-                                pa_log_debug("Found internal device(sink) , set (%s) as default sink", sink->name);
-                                found = true;
-                                break;
-                            }
-                        }
-                        else {
-                            pa_log_debug("This device doesn't have form factor property");
-                        }
-                    }
-                } else {
-                    pa_log_debug(" Found no bus ");
-                    if (!strcmp(DEVICE_BUS_BUILTIN, bus)) {
-                        pa_log_debug(" searching bus was builtin, then select this");
-                        found = true;
-                        break;
-                    }
-                }
-            } else {
-                pa_log_debug("No string [%s] match!!!!\n", api);
-            }
-        }
-
-        }
-    }
-
-    if (!found)
-        sink = NULL;
-
-    CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
-
-    pa_namereg_set_default_sink(c->protocol->core, sink);
-
-    pa_pstream_send_simple_ack(c->pstream, tag);
-}
-
-static void command_set_default_sink_for_usb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
-    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
-    pa_sink *sink;
-    bool found = false;
-    const char *serial;
-    const char *s;
-    uint32_t idx;
-
-    pa_native_connection_assert_ref(c);
-    pa_assert(t);
-
-    if (pa_tagstruct_gets(t, &s) < 0 ||
-        !pa_tagstruct_eof(t)) {
-        protocol_error(c);
-        return;
-    }
-
-    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
-    CHECK_VALIDITY(c->pstream, !s || pa_namereg_is_valid_name(s), tag, PA_ERR_INVALID);
-
-    pa_assert(command == PA_COMMAND_SET_DEFAULT_SINK_FOR_USB);
-
-    PA_IDXSET_FOREACH(sink, c->protocol->core->sinks, idx) {
-        if (sink && sink->card && sink->card->proplist) {
-            if ((serial = pa_proplist_gets(sink->card->proplist, PA_PROP_DEVICE_SERIAL)) == NULL) {
-                pa_log_warn("  ** No serial for this sink [%s]", sink->name);
-                continue;
-            }
-
-            if ((found = pa_streq(serial, s))) {
-                pa_log_info("  ** serial [%s] for sink [%s] is matched, set as default sink\n", serial, sink->name);
-                break;
-            } else {
-                pa_log_debug("  ** serial [%s] for sink [%s] is not matched...", serial, sink->name);
-            }
-        }
-    }
-
-    if (!found)
-        sink = NULL;
-
-    CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
-
-    pa_namereg_set_default_sink(c->protocol->core, sink);
-
-    pa_pstream_send_simple_ack(c->pstream, tag);
-}
-
-#endif /* __TIZEN__ */
-
 static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
     uint32_t idx;
@@ -5235,6 +5115,58 @@ static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command,
     pa_pstream_send_simple_ack(c->pstream, tag);
 }
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+static void command_set_pcm_dump(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
+    uint32_t dump_type;
+    bool dump_type_enable;
+
+    pa_native_connection_assert_ref(c);
+    pa_assert(t);
+
+    if (pa_tagstruct_getu32(t, &dump_type) < 0 ||
+        pa_tagstruct_get_boolean(t, &dump_type_enable) < 0 ||
+        !pa_tagstruct_eof(t)) {
+        protocol_error(c);
+        return;
+    }
+
+    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
+
+    if (dump_type_enable)
+        c->protocol->core->pcm_dump |= dump_type;
+    else
+        c->protocol->core->pcm_dump &= ~dump_type;
+
+    pa_pstream_send_simple_ack(c->pstream, tag);
+}
+
+static void command_set_pcm_dump_option(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
+    uint32_t dump_option;
+    bool dump_option_enable;
+
+    pa_native_connection_assert_ref(c);
+    pa_assert(t);
+
+    if (pa_tagstruct_getu32(t, &dump_option) < 0 ||
+        pa_tagstruct_get_boolean(t, &dump_option_enable) < 0 ||
+        !pa_tagstruct_eof(t)) {
+        protocol_error(c);
+        return;
+    }
+
+    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
+
+    if (dump_option_enable)
+        c->protocol->core->pcm_dump_option |= dump_option;
+    else
+        c->protocol->core->pcm_dump_option &= ~dump_option;
+
+    pa_pstream_send_simple_ack(c->pstream, tag);
+}
+#endif
+
 /*** pstream callbacks ***/
 
 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
index 8356e25..f2260f0 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
 #include <time.h>
 #include <pulse/timeval.h>
 #endif
@@ -60,9 +60,70 @@ struct volume_factor_entry {
 };
 
 #ifdef __TIZEN__
-#define PA_SINK_INPUT_DUMP_PATH_PREFIX      "/tmp/dump_ap_out_stream"
 static void _empty_pop_reset(pa_sink_input *i);
 static bool _empty_pop_is_started(pa_sink_input *i);
+
+#ifdef ENABLE_PCM_DUMP
+static void pa_sink_input_write_pcm_dump(pa_sink_input *i, pa_memchunk *chunk)
+{
+    char *dump_time = NULL, *dump_path_surfix = NULL;
+    const char *s_device_api_str, *card_name_str, *device_idx_str;
+    struct timeval now;
+    struct tm tm;
+    char datetime[7];
+
+    /* open file for dump pcm */
+    if (i->core->pcm_dump & PA_PCM_DUMP_PA_SINK_INPUT && !i->pcm_dump_fp && i->state == PA_SINK_INPUT_RUNNING) {
+        pa_gettimeofday(&now);
+        localtime_r(&now.tv_sec, &tm);
+        memset(&datetime[0], 0x00, sizeof(datetime));
+        strftime(&datetime[0], sizeof(datetime), "%H%M%S", &tm);
+        dump_time = pa_sprintf_malloc("%s.%03ld", &datetime[0], now.tv_usec / 1000);
+
+        if ((s_device_api_str = pa_proplist_gets(i->sink->proplist, PA_PROP_DEVICE_API))) {
+            if (pa_streq(s_device_api_str, "alsa")) {
+                card_name_str = pa_proplist_gets(i->sink->proplist, "alsa.card_name");
+                device_idx_str = pa_proplist_gets(i->sink->proplist, "alsa.device");
+                dump_path_surfix = pa_sprintf_malloc("%s.%s", pa_strnull(card_name_str), pa_strnull(device_idx_str));
+            } else {
+                dump_path_surfix = pa_sprintf_malloc("%s", s_device_api_str);
+            }
+        } else {
+            dump_path_surfix = pa_sprintf_malloc("%s", i->sink->name);
+        }
+
+        i->dump_path = pa_sprintf_malloc("%s_%s_pa-input%d-sink%d-%s_%dch_%d.raw", PA_PCM_DUMP_PATH_PREFIX, pa_strempty(dump_time),
+            i->index, i->sink->index, pa_strempty(dump_path_surfix), i->sample_spec.channels, i->sample_spec.rate);
+        if (i->dump_path) {
+            i->pcm_dump_fp = fopen(i->dump_path, "w");
+            if (!i->pcm_dump_fp)
+                pa_log_warn("%s open failed", i->dump_path);
+            else
+                pa_log_info("%s opened", i->dump_path);
+        }
+        pa_xfree(dump_time);
+        pa_xfree(dump_path_surfix);
+    /* close file for dump pcm when config is changed */
+    } else if (~i->core->pcm_dump & PA_PCM_DUMP_PA_SINK_INPUT && i->pcm_dump_fp) {
+        fclose(i->pcm_dump_fp);
+        pa_log_info("%s closed", i->dump_path);
+        pa_xfree(i->dump_path);
+        i->pcm_dump_fp = NULL;
+    }
+
+    /* dump pcm */
+    if (i->pcm_dump_fp) {
+        void *ptr = NULL;
+
+        ptr = pa_memblock_acquire(chunk->memblock);
+        if (ptr)
+            fwrite((uint8_t *)ptr + chunk->index, 1, chunk->length, i->pcm_dump_fp);
+        else
+            pa_log_warn("pa_memblock_acquire is failed. ptr is NULL");
+        pa_memblock_release(chunk->memblock);
+    }
+}
+#endif
 #endif
 
 static struct volume_factor_entry *volume_factor_entry_new(const char *key, const pa_cvolume *volume) {
@@ -573,12 +634,14 @@ int pa_sink_input_new(
     reset_callbacks(i);
     i->userdata = NULL;
 #ifdef __TIZEN__
-    i->dump_fp = NULL;
-
     i->is_virtual = false;
     media_name = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
     if (media_name && pa_streq(media_name, "VIRTUAL_STREAM"))
         i->is_virtual = true;
+#ifdef ENABLE_PCM_DUMP
+    i->pcm_dump_fp = NULL;
+    i->dump_path = NULL;
+#endif
 #endif
     if (data->flags & PA_SINK_INPUT_START_RAMP_MUTED)
         pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_MUTED, data->sink->sample_spec.channels);
@@ -678,6 +741,16 @@ static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state)
 
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    if (i->state == PA_SINK_INPUT_RUNNING && i->pcm_dump_fp && (i->core->pcm_dump_option & PA_PCM_DUMP_OPTION_SEPARATED)) {
+        /* close file for dump pcm */
+        fclose(i->pcm_dump_fp);
+        pa_log_info("%s closed", i->dump_path);
+        pa_xfree(i->dump_path);
+        i->pcm_dump_fp = NULL;
+    }
+#endif
+
     update_n_corked(i, state);
     i->state = state;
 
@@ -809,11 +882,13 @@ static void sink_input_free(pa_object *o) {
 
     if (i->thread_info.resampler)
         pa_resampler_free(i->thread_info.resampler);
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
     /* close file for dump pcm */
-    if (i->dump_fp) {
-        fclose(i->dump_fp);
-        i->dump_fp = NULL;
+    if (i->pcm_dump_fp) {
+        fclose(i->pcm_dump_fp);
+        pa_log_info("%s closed", i->dump_path);
+        pa_xfree(i->dump_path);
+        i->pcm_dump_fp = NULL;
     }
 #endif
     if (i->format)
@@ -1141,41 +1216,9 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink bytes */, pa
         pa_cvolume_mute(volume, i->sink->sample_spec.channels);
     else
         *volume = i->thread_info.soft_volume;
-#ifdef __TIZEN__
-    /* open file for dump pcm */
-    if (i->core->dump_sink_input && !i->dump_fp) {
-        time_t t;
-        struct tm tm;
-        char datetime[12];
-        char *dump_path = NULL;
-
-        time(&t);
-        tzset();
-        localtime_r(&t, &tm);
-        memset(&datetime[0], 0x00, sizeof(datetime));
-        strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", &tm);
-        dump_path = pa_sprintf_malloc("%s_%s_%d_sink%d.pcm", PA_SINK_INPUT_DUMP_PATH_PREFIX, &datetime[0], i->index, i->sink->index);
-
-        if (dump_path) {
-            i->dump_fp = fopen(dump_path, "w");
-            pa_xfree(dump_path);
-        }
-    /* close file for dump pcm when config is changed */
-    } else if (!i->core->dump_sink_input && i->dump_fp) {
-        fclose(i->dump_fp);
-        i->dump_fp = NULL;
-    }
-
-    /* dump pcm */
-    if (i->dump_fp) {
-        void *ptr;
-
-        ptr = pa_memblock_acquire(chunk->memblock);
 
-        fwrite((uint8_t*) ptr + chunk->index, 1, chunk->length, i->dump_fp);
-
-        pa_memblock_release(chunk->memblock);
-    }
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    pa_sink_input_write_pcm_dump(i, chunk);
 #endif
 }
 
@@ -1234,10 +1277,10 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
 
     if (i->thread_info.rewrite_nbytes == (size_t) -1) {
 
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
         /* rewind pcm */
-        if (i->dump_fp) {
-            fseeko(i->dump_fp, (off_t)pa_memblockq_get_length(i->thread_info.render_memblockq) * (-1), SEEK_CUR);
+        if (i->pcm_dump_fp) {
+            fseeko(i->pcm_dump_fp, (off_t)pa_memblockq_get_length(i->thread_info.render_memblockq) * (-1), SEEK_CUR);
         }
 #endif
 
@@ -1262,10 +1305,10 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
         if (amount > 0) {
             pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
 
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
             /* rewind pcm */
-            if (i->dump_fp) {
-                fseeko(i->dump_fp, (off_t)amount * (-1), SEEK_CUR);
+            if (i->pcm_dump_fp) {
+                fseeko(i->pcm_dump_fp, (off_t)amount * (-1), SEEK_CUR);
             }
 #endif
 
index e2f9768..2e993d4 100644 (file)
@@ -270,10 +270,11 @@ struct pa_sink_input {
     } thread_info;
 
 #ifdef __TIZEN__
-    FILE *dump_fp;
     pa_usec_t empty_pop_initial_timestamp;
     uint32_t empty_pop_previous_duration;
     bool is_virtual;
+    FILE *pcm_dump_fp;
+    char *dump_path;
 #endif
 
     void *userdata;
index 6bfb16f..364a787 100644 (file)
@@ -27,7 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
 #include <time.h>
 #endif
 
@@ -74,79 +74,71 @@ struct sink_message_set_port {
     int ret;
 };
 
-#ifdef __TIZEN__
-//#define PA_DUMP_SINK_FOR_EACH_SUSPEND
-#define PA_DUMP_SINK_PATH_PREFIX            "/tmp/dump_pa_sink"
-#endif
-
 static void sink_free(pa_object *s);
 
 static void pa_sink_volume_change_push(pa_sink *s);
 static void pa_sink_volume_change_flush(pa_sink *s);
 static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes);
 
-#ifdef __TIZEN__
-static void __toggle_open_close_n_write_dump(pa_sink *s, pa_memchunk *target)
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+static void pa_sink_write_pcm_dump(pa_sink *s, pa_memchunk *chunk)
 {
+    char *dump_time = NULL, *dump_path_surfix = NULL;
+    const char *s_device_api_str, *card_name_str, *device_idx_str;
+    struct timeval now;
+    struct tm tm;
+    char datetime[7];
+
     /* open file for dump pcm */
-    if (s->core->dump_sink && !s->dump_fp) {
-        char *dump_path = NULL, *dump_path_surfix = NULL;
-        const char *s_device_api_str;
-#ifdef PA_DUMP_SINK_FOR_EACH_SUSPEND
-        time_t t;
-        char datetime[12];
-
-        time(&t);
+    if (s->core->pcm_dump & PA_PCM_DUMP_PA_SINK && !s->pcm_dump_fp && s->state == PA_SINK_RUNNING) {
+        pa_gettimeofday(&now);
+        localtime_r(&now.tv_sec, &tm);
         memset(&datetime[0], 0x00, sizeof(datetime));
-        strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", localtime(&t));
-#endif
+        strftime(&datetime[0], sizeof(datetime), "%H%M%S", &tm);
+        dump_time = pa_sprintf_malloc("%s.%03ld", &datetime[0], now.tv_usec / 1000);
 
         if ((s_device_api_str = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_API))) {
             if (pa_streq(s_device_api_str, "alsa")) {
-                const char *card_idx_str, *device_idx_str;
-                uint32_t card_idx = 0, device_idx = 0;
-
-                if ((card_idx_str = pa_proplist_gets(s->proplist, "alsa.card")))
-                    pa_atou(card_idx_str, &card_idx);
-                if ((device_idx_str = pa_proplist_gets(s->proplist, "alsa.device")))
-                    pa_atou(device_idx_str, &device_idx);
-                dump_path_surfix = pa_sprintf_malloc("alsa_%d_%d.pcm", card_idx, device_idx);
-            } else if (pa_streq(s_device_api_str, "bluez")) {
-                dump_path_surfix = pa_sprintf_malloc("bluez.pcm");
+                card_name_str = pa_proplist_gets(s->proplist, "alsa.card_name");
+                device_idx_str = pa_proplist_gets(s->proplist, "alsa.device");
+                dump_path_surfix = pa_sprintf_malloc("%s.%s", pa_strnull(card_name_str), pa_strnull(device_idx_str));
+            } else {
+                dump_path_surfix = pa_sprintf_malloc("%s", s_device_api_str);
             }
-        }
-        if (!dump_path_surfix) {
-            dump_path_surfix = pa_sprintf_malloc("idx_%d.pcm", s->index);
+        } else {
+            dump_path_surfix = pa_sprintf_malloc("%s", s->name);
         }
 
-#ifdef PA_DUMP_SINK_FOR_EACH_SUSPEND
-        dump_path = pa_sprintf_malloc("%s_%s_%s", PA_DUMP_SINK_PATH_PREFIX, &datetime[0], dump_path_surfix);
-#else
-        dump_path = pa_sprintf_malloc("%s_%s", PA_DUMP_SINK_PATH_PREFIX, dump_path_surfix);
-#endif
-
-        if (dump_path) {
-            s->dump_fp = fopen(dump_path, "w");
-            pa_log_info("pa_sink dump started:%s", dump_path);
-            pa_xfree(dump_path);
+        s->dump_path = pa_sprintf_malloc("%s_%s_pa-sink%d-%s_%dch_%d.raw", PA_PCM_DUMP_PATH_PREFIX, pa_strempty(dump_time),
+            s->index, pa_strempty(dump_path_surfix), s->sample_spec.channels, s->sample_spec.rate);
+        if (s->dump_path) {
+            s->pcm_dump_fp = fopen(s->dump_path, "w");
+            if (!s->pcm_dump_fp)
+                pa_log_warn("%s open failed", s->dump_path);
+            else
+                pa_log_info("%s opened", s->dump_path);
         }
-        if (dump_path_surfix)
-            pa_xfree(dump_path_surfix);
+        pa_xfree(dump_time);
+        pa_xfree(dump_path_surfix);
     /* close file for dump pcm when config is changed */
-    } else if (!s->core->dump_sink && s->dump_fp) {
-        fclose(s->dump_fp);
-        s->dump_fp = NULL;
+    } else if (~s->core->pcm_dump & PA_PCM_DUMP_PA_SINK && s->pcm_dump_fp) {
+        fclose(s->pcm_dump_fp);
+        pa_log_info("%s closed", s->dump_path);
+        pa_xfree(s->dump_path);
+        s->pcm_dump_fp = NULL;
     }
 
     /* dump pcm */
-    if (s->dump_fp) {
-        void *ptr;
-
-        ptr = pa_memblock_acquire(target->memblock);
+    if (s->pcm_dump_fp) {
+        void *ptr = NULL;
 
-        fwrite((uint8_t*) ptr + target->index, 1, target->length, s->dump_fp);
+        ptr = pa_memblock_acquire(chunk->memblock);
+        if (ptr)
+            fwrite((uint8_t *)ptr + chunk->index, 1, chunk->length, s->pcm_dump_fp);
+        else
+            pa_log_warn("pa_memblock_acquire is failed. ptr is NULL");
 
-        pa_memblock_release(target->memblock);
+        pa_memblock_release(chunk->memblock);
     }
 }
 #endif
@@ -392,8 +384,9 @@ pa_sink* pa_sink_new(
 
     s->save_volume = data->save_volume;
     s->save_muted = data->save_muted;
-#ifdef __TIZEN__
-    s->dump_fp = NULL;
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    s->pcm_dump_fp = NULL;
+    s->dump_path = NULL;
 #endif
 
     pa_silence_memchunk_get(
@@ -512,6 +505,17 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
 
     s->state = state;
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    /* close file for dump pcm */
+    if (s->pcm_dump_fp && (s->core->pcm_dump_option & PA_PCM_DUMP_OPTION_SEPARATED) &&
+        state == PA_SINK_IDLE && original_state == PA_SINK_RUNNING) {
+        fclose(s->pcm_dump_fp);
+        pa_log_info("%s closed", s->dump_path);
+        pa_xfree(s->dump_path);
+        s->pcm_dump_fp = NULL;
+    }
+#endif
+
     if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the appropriate events */
         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s);
         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
@@ -834,13 +838,16 @@ static void sink_free(pa_object *o) {
     if (s->ports)
         pa_hashmap_free(s->ports);
 
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
     /* close file for dump pcm */
-    if (s->dump_fp) {
-        fclose(s->dump_fp);
-        s->dump_fp = NULL;
+    if (s->pcm_dump_fp) {
+        fclose(s->pcm_dump_fp);
+        pa_log_info("%s closed", s->dump_path);
+        pa_xfree(s->dump_path);
+        s->pcm_dump_fp = NULL;
     }
 #endif
+
     pa_xfree(s);
 }
 
@@ -976,18 +983,6 @@ int pa_sink_suspend(pa_sink *s, bool suspend, pa_suspend_cause_t cause) {
     pa_log_debug("Suspend cause of sink %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
 
 #ifdef __TIZEN__
-#ifdef PA_DUMP_SINK_FOR_EACH_SUSPEND
-    /* close file for dump pcm */
-    if (suspend && s->dump_in_fp) {
-        fclose(s->dump_in_fp);
-        s->dump_in_fp = NULL;
-    }
-    if (suspend && s->dump_out_fp) {
-        fclose(s->dump_out_fp);
-        s->dump_out_fp = NULL;
-    }
-#endif
-
     if (s->suspend_cause) {
         ret = sink_set_state(s, PA_SINK_SUSPENDED);
         if (ret == 0 && cause == PA_SUSPEND_INTERNAL) {
@@ -1113,10 +1108,11 @@ void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {
         pa_log_debug("Processing rewind...");
         if (s->flags & PA_SINK_DEFERRED_VOLUME)
             pa_sink_volume_change_rewind(s, nbytes);
-#ifdef __TIZEN__
+
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
         /* rewind pcm */
-        if (s->dump_fp) {
-            fseeko(s->dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
+        if (s->pcm_dump_fp) {
+            fseeko(s->pcm_dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
         }
 #endif
     }
@@ -1376,8 +1372,8 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
 
     inputs_drop(s, info, n, result);
 
-#ifdef __TIZEN__
-    __toggle_open_close_n_write_dump(s, result);
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    pa_sink_write_pcm_dump(s, result);
 #endif
 
     pa_sink_unref(s);
@@ -1487,8 +1483,8 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
 
     inputs_drop(s, info, n, target);
 
-#ifdef __TIZEN__
-    __toggle_open_close_n_write_dump(s, target);
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    pa_sink_write_pcm_dump(s, target);
 #endif
     pa_sink_unref(s);
 }
index 8249556..8ca936b 100644 (file)
@@ -311,10 +311,11 @@ struct pa_sink {
     } thread_info;
 
 #ifdef __TIZEN__
-    FILE *dump_fp;
     pa_hashmap *device_types;
     void* device_item;
     bool use_internal_codec;
+    FILE *pcm_dump_fp;
+    char *dump_path;
 #endif
 
     void *userdata;
index 621c955..4969f74 100644 (file)
@@ -26,8 +26,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
 #include <time.h>
+#include <pulse/timeval.h>
 #endif
 
 #include <pulse/utf8.h>
@@ -52,8 +53,67 @@ PA_DEFINE_PUBLIC_CLASS(pa_source_output, pa_msgobject);
 static void source_output_free(pa_object* mo);
 static void set_real_ratio(pa_source_output *o, const pa_cvolume *v);
 
-#ifdef __TIZEN__
-#define PA_SOURCE_OUTPUT_DUMP_PATH_PREFIX      "/tmp/dump_pa_source_output"
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+static void pa_source_output_write_pcm_dump(pa_source_output *o, pa_memchunk *chunk)
+{
+    char *dump_time = NULL, *dump_path_surfix = NULL;
+    const char *s_device_api_str, *card_name_str, *device_idx_str;
+    struct timeval now;
+    struct tm tm;
+    char datetime[7];
+
+    /* open file for dump pcm */
+    if (o->core->pcm_dump & PA_PCM_DUMP_PA_SOURCE_OUTPUT && !o->pcm_dump_fp && o->state == PA_SOURCE_OUTPUT_RUNNING) {
+        pa_gettimeofday(&now);
+        localtime_r(&now.tv_sec, &tm);
+        memset(&datetime[0], 0x00, sizeof(datetime));
+        strftime(&datetime[0], sizeof(datetime), "%H%M%S", &tm);
+        dump_time = pa_sprintf_malloc("%s.%03ld", &datetime[0], now.tv_usec / 1000);
+
+        if ((s_device_api_str = pa_proplist_gets(o->source->proplist, PA_PROP_DEVICE_API))) {
+            if (pa_streq(s_device_api_str, "alsa")) {
+                card_name_str = pa_proplist_gets(o->source->proplist, "alsa.card_name");
+                device_idx_str = pa_proplist_gets(o->source->proplist, "alsa.device");
+                dump_path_surfix = pa_sprintf_malloc("%s.%s", pa_strnull(card_name_str), pa_strnull(device_idx_str));
+            } else {
+                dump_path_surfix = pa_sprintf_malloc("%s", s_device_api_str);
+            }
+        } else {
+            dump_path_surfix = pa_sprintf_malloc("%s", o->source->name);
+        }
+
+        o->dump_path = pa_sprintf_malloc("%s_%s_pa-output%d-source%d-%s_%dch_%d.raw", PA_PCM_DUMP_PATH_PREFIX, pa_strempty(dump_time),
+            o->index, o->source->index, pa_strempty(dump_path_surfix), o->sample_spec.channels, o->sample_spec.rate);
+        if (o->dump_path) {
+            o->pcm_dump_fp = fopen(o->dump_path, "w");
+            if (!o->pcm_dump_fp)
+                pa_log_warn("%s open failed", o->dump_path);
+            else
+                pa_log_info("%s opened", o->dump_path);
+        }
+        pa_xfree(dump_time);
+        pa_xfree(dump_path_surfix);
+    /* close file for dump pcm when config is changed */
+    } else if (~o->core->pcm_dump & PA_PCM_DUMP_PA_SOURCE_OUTPUT && o->pcm_dump_fp) {
+        fclose(o->pcm_dump_fp);
+        pa_log_info("%s closed", o->dump_path);
+        pa_xfree(o->dump_path);
+        o->pcm_dump_fp = NULL;
+    }
+
+    /* dump pcm */
+    if (o->pcm_dump_fp) {
+        void *ptr = NULL;
+
+        ptr = pa_memblock_acquire(chunk->memblock);
+        if (ptr)
+            fwrite((uint8_t *)ptr + chunk->index, 1, chunk->length, o->pcm_dump_fp);
+        else
+            pa_log_warn("pa_memblock_acquire is failed. ptr is NULL");
+
+        pa_memblock_release(chunk->memblock);
+    }
+}
 #endif
 
 pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data) {
@@ -495,8 +555,9 @@ int pa_source_output_new(
 
     reset_callbacks(o);
     o->userdata = NULL;
-#ifdef __TIZEN__
-    o->dump_fp = NULL;
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    o->pcm_dump_fp = NULL;
+    o->dump_path = NULL;
 #endif
 
     o->thread_info.state = o->state;
@@ -576,6 +637,16 @@ static void source_output_set_state(pa_source_output *o, pa_source_output_state_
 
     pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    if (o->state == PA_SOURCE_OUTPUT_RUNNING && o->pcm_dump_fp && (o->core->pcm_dump_option & PA_PCM_DUMP_OPTION_SEPARATED)) {
+        /* close file for dump pcm */
+        fclose(o->pcm_dump_fp);
+        pa_log_info("%s closed", o->dump_path);
+        pa_xfree(o->dump_path);
+        o->pcm_dump_fp = NULL;
+    }
+#endif
+
     update_n_corked(o, state);
     o->state = state;
 
@@ -677,11 +748,13 @@ static void source_output_free(pa_object* mo) {
     if (o->thread_info.resampler)
         pa_resampler_free(o->thread_info.resampler);
 
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
     /* close file for dump pcm */
-    if (o->dump_fp) {
-        fclose(o->dump_fp);
-        o->dump_fp = NULL;
+    if (o->pcm_dump_fp) {
+        fclose(o->pcm_dump_fp);
+        pa_log_info("%s closed", o->dump_path);
+        pa_xfree(o->dump_path);
+        o->pcm_dump_fp = NULL;
     }
 #endif
 
@@ -885,39 +958,8 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
         pa_memblockq_drop(o->thread_info.delay_memblockq, qchunk.length);
     }
 
-#ifdef __TIZEN__
-    /* open file for dump pcm */
-    if (o->core->dump_source_output && !o->dump_fp) {
-        time_t t;
-        struct tm tm;
-        char datetime[12];
-        char *dump_path = NULL;
-
-        time(&t);
-        tzset();
-        localtime_r(&t, &tm);
-        memset(&datetime[0], 0x00, sizeof(datetime));
-        strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", &tm);
-        dump_path = pa_sprintf_malloc("%s_%s_%d_source%d.pcm", PA_SOURCE_OUTPUT_DUMP_PATH_PREFIX, &datetime[0], o->index, o->source->index);
-
-        if (dump_path) {
-            o->dump_fp = fopen(dump_path, "w");
-            pa_xfree(dump_path);
-        }
-    /* close file for dump pcm when config is changed */
-    } else if (!o->core->dump_source_output && o->dump_fp) {
-        fclose(o->dump_fp);
-        o->dump_fp = NULL;
-    }
-
-    /* dump pcm */
-    if (o->dump_fp) {
-        void *ptr;
-
-        ptr = pa_memblock_acquire(chunk->memblock);
-        fwrite((uint8_t*) ptr + chunk->index, 1, chunk->length, o->dump_fp);
-        pa_memblock_release(chunk->memblock);
-    }
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    pa_source_output_write_pcm_dump(o, (pa_memchunk *)chunk);
 #endif
 }
 
@@ -939,10 +981,10 @@ void pa_source_output_process_rewind(pa_source_output *o, size_t nbytes /* in so
             nbytes = pa_resampler_result(o->thread_info.resampler, nbytes);
 
         pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) nbytes);
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
         /* rewind pcm */
-        if (o->dump_fp) {
-            fseeko(o->dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
+        if (o->pcm_dump_fp) {
+            fseeko(o->pcm_dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
         }
 #endif
 
index 3f7d199..a471324 100644 (file)
@@ -213,7 +213,8 @@ struct pa_source_output {
         pa_sink_input *direct_on_input;       /* may be NULL */
     } thread_info;
 #ifdef __TIZEN__
-    FILE *dump_fp;
+    FILE *pcm_dump_fp;
+    char *dump_path;
 #endif
 
     void *userdata;
index af61cc0..207f538 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
 #include <time.h>
 #endif
 
@@ -66,79 +66,71 @@ struct source_message_set_port {
     int ret;
 };
 
-#ifdef __TIZEN__
-//#define PA_DUMP_SOURCE_FOR_EACH_SUSPEND
-#define PA_DUMP_SOURCE_PATH_PREFIX            "/tmp/dump_pa_source"
-#endif
-
 static void source_free(pa_object *o);
 
 static void pa_source_volume_change_push(pa_source *s);
 static void pa_source_volume_change_flush(pa_source *s);
 
-#ifdef __TIZEN__
-static void __toggle_open_close_n_write_dump_source(pa_source *s, const pa_memchunk *target)
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+static void pa_source_write_pcm_dump(pa_source *s, pa_memchunk *chunk)
 {
+    char *dump_time = NULL, *dump_path_surfix = NULL;
+    const char *s_device_api_str, *card_name_str, *device_idx_str;
+    struct timeval now;
+    struct tm tm;
+    char datetime[7];
 
     /* open file for dump pcm */
-    if (s->core->dump_source && !s->dump_fp) {
-        char *dump_path = NULL, *dump_path_surfix = NULL;
-        const char *s_device_api_str;
-#ifdef PA_DUMP_SOURCE_FOR_EACH_SUSPEND
-        time_t t;
-        char datetime[12];
-
-        time(&t);
+    if (s->core->pcm_dump & PA_PCM_DUMP_PA_SOURCE && !s->pcm_dump_fp && s->state == PA_SOURCE_RUNNING &&
+        !(~s->core->pcm_dump_option & PA_PCM_DUMP_OPTION_MONITOR && s->monitor_of)) {
+        pa_gettimeofday(&now);
+        localtime_r(&now.tv_sec, &tm);
         memset(&datetime[0], 0x00, sizeof(datetime));
-        strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", localtime(&t));
-#endif
+        strftime(&datetime[0], sizeof(datetime), "%H%M%S", &tm);
+        dump_time = pa_sprintf_malloc("%s.%03ld", &datetime[0], now.tv_usec / 1000);
 
         if ((s_device_api_str = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_API))) {
             if (pa_streq(s_device_api_str, "alsa")) {
-                const char *card_idx_str, *device_idx_str;
-                uint32_t card_idx = 0, device_idx = 0;
-
-                if ((card_idx_str = pa_proplist_gets(s->proplist, "alsa.card")))
-                    pa_atou(card_idx_str, &card_idx);
-                if ((device_idx_str = pa_proplist_gets(s->proplist, "alsa.device")))
-                    pa_atou(device_idx_str, &device_idx);
-                dump_path_surfix = pa_sprintf_malloc("alsa_%d_%d.pcm", card_idx, device_idx);
-            } else if (pa_streq(s_device_api_str, "bluez")) {
-                dump_path_surfix = pa_sprintf_malloc("bluez.pcm");
+                card_name_str = pa_proplist_gets(s->proplist, "alsa.card_name");
+                device_idx_str = pa_proplist_gets(s->proplist, "alsa.device");
+                dump_path_surfix = pa_sprintf_malloc("%s.%s%s", pa_strnull(card_name_str), pa_strnull(device_idx_str), s->monitor_of ? ".monitor" : "");
+            } else {
+                dump_path_surfix = pa_sprintf_malloc("%s%s", s_device_api_str, s->monitor_of ? ".monitor" : "");
             }
+        } else {
+            dump_path_surfix = pa_sprintf_malloc("%s", s->name);
         }
-        if (!dump_path_surfix) {
-            dump_path_surfix = pa_sprintf_malloc("idx_%d.pcm", s->index);
-        }
-
-#ifdef PA_DUMP_SOURCE_FOR_EACH_SUSPEND
-        dump_path = pa_sprintf_malloc("%s_%s_%s", PA_DUMP_SOURCE_PATH_PREFIX, &datetime[0], dump_path_surfix);
-#else
-        dump_path = pa_sprintf_malloc("%s_%s", PA_DUMP_SOURCE_PATH_PREFIX, dump_path_surfix);
-#endif
 
-        if (dump_path) {
-            s->dump_fp = fopen(dump_path, "w");
-            pa_log_info("pa_source dump started:%s", dump_path);
-            pa_xfree(dump_path);
+        s->dump_path = pa_sprintf_malloc("%s_%s_pa-src%d-%s_%dch_%d.raw", PA_PCM_DUMP_PATH_PREFIX, pa_strempty(dump_time),
+            s->index, pa_strempty(dump_path_surfix), s->sample_spec.channels, s->sample_spec.rate);
+        if (s->dump_path) {
+            s->pcm_dump_fp = fopen(s->dump_path, "w");
+            if (!s->pcm_dump_fp)
+                pa_log_warn("%s open failed", s->dump_path);
+            else
+                pa_log_info("%s opened", s->dump_path);
         }
-        if (dump_path_surfix)
-            pa_xfree(dump_path_surfix);
+        pa_xfree(dump_time);
+        pa_xfree(dump_path_surfix);
     /* close file for dump pcm when config is changed */
-    } else if (!s->core->dump_source && s->dump_fp) {
-        fclose(s->dump_fp);
-        s->dump_fp = NULL;
+    } else if (~s->core->pcm_dump & PA_PCM_DUMP_PA_SOURCE && s->pcm_dump_fp) {
+        fclose(s->pcm_dump_fp);
+        pa_log_info("%s closed", s->dump_path);
+        pa_xfree(s->dump_path);
+        s->pcm_dump_fp = NULL;
     }
 
     /* dump pcm */
-    if (s->dump_fp) {
-        void *ptr;
-
-        ptr = pa_memblock_acquire(target->memblock);
+    if (s->pcm_dump_fp) {
+        void *ptr = NULL;
 
-        fwrite((uint8_t*) ptr + target->index, 1, target->length, s->dump_fp);
+        ptr = pa_memblock_acquire(chunk->memblock);
+        if (ptr)
+            fwrite((uint8_t *)ptr + chunk->index, 1, chunk->length, s->pcm_dump_fp);
+        else
+            pa_log_warn("pa_memblock_acquire is failed. ptr is NULL");
 
-        pa_memblock_release(target->memblock);
+        pa_memblock_release(chunk->memblock);
     }
 }
 #endif
@@ -381,8 +373,9 @@ pa_source* pa_source_new(
 
     s->save_volume = data->save_volume;
     s->save_muted = data->save_muted;
-#ifdef __TIZEN__
-    s->dump_fp = NULL;
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    s->pcm_dump_fp = NULL;
+    s->dump_path = NULL;
 #endif
 
     pa_silence_memchunk_get(
@@ -463,6 +456,17 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {
 
     s->state = state;
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    /* close file for dump pcm */
+    if (s->pcm_dump_fp && (s->core->pcm_dump_option & PA_PCM_DUMP_OPTION_SEPARATED) &&
+        state == PA_SOURCE_IDLE && original_state == PA_SOURCE_RUNNING) {
+        fclose(s->pcm_dump_fp);
+        pa_log_info("%s closed", s->dump_path);
+        pa_xfree(s->dump_path);
+        s->pcm_dump_fp = NULL;
+    }
+#endif
+
     if (state != PA_SOURCE_UNLINKED) { /* if we enter UNLINKED state pa_source_unlink() will fire the appropriate events */
         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s);
         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
@@ -760,11 +764,13 @@ static void source_free(pa_object *o) {
 
     if (s->ports)
         pa_hashmap_free(s->ports);
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
     /* close file for dump pcm */
-    if (s->dump_fp) {
-        fclose(s->dump_fp);
-        s->dump_fp = NULL;
+    if (s->pcm_dump_fp) {
+        fclose(s->pcm_dump_fp);
+        pa_log_info("%s closed", s->dump_path);
+        pa_xfree(s->dump_path);
+        s->pcm_dump_fp = NULL;
     }
 #endif
     pa_xfree(s);
@@ -890,17 +896,6 @@ int pa_source_suspend(pa_source *s, bool suspend, pa_suspend_cause_t cause) {
     pa_log_debug("Suspend cause of source %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
 
 #ifdef __TIZEN__
-#ifdef PA_DUMP_SOURCE_FOR_EACH_SUSPEND
-    /* close file for dump pcm */
-    if (suspend && s->dump_in_fp) {
-        fclose(s->dump_in_fp);
-        s->dump_in_fp = NULL;
-    }
-    if (suspend && s->dump_out_fp) {
-        fclose(s->dump_out_fp);
-        s->dump_out_fp = NULL;
-    }
-#endif
     if (s->suspend_cause) {
         ret = source_set_state(s, PA_SOURCE_SUSPENDED);
         if (ret == 0 && cause == PA_SUSPEND_INTERNAL) {
@@ -1014,10 +1009,10 @@ void pa_source_process_rewind(pa_source *s, size_t nbytes) {
 
     pa_log_debug("Processing rewind...");
 
-#ifdef __TIZEN__
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
     /* rewind pcm */
-    if (s->dump_fp) {
-        fseeko(s->dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
+    if (s->pcm_dump_fp) {
+        fseeko(s->pcm_dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
     }
 #endif
 
@@ -1040,8 +1035,8 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) {
     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
         return;
 
-#ifdef __TIZEN__
-    __toggle_open_close_n_write_dump_source(s, chunk);
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    pa_source_write_pcm_dump(s, (pa_memchunk *)chunk);
 #endif
 
     if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
@@ -1086,8 +1081,8 @@ void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *
     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
         return;
 
-#ifdef __TIZEN__
-    __toggle_open_close_n_write_dump_source(s, chunk);
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    pa_source_write_pcm_dump(s, (pa_memchunk *)chunk);
 #endif
 
     if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
index 28bfbf4..94f422f 100644 (file)
@@ -247,9 +247,10 @@ struct pa_source {
 
 #ifdef __TIZEN__
     pa_hashmap *device_types;
-    FILE *dump_fp;
     void* device_item;
     bool use_internal_codec;
+    FILE *pcm_dump_fp;
+    char *dump_path;
 #endif
 
     void *userdata;
index e25cf72..e97ae6c 100644 (file)
 
 #include <sndfile.h>
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+#include <vconf.h>
+#include <pulsecore/core.h>
+#endif
+
 #include <pulse/pulseaudio.h>
 #include <pulse/ext-device-restore.h>
 
@@ -97,6 +102,11 @@ static int actions = 0;
 
 static bool nl = false;
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+static uint32_t pcm_dump_type = 0, pcm_dump_vconf = 0, pcm_dump_option = 0;
+static int pcm_dump_type_enable, pcm_dump_option_enable;
+#endif
+
 static enum {
     NONE,
     EXIT,
@@ -127,7 +137,11 @@ static enum {
     SET_SOURCE_OUTPUT_MUTE,
     SET_SINK_FORMATS,
     SET_PORT_LATENCY_OFFSET,
-    SUBSCRIBE
+    SUBSCRIBE,
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    SET_PCM_DUMP,
+    SET_PCM_DUMP_OPTION,
+#endif
 } action = NONE;
 
 static void quit(int ret) {
@@ -1426,6 +1440,16 @@ static void context_state_callback(pa_context *c, void *userdata) {
                                              NULL);
                     break;
 
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+                case SET_PCM_DUMP:
+                    o = pa_context_set_pcm_dump(c, pcm_dump_type, pcm_dump_type_enable, simple_callback, NULL);
+                    break;
+
+                case SET_PCM_DUMP_OPTION:
+                    o = pa_context_set_pcm_dump_option(c, pcm_dump_option, pcm_dump_option_enable, simple_callback, NULL);
+                    break;
+#endif
+
                 default:
                     pa_assert_not_reached();
             }
@@ -1557,7 +1581,10 @@ static void help(const char *argv0) {
     printf("%s %s %s\n",    argv0, _("[options]"), "subscribe");
     printf(_("\nThe special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@\n"
              "can be used to specify the default sink, source and monitor.\n"));
-
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-pcm-dump", _("[TYPE] 1|0"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-pcm-dump-option", _("OPTION 1|0"));
+#endif
     printf(_("\n"
              "  -h, --help                            Show this help\n"
              "      --version                         Show version\n\n"
@@ -2027,6 +2054,112 @@ int main(int argc, char *argv[]) {
             ret = 0;
             goto quit;
         }
+#if defined (__TIZEN__) && defined (ENABLE_PCM_DUMP)
+        else if (pa_streq(argv[optind], "set-pcm-dump")) {
+            int i, b;
+
+            action = SET_PCM_DUMP;
+
+            if (argc == optind+2) {
+                pcm_dump_vconf |= PA_PCM_DUMP_GST_DECODER_OUT | PA_PCM_DUMP_GST_RESAMPLER_IN | PA_PCM_DUMP_GST_RESAMPLER_OUT |
+                                  PA_PCM_DUMP_GST_AUDIO_SINK_IN | PA_PCM_DUMP_PA_STREAM_WRITE;
+                pcm_dump_type |= PA_PCM_DUMP_PA_SINK_INPUT | PA_PCM_DUMP_PA_SINK;
+                pcm_dump_vconf |= PA_PCM_DUMP_PA_STREAM_READ | PA_PCM_DUMP_GST_AUDIO_SRC_OUT | PA_PCM_DUMP_GST_ENCODER_IN;
+                pcm_dump_type |= PA_PCM_DUMP_PA_SOURCE | PA_PCM_DUMP_PA_SOURCE_OUTPUT;
+            } else {
+                for (i = optind+1; i < argc-1; i++) {
+                    if (pa_streq(argv[optind+1], "playback")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_GST_DECODER_OUT | PA_PCM_DUMP_GST_RESAMPLER_IN | PA_PCM_DUMP_GST_RESAMPLER_OUT |
+                                          PA_PCM_DUMP_GST_AUDIO_SINK_IN | PA_PCM_DUMP_PA_STREAM_WRITE;
+                        pcm_dump_type |= PA_PCM_DUMP_PA_SINK_INPUT | PA_PCM_DUMP_PA_SINK;
+                    } else if (pa_streq(argv[i], "decoder-out")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_GST_DECODER_OUT;
+                    } else if (pa_streq(argv[i], "resampler-in")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_GST_RESAMPLER_IN;
+                    } else if (pa_streq(argv[i], "resampler-out")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_GST_RESAMPLER_OUT;
+                    } else if (pa_streq(argv[i], "gst-audio-sink")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_GST_AUDIO_SINK_IN;
+                    } else if (pa_streq(argv[i], "stream-write")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_PA_STREAM_WRITE;
+                    } else if (pa_streq(argv[i], "sink-input")) {
+                        pcm_dump_type |= PA_PCM_DUMP_PA_SINK_INPUT;
+                    } else if (pa_streq(argv[i], "sink")) {
+                        pcm_dump_type |= PA_PCM_DUMP_PA_SINK;
+                    } else if (pa_streq(argv[i], "capture")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_PA_STREAM_READ | PA_PCM_DUMP_GST_AUDIO_SRC_OUT | PA_PCM_DUMP_GST_ENCODER_IN;
+                        pcm_dump_type |= PA_PCM_DUMP_PA_SOURCE | PA_PCM_DUMP_PA_SOURCE_OUTPUT;
+                    } else if (pa_streq(argv[i], "source")) {
+                        pcm_dump_type |= PA_PCM_DUMP_PA_SOURCE;
+                    } else if (pa_streq(argv[i], "source-output")) {
+                        pcm_dump_type |= PA_PCM_DUMP_PA_SOURCE_OUTPUT;
+                    } else if (pa_streq(argv[i], "stream-read")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_PA_STREAM_READ;
+                    } else if (pa_streq(argv[i], "gst-audio-src")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_GST_AUDIO_SRC_OUT;
+                    } else if (pa_streq(argv[i], "encoder-in")) {
+                        pcm_dump_vconf |= PA_PCM_DUMP_GST_ENCODER_IN;
+                    } else {
+                        pa_log(_("Specify nothing, or one of: %s"), "playback, decoder-out, resampler-in, resampler-out, "
+                            "sink-input, sink, capture, source, source-output, stream-read, gst-audio-src, encoder-in");
+                    }
+                }
+            }
+
+            if ((b = pa_parse_boolean(argv[argc-1])) < 0) {
+                pa_log(_("Invalid dump specification."));
+                goto quit;
+            }
+
+            pcm_dump_type_enable = !!b;
+
+            if (pcm_dump_vconf > 0) {
+                int pcm_dump_vconf_old = 0, pcm_dump_vconf_new = 0;
+
+                if(vconf_get_int(PA_PCM_DUMP_VCONF_KEY, &pcm_dump_vconf_old)) {
+                    pa_log_warn("vconf_get_int for %s failed", PA_PCM_DUMP_VCONF_KEY);
+                }
+                if (pcm_dump_type_enable)
+                    pcm_dump_vconf_new = pcm_dump_vconf_old | pcm_dump_vconf;
+                else
+                    pcm_dump_vconf_new = pcm_dump_vconf_old & ~pcm_dump_vconf;
+                if (pcm_dump_vconf_new != pcm_dump_vconf_old) {
+                    if (vconf_set_int(PA_PCM_DUMP_VCONF_KEY, pcm_dump_vconf_new)) {
+                        pa_log_warn("vconf_set_int for %s failed of %d", PA_PCM_DUMP_VCONF_KEY, vconf_get_ext_errno());
+                    }
+                }
+            }
+
+            if (!pcm_dump_type)
+                goto quit;
+        } else if (pa_streq(argv[optind], "set-pcm-dump-option")) {
+            int b;
+
+            action = SET_PCM_DUMP_OPTION;
+
+            if (argc != optind+3) {
+                pa_log(_("You have to specify a pcm dump option name & value"));
+                goto quit;
+            }
+
+            if (pa_streq(argv[optind+1], "separated")) {
+                pcm_dump_option = PA_PCM_DUMP_OPTION_SEPARATED;
+            } else if (pa_streq(argv[optind+1], "monitor")) {
+                pcm_dump_option = PA_PCM_DUMP_OPTION_MONITOR;
+            } else {
+                pa_log(_("Specify one of: %s"), "separated");
+            }
+
+            if ((b = pa_parse_boolean(argv[argc-1])) < 0) {
+                pa_log(_("Invalid dump option specification."));
+                goto quit;
+            }
+
+            pcm_dump_option_enable = !!b;
+        }
+
+#endif
+
     }
 
     if (action == NONE) {