output_all: add basic GError support

This commit is contained in:
Max Kellermann 2012-08-08 22:47:51 +02:00
parent 8c425c758c
commit f794b1e1aa
5 changed files with 75 additions and 11 deletions

View File

@ -795,6 +795,7 @@ OUTPUT_API_SRC = \
src/output_list.c \ src/output_list.c \
src/output_all.c \ src/output_all.c \
src/output_thread.c \ src/output_thread.c \
src/output_error.h \
src/output_control.c \ src/output_control.c \
src/output_state.c \ src/output_state.c \
src/output_print.c \ src/output_print.c \

View File

@ -19,6 +19,7 @@
#include "config.h" #include "config.h"
#include "output_all.h" #include "output_all.h"
#include "output_error.h"
#include "output_internal.h" #include "output_internal.h"
#include "output_control.h" #include "output_control.h"
#include "chunk.h" #include "chunk.h"
@ -270,7 +271,7 @@ audio_output_all_update(void)
} }
bool bool
audio_output_all_play(struct music_chunk *chunk) audio_output_all_play(struct music_chunk *chunk, GError **error_r)
{ {
bool ret; bool ret;
unsigned int i; unsigned int i;
@ -281,8 +282,12 @@ audio_output_all_play(struct music_chunk *chunk)
assert(music_chunk_check_format(chunk, &input_audio_format)); assert(music_chunk_check_format(chunk, &input_audio_format));
ret = audio_output_all_update(); 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; return false;
}
music_pipe_push(g_mp, chunk); music_pipe_push(g_mp, chunk);
@ -294,7 +299,8 @@ audio_output_all_play(struct music_chunk *chunk)
bool bool
audio_output_all_open(const struct audio_format *audio_format, 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; bool ret = false, enabled = false;
unsigned int i; unsigned int i;
@ -334,7 +340,12 @@ audio_output_all_open(const struct audio_format *audio_format,
} }
if (!enabled) 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) if (!ret)
/* close all devices if there was an error */ /* close all devices if there was an error */

View File

@ -26,6 +26,8 @@
#ifndef OUTPUT_ALL_H #ifndef OUTPUT_ALL_H
#define OUTPUT_ALL_H #define OUTPUT_ALL_H
#include "gerror.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
@ -84,7 +86,8 @@ audio_output_all_enable_disable(void);
*/ */
bool bool
audio_output_all_open(const struct audio_format *audio_format, 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. * Closes all audio outputs.
@ -108,7 +111,7 @@ audio_output_all_release(void);
* (all closed then) * (all closed then)
*/ */
bool 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 * Checks if the output devices have drained their music pipe, and

35
src/output_error.h Normal file
View File

@ -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

View File

@ -305,7 +305,9 @@ player_open_output(struct player *player)
assert(pc->state == PLAYER_STATE_PLAY || assert(pc->state == PLAYER_STATE_PLAY ||
pc->state == PLAYER_STATE_PAUSE); pc->state == PLAYER_STATE_PAUSE);
if (audio_output_all_open(&player->play_audio_format, player_buffer)) { GError *error = NULL;
if (audio_output_all_open(&player->play_audio_format, player_buffer,
&error)) {
player->output_open = true; player->output_open = true;
player->paused = false; player->paused = false;
@ -315,6 +317,9 @@ player_open_output(struct player *player)
return true; return true;
} else { } else {
g_warning("%s", error->message);
g_error_free(error);
player->output_open = false; player->output_open = false;
/* pause: the user may resume playback as soon as an /* pause: the user may resume playback as soon as an
@ -429,7 +434,11 @@ player_send_silence(struct player *player)
chunk->length = num_frames * frame_size; chunk->length = num_frames * frame_size;
memset(chunk->data, 0, chunk->length); memset(chunk->data, 0, chunk->length);
if (!audio_output_all_play(chunk)) { GError *error = NULL;
if (!audio_output_all_play(chunk, &error)) {
g_warning("%s", error->message);
g_error_free(error);
music_buffer_return(player_buffer, chunk); music_buffer_return(player_buffer, chunk);
return false; return false;
} }
@ -650,7 +659,8 @@ update_song_tag(struct song *song, const struct tag *new_tag)
static bool static bool
play_chunk(struct player_control *pc, play_chunk(struct player_control *pc,
struct song *song, struct music_chunk *chunk, struct song *song, struct music_chunk *chunk,
const struct audio_format *format) const struct audio_format *format,
GError **error_r)
{ {
assert(music_chunk_check_format(chunk, format)); assert(music_chunk_check_format(chunk, format));
@ -668,7 +678,7 @@ play_chunk(struct player_control *pc,
/* send the chunk to the audio outputs */ /* send the chunk to the audio outputs */
if (!audio_output_all_play(chunk)) if (!audio_output_all_play(chunk, error_r))
return false; return false;
pc->total_play_time += (double)chunk->length / pc->total_play_time += (double)chunk->length /
@ -783,8 +793,12 @@ play_next_chunk(struct player *player)
/* play the current chunk */ /* play the current chunk */
GError *error = NULL;
if (!play_chunk(player->pc, player->song, chunk, if (!play_chunk(player->pc, player->song, chunk,
&player->play_audio_format)) { &player->play_audio_format, &error)) {
g_warning("%s", error->message);
g_error_free(error);
music_buffer_return(player_buffer, chunk); music_buffer_return(player_buffer, chunk);
player_lock(pc); player_lock(pc);