aboutsummaryrefslogtreecommitdiffstats
path: root/src/output
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/output/httpd_client.h3
-rw-r--r--src/output/pulse_output_plugin.h4
-rw-r--r--src/output/shout_output_plugin.c71
-rw-r--r--src/output_all.c19
-rw-r--r--src/output_all.h7
-rw-r--r--src/output_error.h35
-rw-r--r--src/output_init.c1
-rw-r--r--src/output_internal.h7
-rw-r--r--src/output_plugin.h7
-rw-r--r--src/output_thread.c2
10 files changed, 111 insertions, 45 deletions
diff --git a/src/output/httpd_client.h b/src/output/httpd_client.h
index 739163f42..f0df829db 100644
--- a/src/output/httpd_client.h
+++ b/src/output/httpd_client.h
@@ -20,9 +20,8 @@
#ifndef MPD_OUTPUT_HTTPD_CLIENT_H
#define MPD_OUTPUT_HTTPD_CLIENT_H
-#include <glib.h>
-
#include <stdbool.h>
+#include <stddef.h>
struct httpd_client;
struct httpd_output;
diff --git a/src/output/pulse_output_plugin.h b/src/output/pulse_output_plugin.h
index 02a51f27b..b285b5e4d 100644
--- a/src/output/pulse_output_plugin.h
+++ b/src/output/pulse_output_plugin.h
@@ -20,9 +20,9 @@
#ifndef MPD_PULSE_OUTPUT_PLUGIN_H
#define MPD_PULSE_OUTPUT_PLUGIN_H
-#include <stdbool.h>
+#include "gerror.h"
-#include <glib.h>
+#include <stdbool.h>
struct pulse_output;
struct pulse_mixer;
diff --git a/src/output/shout_output_plugin.c b/src/output/shout_output_plugin.c
index 56456a0ea..8f9df2ccf 100644
--- a/src/output/shout_output_plugin.c
+++ b/src/output/shout_output_plugin.c
@@ -105,15 +105,10 @@ static void free_shout_data(struct shout_data *sd)
} \
}
-static struct audio_output *
-my_shout_init_driver(const struct config_param *param,
- GError **error)
+static bool
+my_shout_configure(struct shout_data *sd, const struct config_param *param,
+ GError **error)
{
- struct shout_data *sd = new_shout_data();
- if (!ao_base_init(&sd->base, &shout_output_plugin, param, error)) {
- free_shout_data(sd);
- return NULL;
- }
const struct audio_format *audio_format =
&sd->base.config_audio_format;
@@ -125,11 +120,6 @@ my_shout_init_driver(const struct config_param *param,
return NULL;
}
- if (shout_init_count == 0)
- shout_init();
-
- shout_init_count++;
-
const struct block_param *block_param;
check_block_param("host");
char *host = block_param->value;
@@ -141,7 +131,7 @@ my_shout_init_driver(const struct config_param *param,
if (port == 0) {
g_set_error(error, shout_output_quark(), 0,
"shout port must be configured");
- goto failure;
+ return false;
}
check_block_param("password");
@@ -164,21 +154,21 @@ my_shout_init_driver(const struct config_param *param,
"shout quality \"%s\" is not a number in the "
"range -1 to 10, line %i",
value, param->line);
- goto failure;
+ return false;
}
if (config_get_block_string(param, "bitrate", NULL) != NULL) {
g_set_error(error, shout_output_quark(), 0,
"quality and bitrate are "
"both defined");
- goto failure;
+ return false;
}
} else {
value = config_get_block_string(param, "bitrate", NULL);
if (value == NULL) {
g_set_error(error, shout_output_quark(), 0,
"neither bitrate nor quality defined");
- goto failure;
+ return false;
}
char *test;
@@ -187,7 +177,7 @@ my_shout_init_driver(const struct config_param *param,
if (*test != '\0' || sd->bitrate <= 0) {
g_set_error(error, shout_output_quark(), 0,
"bitrate must be a positive integer");
- goto failure;
+ return false;
}
}
@@ -199,12 +189,12 @@ my_shout_init_driver(const struct config_param *param,
g_set_error(error, shout_output_quark(), 0,
"couldn't find shout encoder plugin \"%s\"",
encoding);
- goto failure;
+ return false;
}
sd->encoder = encoder_init(encoder_plugin, param, error);
if (sd->encoder == NULL)
- goto failure;
+ return false;
unsigned shout_format;
if (strcmp(encoding, "mp3") == 0 || strcmp(encoding, "lame") == 0)
@@ -220,7 +210,7 @@ my_shout_init_driver(const struct config_param *param,
g_set_error(error, shout_output_quark(), 0,
"you cannot stream \"%s\" to shoutcast, use mp3",
encoding);
- goto failure;
+ return false;
} else if (0 == strcmp(value, "shoutcast"))
protocol = SHOUT_PROTOCOL_ICY;
else if (0 == strcmp(value, "icecast1"))
@@ -232,7 +222,7 @@ my_shout_init_driver(const struct config_param *param,
"shout protocol \"%s\" is not \"shoutcast\" or "
"\"icecast1\"or \"icecast2\"",
value);
- goto failure;
+ return false;
}
} else {
protocol = SHOUT_PROTOCOL_HTTP;
@@ -251,7 +241,7 @@ my_shout_init_driver(const struct config_param *param,
shout_set_agent(sd->shout_conn, "MPD") != SHOUTERR_SUCCESS) {
g_set_error(error, shout_output_quark(), 0,
"%s", shout_get_error(sd->shout_conn));
- goto failure;
+ return false;
}
/* optional paramters */
@@ -262,21 +252,21 @@ my_shout_init_driver(const struct config_param *param,
if (value != NULL && shout_set_genre(sd->shout_conn, value)) {
g_set_error(error, shout_output_quark(), 0,
"%s", shout_get_error(sd->shout_conn));
- goto failure;
+ return false;
}
value = config_get_block_string(param, "description", NULL);
if (value != NULL && shout_set_description(sd->shout_conn, value)) {
g_set_error(error, shout_output_quark(), 0,
"%s", shout_get_error(sd->shout_conn));
- goto failure;
+ return false;
}
value = config_get_block_string(param, "url", NULL);
if (value != NULL && shout_set_url(sd->shout_conn, value)) {
g_set_error(error, shout_output_quark(), 0,
"%s", shout_get_error(sd->shout_conn));
- goto failure;
+ return false;
}
{
@@ -301,12 +291,31 @@ my_shout_init_driver(const struct config_param *param,
}
}
- return &sd->base;
+ return true;
+}
-failure:
- ao_base_finish(&sd->base);
- free_shout_data(sd);
- return NULL;
+static struct audio_output *
+my_shout_init_driver(const struct config_param *param,
+ GError **error)
+{
+ struct shout_data *sd = new_shout_data();
+ if (!ao_base_init(&sd->base, &shout_output_plugin, param, error)) {
+ free_shout_data(sd);
+ return NULL;
+ }
+
+ if (!my_shout_configure(sd, param, error)) {
+ ao_base_finish(&sd->base);
+ free_shout_data(sd);
+ return NULL;
+ }
+
+ if (shout_init_count == 0)
+ shout_init();
+
+ shout_init_count++;
+
+ return &sd->base;
}
static bool
diff --git a/src/output_all.c b/src/output_all.c
index f56cd04ee..b2ef1561f 100644
--- a/src/output_all.c
+++ b/src/output_all.c
@@ -19,6 +19,7 @@
#include "config.h"
#include "output_all.h"
+#include "output_error.h"
#include "output_internal.h"
#include "output_control.h"
#include "chunk.h"
@@ -270,7 +271,7 @@ audio_output_all_update(void)
}
bool
-audio_output_all_play(struct music_chunk *chunk)
+audio_output_all_play(struct music_chunk *chunk, GError **error_r)
{
bool ret;
unsigned int i;
@@ -281,8 +282,12 @@ audio_output_all_play(struct music_chunk *chunk)
assert(music_chunk_check_format(chunk, &input_audio_format));
ret = audio_output_all_update();
- if (!ret)
+ if (!ret) {
+ /* TODO: obtain real error */
+ g_set_error(error_r, output_quark(), 0,
+ "Failed to open audio output");
return false;
+ }
music_pipe_push(g_mp, chunk);
@@ -294,7 +299,8 @@ audio_output_all_play(struct music_chunk *chunk)
bool
audio_output_all_open(const struct audio_format *audio_format,
- struct music_buffer *buffer)
+ struct music_buffer *buffer,
+ GError **error_r)
{
bool ret = false, enabled = false;
unsigned int i;
@@ -334,7 +340,12 @@ audio_output_all_open(const struct audio_format *audio_format,
}
if (!enabled)
- g_warning("All audio outputs are disabled");
+ g_set_error(error_r, output_quark(), 0,
+ "All audio outputs are disabled");
+ else if (!ret)
+ /* TODO: obtain real error */
+ g_set_error(error_r, output_quark(), 0,
+ "Failed to open audio output");
if (!ret)
/* close all devices if there was an error */
diff --git a/src/output_all.h b/src/output_all.h
index 4eeb94f13..00864c9ba 100644
--- a/src/output_all.h
+++ b/src/output_all.h
@@ -26,6 +26,8 @@
#ifndef OUTPUT_ALL_H
#define OUTPUT_ALL_H
+#include "gerror.h"
+
#include <stdbool.h>
#include <stddef.h>
@@ -84,7 +86,8 @@ audio_output_all_enable_disable(void);
*/
bool
audio_output_all_open(const struct audio_format *audio_format,
- struct music_buffer *buffer);
+ struct music_buffer *buffer,
+ GError **error_r);
/**
* Closes all audio outputs.
@@ -108,7 +111,7 @@ audio_output_all_release(void);
* (all closed then)
*/
bool
-audio_output_all_play(struct music_chunk *chunk);
+audio_output_all_play(struct music_chunk *chunk, GError **error_r);
/**
* Checks if the output devices have drained their music pipe, and
diff --git a/src/output_error.h b/src/output_error.h
new file mode 100644
index 000000000..ccc784f89
--- /dev/null
+++ b/src/output_error.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2003-2012 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_OUTPUT_ERROR_H
+#define MPD_OUTPUT_ERROR_H
+
+#include <glib.h>
+
+/**
+ * Quark for GError.domain.
+ */
+G_GNUC_CONST
+static inline GQuark
+output_quark(void)
+{
+ return g_quark_from_static_string("output");
+}
+
+#endif
diff --git a/src/output_init.c b/src/output_init.c
index c3b808e94..a6d191920 100644
--- a/src/output_init.c
+++ b/src/output_init.c
@@ -165,6 +165,7 @@ ao_base_init(struct audio_output *ao,
}
ao->plugin = plugin;
+ ao->tags = config_get_block_bool(param, "tags", true);
ao->always_on = config_get_block_bool(param, "always_on", false);
ao->enabled = config_get_block_bool(param, "enabled", true);
ao->really_enabled = false;
diff --git a/src/output_internal.h b/src/output_internal.h
index 9d975d789..1a3e8aa1f 100644
--- a/src/output_internal.h
+++ b/src/output_internal.h
@@ -73,6 +73,13 @@ struct audio_output {
struct mixer *mixer;
/**
+ * Will this output receive tags from the decoder? The
+ * default is true, but it may be configured to false to
+ * suppress sending tags to the output.
+ */
+ bool tags;
+
+ /**
* Shall this output always play something (i.e. silence),
* even when playback is stopped?
*/
diff --git a/src/output_plugin.h b/src/output_plugin.h
index 209ca6221..a47296566 100644
--- a/src/output_plugin.h
+++ b/src/output_plugin.h
@@ -20,7 +20,8 @@
#ifndef MPD_OUTPUT_PLUGIN_H
#define MPD_OUTPUT_PLUGIN_H
-#include <glib.h>
+#include "gcc.h"
+#include "gerror.h"
#include <stdbool.h>
#include <stddef.h>
@@ -165,7 +166,7 @@ ao_plugin_test_default_device(const struct audio_output_plugin *plugin)
: false;
}
-G_GNUC_MALLOC
+gcc_malloc
struct audio_output *
ao_plugin_init(const struct audio_output_plugin *plugin,
const struct config_param *param,
@@ -187,7 +188,7 @@ ao_plugin_open(struct audio_output *ao, struct audio_format *audio_format,
void
ao_plugin_close(struct audio_output *ao);
-G_GNUC_PURE
+gcc_pure
unsigned
ao_plugin_delay(struct audio_output *ao);
diff --git a/src/output_thread.c b/src/output_thread.c
index 4eef2ccdd..cd1a8a878 100644
--- a/src/output_thread.c
+++ b/src/output_thread.c
@@ -435,7 +435,7 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
assert(ao != NULL);
assert(ao->filter != NULL);
- if (chunk->tag != NULL) {
+ if (ao->tags && gcc_unlikely(chunk->tag != NULL)) {
g_mutex_unlock(ao->mutex);
ao_plugin_send_tag(ao, chunk->tag);
g_mutex_lock(ao->mutex);