Source tree moved to mafw-gst-subtitles-renderer directory.
[mafwsubrenderer] / mafw-gst-subtitles-renderer / libmafw-gst-renderer / mafw-gst-renderer-worker-volume.c
diff --git a/mafw-gst-subtitles-renderer/libmafw-gst-renderer/mafw-gst-renderer-worker-volume.c b/mafw-gst-subtitles-renderer/libmafw-gst-renderer/mafw-gst-renderer-worker-volume.c
new file mode 100644 (file)
index 0000000..31aa22b
--- /dev/null
@@ -0,0 +1,710 @@
+/*
+ * This file is a part of MAFW
+ *
+ * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME
+
+#include <pulse/pulseaudio.h>
+#include <pulse/glib-mainloop.h>
+#include <pulse/ext-stream-restore.h>
+#include <string.h>
+
+#include "mafw-gst-renderer-worker-volume.h"
+#include "config.h"
+
+#undef  G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-worker-volume"
+
+#define MAFW_GST_RENDERER_WORKER_VOLUME_SERVER NULL
+
+#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PROPERTY "PULSE_PROP_media.role"
+#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX "sink-input-by-media-role:"
+#define MAFW_GST_RENDERER_WORKER_VOLUME_ROLE "x-maemo"
+
+#define MAFW_GST_RENDERER_WORKER_SET_TIMEOUT 200
+
+
+struct _MafwGstRendererWorkerVolume {
+       pa_glib_mainloop *mainloop;
+       pa_context *context;
+       gdouble pulse_volume;
+       gboolean pulse_mute;
+       MafwGstRendererWorkerVolumeChangedCb cb;
+       gpointer user_data;
+       MafwGstRendererWorkerVolumeMuteCb mute_cb;
+       gpointer mute_user_data;
+       gdouble current_volume;
+       gboolean current_mute;
+       gboolean pending_operation;
+       gdouble pending_operation_volume;
+       gboolean pending_operation_mute;
+       guint change_request_id;
+       pa_operation *pa_operation;
+};
+
+typedef struct {
+       MafwGstRendererWorkerVolume *wvolume;
+       MafwGstRendererWorkerVolumeInitCb cb;
+       gpointer user_data;
+} InitCbClosure;
+
+#define _pa_volume_to_per_one(volume) \
+       ((guint) ((((gdouble)(volume) / (gdouble) PA_VOLUME_NORM) + \
+                  (gdouble) 0.005) * (gdouble) 100.0) / (gdouble) 100.0)
+#define _pa_volume_from_per_one(volume) \
+       ((pa_volume_t)((gdouble)(volume) * (gdouble) PA_VOLUME_NORM))
+
+#define _pa_operation_running(wvolume) \
+       (wvolume->pa_operation != NULL && \
+        pa_operation_get_state(wvolume->pa_operation) == PA_OPERATION_RUNNING)
+
+static void _state_cb_init(pa_context *c, void *data);
+
+
+static gchar *_get_client_name(void) {
+       gchar buf[PATH_MAX];
+       gchar *name = NULL;
+
+       if (pa_get_binary_name(buf, sizeof(buf)))
+               name = g_strdup_printf("mafw-gst-renderer[%s]", buf);
+       else
+               name = g_strdup("mafw-gst-renderer");
+
+       return name;
+}
+
+static void _ext_stream_restore_read_cb(pa_context *c,
+                                       const pa_ext_stream_restore2_info *i,
+                                       int eol,
+                                       void *userdata)
+{
+       MafwGstRendererWorkerVolume *wvolume = userdata;
+       gdouble volume;
+       gboolean mute;
+
+       if (eol < 0) {
+               g_critical("eol parameter should not be < 1. "
+                          "Discarding volume event");
+               return;
+       }
+
+       if (i == NULL ||
+           strcmp(i->name, MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
+                  MAFW_GST_RENDERER_WORKER_VOLUME_ROLE) != 0) {
+               return;
+       }
+
+       volume = _pa_volume_to_per_one(pa_cvolume_max(&i->volume));
+       mute = i->mute != 0 ? TRUE : FALSE;
+
+       if (_pa_operation_running(wvolume) ||
+           (wvolume->pending_operation &&
+            (wvolume->pending_operation_volume != volume
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+               || wvolume->pending_operation_mute != mute
+#endif
+       ))) {
+               g_debug("volume notification, but operation running, ignoring");
+               return;
+       }
+
+       wvolume->pulse_volume = volume;
+       wvolume->pulse_mute = mute;
+
+       /* EMIT VOLUME */
+       g_debug("ext stream volume is %lf (mute: %d) for role %s in device %s",
+               wvolume->pulse_volume, wvolume->pulse_mute, i->name, i->device);
+       if (!wvolume->pending_operation &&
+           wvolume->pulse_volume != wvolume->current_volume) {
+               wvolume->current_volume = wvolume->pulse_volume;
+               if (wvolume->cb != NULL) {
+                       g_debug("signalling volume");
+                       wvolume->cb(wvolume, wvolume->current_volume,
+                                   wvolume->user_data);
+               }
+       }
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+       if (!wvolume->pending_operation &&
+           wvolume->pulse_mute != wvolume->current_mute) {
+               wvolume->current_mute = wvolume->pulse_mute;
+               if (wvolume->mute_cb != NULL) {
+                       g_debug("signalling mute");
+                       wvolume->mute_cb(wvolume, wvolume->current_mute,
+                                        wvolume->mute_user_data);
+               }
+       }
+#endif
+
+       wvolume->pending_operation = FALSE;
+}
+
+static void _destroy_context(MafwGstRendererWorkerVolume *wvolume)
+{
+       if (wvolume->pa_operation != NULL) {
+               if (pa_operation_get_state(wvolume->pa_operation) ==
+                   PA_OPERATION_RUNNING) {
+                       pa_operation_cancel(wvolume->pa_operation);
+               }
+               pa_operation_unref(wvolume->pa_operation);
+               wvolume->pa_operation = NULL;
+       }
+       pa_context_unref(wvolume->context);
+}
+
+static InitCbClosure *_init_cb_closure_new(MafwGstRendererWorkerVolume *wvolume,
+                                          MafwGstRendererWorkerVolumeInitCb cb,
+                                          gpointer user_data)
+{
+       InitCbClosure *closure;
+
+       closure = g_new(InitCbClosure, 1);
+       closure->wvolume = wvolume;
+       closure->cb = cb;
+       closure->user_data = user_data;
+
+       return closure;
+}
+
+static void _connect(gpointer user_data)
+{
+       gchar *name = NULL;
+       pa_mainloop_api *api = NULL;
+       InitCbClosure *closure = user_data;
+       MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
+
+       name = _get_client_name();
+
+       /* get the mainloop api and create a context */
+       api = pa_glib_mainloop_get_api(wvolume->mainloop);
+       wvolume->context = pa_context_new(api, name);
+       g_assert(wvolume->context != NULL);
+
+       /* register some essential callbacks */
+       pa_context_set_state_callback(wvolume->context, _state_cb_init,
+                                     closure);
+
+       g_debug("connecting to pulse");
+
+       g_assert(pa_context_connect(wvolume->context,
+                                   MAFW_GST_RENDERER_WORKER_VOLUME_SERVER,
+                                   PA_CONTEXT_NOAUTOSPAWN | PA_CONTEXT_NOFAIL,
+                                   NULL) >= 0);
+       g_free(name);
+}
+
+static gboolean _reconnect(gpointer user_data)
+{
+       InitCbClosure *closure = user_data;
+       MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
+
+       g_warning("got disconnected from pulse, reconnecting");
+       _destroy_context(wvolume);
+       _connect(user_data);
+
+       return FALSE;
+}
+
+static void
+_state_cb(pa_context *c, void *data)
+{
+       MafwGstRendererWorkerVolume *wvolume = data;
+       pa_context_state_t state;
+
+       state = pa_context_get_state(c);
+
+       switch (state) {
+       case PA_CONTEXT_TERMINATED:
+       case PA_CONTEXT_FAILED:
+       {
+               InitCbClosure *closure;
+
+               closure = _init_cb_closure_new(wvolume, NULL, NULL);
+               g_idle_add(_reconnect, closure);
+               break;
+       }
+       case PA_CONTEXT_READY: {
+               pa_operation *o;
+
+               o = pa_ext_stream_restore2_read(c, _ext_stream_restore_read_cb,
+                                              wvolume);
+               g_assert(o != NULL);
+               pa_operation_unref(o);
+
+               break;
+       }
+       default:
+               break;
+       }
+}
+
+static void _ext_stream_restore_read_cb_init(pa_context *c,
+                                            const pa_ext_stream_restore2_info *i,
+                                            int eol,
+                                            void *userdata)
+{
+       InitCbClosure *closure = userdata;
+
+       if (eol < 0) {
+               g_critical("eol parameter should not be < 1");
+       }
+
+       if (i == NULL ||
+           strcmp(i->name, MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
+                  MAFW_GST_RENDERER_WORKER_VOLUME_ROLE) != 0)
+               return;
+
+       closure->wvolume->pulse_volume =
+               _pa_volume_to_per_one(pa_cvolume_max(&i->volume));
+       closure->wvolume->pulse_mute = i->mute != 0 ? TRUE : FALSE;
+       closure->wvolume->current_volume = closure->wvolume->pulse_volume;
+       closure->wvolume->current_mute = closure->wvolume->pulse_mute;
+
+       /* NOT EMIT VOLUME, BUT DEBUG */
+       g_debug("ext stream volume is %lf (mute: %d) for role %s in device %s",
+               closure->wvolume->pulse_volume, i->mute, i->name, i->device);
+
+       if (closure->cb != NULL) {
+               g_debug("initialized: returning volume manager");
+               closure->cb(closure->wvolume, closure->user_data);
+       } else {
+               if (closure->wvolume->cb != NULL) {
+                       g_debug("signalling volume after reconnection");
+                       closure->wvolume->cb(closure->wvolume,
+                                            closure->wvolume->current_volume,
+                                            closure->wvolume->user_data);
+               }
+               if (closure->wvolume->mute_cb != NULL) {
+                       g_debug("signalling mute after reconnection");
+                       closure->wvolume->mute_cb(closure->wvolume,
+                                                 closure->wvolume->
+                                                 current_mute,
+                                                 closure->wvolume->
+                                                 mute_user_data);
+               }
+       }
+
+       pa_context_set_state_callback(closure->wvolume->context, _state_cb,
+                                     closure->wvolume);
+
+       g_free(closure);
+}
+
+static void _ext_stream_restore_subscribe_cb(pa_context *c, void *userdata)
+{
+    pa_operation *o;
+
+    o = pa_ext_stream_restore2_read(c, _ext_stream_restore_read_cb, userdata);
+    g_assert(o != NULL);
+    pa_operation_unref(o);
+}
+
+static void
+_state_cb_init(pa_context *c, void *data)
+{
+       InitCbClosure *closure = data;
+       MafwGstRendererWorkerVolume *wvolume = closure->wvolume;
+       pa_context_state_t state;
+
+       state = pa_context_get_state(c);
+
+       g_debug("state: %d", state);
+
+       switch (state) {
+       case PA_CONTEXT_TERMINATED:
+       case PA_CONTEXT_FAILED:
+               g_critical("Connection to pulse failed, reconnection in 1 "
+                          "second");
+               g_timeout_add_seconds(1, _reconnect, closure);
+               break;
+       case PA_CONTEXT_READY: {
+               pa_operation *o;
+
+               g_debug("PA_CONTEXT_READY");
+
+               o = pa_ext_stream_restore2_read(c,
+                                              _ext_stream_restore_read_cb_init,
+                                              closure);
+               g_assert(o != NULL);
+               pa_operation_unref(o);
+
+               pa_ext_stream_restore_set_subscribe_cb(
+                       c, _ext_stream_restore_subscribe_cb, wvolume);
+
+               o = pa_ext_stream_restore_subscribe(c, 1, NULL, NULL);
+               g_assert(o != NULL);
+               pa_operation_unref(o);
+
+               break;
+       }
+       default:
+               break;
+       }
+}
+
+static gboolean _destroy_idle(gpointer data)
+{
+       MafwGstRendererWorkerVolume *wvolume = data;
+
+       g_debug("destroying");
+
+       _destroy_context(wvolume);
+       pa_glib_mainloop_free(wvolume->mainloop);
+       g_free(wvolume);
+
+       return FALSE;
+}
+
+static void
+_state_cb_destroy(pa_context *c, void *data)
+{
+       pa_context_state_t state;
+
+       state = pa_context_get_state(c);
+
+       switch (state) {
+       case PA_CONTEXT_TERMINATED:
+               g_idle_add(_destroy_idle, data);
+               break;
+       case PA_CONTEXT_FAILED:
+               g_error("Unexpected problem in volume management");
+               break;
+       default:
+               break;
+       }
+}
+
+static void _success_cb(pa_context *c, int success, void *userdata)
+{
+       if (success == 0) {
+               g_critical("Setting volume to pulse operation failed");
+       }
+}
+
+static void _remove_set_timeout(MafwGstRendererWorkerVolume *wvolume)
+{
+       if (wvolume->change_request_id != 0) {
+               g_source_remove(wvolume->change_request_id);
+       }
+       wvolume->change_request_id = 0;
+}
+
+static gboolean _set_timeout(gpointer data)
+{
+       pa_ext_stream_restore2_info info;
+        pa_ext_stream_restore2_info *infos[1];
+       MafwGstRendererWorkerVolume *wvolume = data;
+
+       if (wvolume->pending_operation) {
+               g_debug("setting volume ignored as there is still a pending "
+                       "operation. Waiting till next iteration");
+       } else if (wvolume->pulse_volume != wvolume->current_volume
+#ifdef MAFW_GST_RENDERER_ENABLE_MUTE
+                       || wvolume->pulse_mute != wvolume->current_mute
+#endif
+                       ) {
+
+               info.name = MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PREFIX
+                       MAFW_GST_RENDERER_WORKER_VOLUME_ROLE;
+               info.channel_map.channels = 1;
+               info.channel_map.map[0] = PA_CHANNEL_POSITION_MONO;
+               info.device = NULL;
+               info.volume_is_absolute = TRUE;
+               infos[0] = &info;
+
+               info.mute = wvolume->current_mute;
+               pa_cvolume_init(&info.volume);
+               pa_cvolume_set(&info.volume, info.channel_map.channels,
+                              _pa_volume_from_per_one(wvolume->
+                                                      current_volume));
+
+               g_debug("setting volume to %lf and mute to %d",
+                       wvolume->current_volume, wvolume->current_mute);
+
+               if (wvolume->pa_operation != NULL) {
+                       pa_operation_unref(wvolume->pa_operation);
+               }
+
+               wvolume->pending_operation = TRUE;
+               wvolume->pending_operation_volume = wvolume->current_volume;
+               wvolume->pending_operation_mute = wvolume->current_mute;
+
+               wvolume->pa_operation = pa_ext_stream_restore2_write(
+                       wvolume->context,
+                       PA_UPDATE_REPLACE,
+                       (const pa_ext_stream_restore2_info*
+                        const *)infos,
+                       1, TRUE, _success_cb, wvolume);
+
+               if (wvolume->pa_operation == NULL) {
+                       g_critical("NULL operation when writing volume to "
+                                  "pulse");
+                       _remove_set_timeout(wvolume);
+               }
+       } else {
+               g_debug("removing volume timeout");
+               _remove_set_timeout(wvolume);
+       }
+
+       return wvolume->change_request_id != 0;
+}
+
+void mafw_gst_renderer_worker_volume_init(GMainContext *main_context,
+                                         MafwGstRendererWorkerVolumeInitCb cb,
+                                         gpointer user_data,
+                                         MafwGstRendererWorkerVolumeChangedCb
+                                         changed_cb,
+                                         gpointer changed_user_data,
+                                         MafwGstRendererWorkerVolumeMuteCb
+                                         mute_cb, gpointer mute_user_data)
+{
+       MafwGstRendererWorkerVolume *wvolume = NULL;
+       InitCbClosure *closure;
+
+       g_return_if_fail(cb != NULL);
+
+       g_assert(g_setenv(MAFW_GST_RENDERER_WORKER_VOLUME_ROLE_PROPERTY,
+                         MAFW_GST_RENDERER_WORKER_VOLUME_ROLE, FALSE));
+
+       g_debug("initializing volume manager");
+
+       wvolume = g_new0(MafwGstRendererWorkerVolume, 1);
+
+       wvolume->pulse_volume = 1.0;
+       wvolume->pulse_mute = FALSE;
+       wvolume->cb = changed_cb;
+       wvolume->user_data = changed_user_data;
+       wvolume->mute_cb = mute_cb;
+       wvolume->mute_user_data = mute_user_data;
+
+       wvolume->mainloop = pa_glib_mainloop_new(main_context);
+       g_assert(wvolume->mainloop != NULL);
+
+       closure = _init_cb_closure_new(wvolume, cb, user_data);
+       _connect(closure);
+}
+
+void mafw_gst_renderer_worker_volume_set(MafwGstRendererWorkerVolume *wvolume,
+                                        gdouble volume, gboolean mute)
+{
+       gboolean signal_volume, signal_mute;
+
+       g_return_if_fail(wvolume != NULL);
+       g_return_if_fail(pa_context_get_state(wvolume->context) ==
+                        PA_CONTEXT_READY);
+
+#ifndef MAFW_GST_RENDERER_ENABLE_MUTE
+       mute = FALSE;
+#endif
+
+       signal_volume = wvolume->current_volume != volume &&
+               wvolume->cb != NULL;
+       signal_mute = wvolume->current_mute != mute && wvolume->mute_cb != NULL;
+
+       wvolume->current_volume = volume;
+       wvolume->current_mute = mute;
+
+       g_debug("volume set: %lf (mute %d)", volume, mute);
+
+       if (signal_volume) {
+               g_debug("signalling volume");
+               wvolume->cb(wvolume, volume, wvolume->user_data);
+       }
+
+       if (signal_mute) {
+               g_debug("signalling mute");
+               wvolume->mute_cb(wvolume, mute, wvolume->mute_user_data);
+       }
+
+       if ((signal_mute || signal_volume) && wvolume->change_request_id == 0) {
+               wvolume->change_request_id =
+                       g_timeout_add(MAFW_GST_RENDERER_WORKER_SET_TIMEOUT,
+                                     _set_timeout, wvolume);
+
+               _set_timeout(wvolume);
+       }
+}
+
+gdouble mafw_gst_renderer_worker_volume_get(
+       MafwGstRendererWorkerVolume *wvolume)
+{
+       g_return_val_if_fail(wvolume != NULL, 0.0);
+
+       g_debug("getting volume; %lf", wvolume->current_volume);
+
+       return wvolume->current_volume;
+}
+
+gboolean mafw_gst_renderer_worker_volume_is_muted(
+       MafwGstRendererWorkerVolume *wvolume)
+{
+       g_return_val_if_fail(wvolume != NULL, FALSE);
+
+       g_debug("getting mute; %d", wvolume->current_mute);
+
+       return wvolume->current_mute;
+}
+
+void mafw_gst_renderer_worker_volume_destroy(
+       MafwGstRendererWorkerVolume *wvolume)
+{
+       g_return_if_fail(wvolume != NULL);
+
+       g_debug("disconnecting");
+
+       pa_ext_stream_restore_set_subscribe_cb(wvolume->context, NULL, NULL);
+       pa_context_set_state_callback(wvolume->context, _state_cb_destroy,
+                                     wvolume);
+       pa_context_disconnect(wvolume->context);
+}
+
+
+
+#else
+
+
+#include "mafw-gst-renderer-worker-volume.h"
+
+#undef  G_LOG_DOMAIN
+#define G_LOG_DOMAIN "mafw-gst-renderer-worker-volume-fake"
+
+struct _MafwGstRendererWorkerVolume {
+       MafwGstRendererWorkerVolumeChangedCb cb;
+       gpointer user_data;
+       MafwGstRendererWorkerVolumeMuteCb mute_cb;
+       gpointer mute_user_data;
+       gdouble current_volume;
+       gboolean current_mute;
+};
+
+typedef struct {
+       MafwGstRendererWorkerVolume *wvolume;
+       MafwGstRendererWorkerVolumeInitCb cb;
+       gpointer user_data;
+} InitCbClosure;
+
+static gboolean _init_cb_closure(gpointer user_data)
+{
+       InitCbClosure *closure = user_data;
+
+       if (closure->cb != NULL) {
+               closure->cb(closure->wvolume, closure->user_data);
+       }
+       g_free(closure);
+
+       return FALSE;
+}
+
+void mafw_gst_renderer_worker_volume_init(GMainContext *main_context,
+                                         MafwGstRendererWorkerVolumeInitCb cb,
+                                         gpointer user_data,
+                                         MafwGstRendererWorkerVolumeChangedCb
+                                         changed_cb,
+                                         gpointer changed_user_data,
+                                         MafwGstRendererWorkerVolumeMuteCb
+                                         mute_cb, gpointer mute_user_data)
+{
+       MafwGstRendererWorkerVolume *wvolume = NULL;
+       InitCbClosure *closure;
+
+       g_return_if_fail(cb != NULL);
+
+       g_debug("initializing volume manager");
+
+       wvolume = g_new0(MafwGstRendererWorkerVolume, 1);
+
+       wvolume->cb = changed_cb;
+       wvolume->user_data = changed_user_data;
+       wvolume->mute_cb = mute_cb;
+       wvolume->mute_user_data = mute_user_data;
+       wvolume->current_volume = 0.485;
+
+       closure = g_new0(InitCbClosure, 1);
+       closure->wvolume = wvolume;
+       closure->cb = cb;
+       closure->user_data = user_data;
+       g_idle_add(_init_cb_closure, closure);
+}
+
+void mafw_gst_renderer_worker_volume_set(MafwGstRendererWorkerVolume *wvolume,
+                                        gdouble volume, gboolean mute)
+{
+       gboolean signal_volume, signal_mute;
+
+       g_return_if_fail(wvolume != NULL);
+
+#ifndef MAFW_GST_RENDERER_ENABLE_MUTE
+       mute = FALSE;
+#endif
+
+       signal_volume = wvolume->current_volume != volume &&
+               wvolume->cb != NULL;
+       signal_mute = wvolume->current_mute != mute && wvolume->mute_cb != NULL;
+
+       wvolume->current_volume = volume;
+       wvolume->current_mute = mute;
+
+       g_debug("volume set: %lf (mute %d)", volume, mute);
+
+       if (signal_volume) {
+               g_debug("signalling volume");
+               wvolume->cb(wvolume, volume, wvolume->user_data);
+       }
+
+       if (signal_mute) {
+               g_debug("signalling mute");
+               wvolume->mute_cb(wvolume, mute, wvolume->mute_user_data);
+       }
+}
+
+gdouble mafw_gst_renderer_worker_volume_get(
+       MafwGstRendererWorkerVolume *wvolume)
+{
+       g_return_val_if_fail(wvolume != NULL, 0.0);
+
+       g_debug("getting volume; %lf", wvolume->current_volume);
+
+       return wvolume->current_volume;
+}
+
+gboolean mafw_gst_renderer_worker_volume_is_muted(
+       MafwGstRendererWorkerVolume *wvolume)
+{
+       g_return_val_if_fail(wvolume != NULL, FALSE);
+
+       g_debug("getting mute; %d", wvolume->current_mute);
+
+       return wvolume->current_mute;
+}
+
+void mafw_gst_renderer_worker_volume_destroy(
+       MafwGstRendererWorkerVolume *wvolume)
+{
+       g_return_if_fail(wvolume != NULL);
+
+       g_free(wvolume);
+}
+
+#endif