From 8dbbea85984e923a369dd41988222c8af0870cfe Mon Sep 17 00:00:00 2001 From: Warren Dukes Date: Sat, 23 Oct 2004 15:25:42 +0000 Subject: slightly better error handling/broken connection detection for shout output git-svn-id: https://svn.musicpd.org/mpd/trunk@2316 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/audioOutput_shout.c | 86 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/audioOutput_shout.c b/src/audioOutput_shout.c index 3d3c332a3..9f0984f32 100644 --- a/src/audioOutput_shout.c +++ b/src/audioOutput_shout.c @@ -64,6 +64,8 @@ typedef struct _ShoutData { long convBufferLen; /* shoud we convert the audio to a different format? */ int audioFormatConvert; + + int opened; } ShoutData; static ShoutData * newShoutData() { @@ -73,6 +75,7 @@ static ShoutData * newShoutData() { ret->serialno = rand(); ret->convBuffer = NULL; ret->convBufferLen = 0; + ret->opened = 0; return ret; } @@ -187,9 +190,28 @@ static int shout_initDriver(AudioOutput * audioOutput) { return 0; } +static void shout_closeShoutConn(ShoutData * sd) { + if(sd->opened) { + if(shout_close(sd->shoutConn) != SHOUTERR_SUCCESS) { + ERROR("problem closing connection to shout server: " + "%s\n", shout_get_error(sd->shoutConn)); + } + + ogg_stream_clear(&(sd->os)); + vorbis_block_clear(&(sd->vb)); + vorbis_dsp_clear(&(sd->vd)); + vorbis_comment_clear(&(sd->vc)); + vorbis_info_clear(&(sd->vi)); + } + + sd->opened = 0; +} + static void shout_finishDriver(AudioOutput * audioOutput) { ShoutData * sd = (ShoutData *)audioOutput->data; + shout_closeShoutConn(sd); + freeShoutData(sd); shoutInitCount--; @@ -198,29 +220,33 @@ static void shout_finishDriver(AudioOutput * audioOutput) { } static void shout_closeDevice(AudioOutput * audioOutput) { - ShoutData * sd = (ShoutData *) audioOutput->data; + audioOutput->open = 0; +} - if(shout_close(sd->shoutConn) != SHOUTERR_SUCCESS) - { - ERROR("problem closing connection to shout server: %s\n", - shout_get_error(sd->shoutConn)); +static void shout_handleError(ShoutData * sd, int err) { + switch(err) { + case SHOUTERR_SUCCESS: + break; + case SHOUTERR_UNCONNECTED: + case SHOUTERR_SOCKET: + ERROR("Lost shout connection, attempting to reconnect\n"); + shout_close(sd->shoutConn); + shout_open(sd->shoutConn); + break; + default: + ERROR("shout: error: %s\n", shout_get_error(sd->shoutConn)); + break; } - - ogg_stream_clear(&(sd->os)); - vorbis_block_clear(&(sd->vb)); - vorbis_dsp_clear(&(sd->vd)); - vorbis_comment_clear(&(sd->vc)); - vorbis_info_clear(&(sd->vi)); - - audioOutput->open = 0; } static void write_page(ShoutData * sd) { if(!sd->og.header_len || !sd->og.body_len) return; - shout_sync(sd->shoutConn); - shout_send(sd->shoutConn, sd->og.header, sd->og.header_len); - shout_send(sd->shoutConn, sd->og.body, sd->og.body_len); + /*shout_sync(sd->shoutConn);*/ + int err = shout_send(sd->shoutConn, sd->og.header, sd->og.header_len); + shout_handleError(sd, err); + err = shout_send(sd->shoutConn, sd->og.body, sd->og.body_len); + shout_handleError(sd, err); shout_sync(sd->shoutConn); } @@ -229,10 +255,25 @@ static int shout_openDevice(AudioOutput * audioOutput, { ShoutData * sd = (ShoutData *)audioOutput->data; + memcpy(&(sd->inAudioFormat), audioFormat, sizeof(AudioFormat)); + + if(0 == memcmp(&(sd->inAudioFormat), &(sd->outAudioFormat), + sizeof(AudioFormat))) + { + sd->audioFormatConvert = 0; + } + else sd->audioFormatConvert = 1; + + audioOutput->open = 1; + + if(sd->opened) return 0; + if(shout_open(sd->shoutConn) != SHOUTERR_SUCCESS) { ERROR("problem opening connection to shout server: %s\n", shout_get_error(sd->shoutConn)); + + audioOutput->open = 0; return -1; } @@ -243,6 +284,8 @@ static int shout_openDevice(AudioOutput * audioOutput, { ERROR("problem seting up vorbis encoder for shout\n"); vorbis_info_clear(&(sd->vi)); + shout_close(sd->shoutConn); + audioOutput->open = 0; return -1; } @@ -259,21 +302,12 @@ static int shout_openDevice(AudioOutput * audioOutput, ogg_stream_packetin(&(sd->os), &(sd->header_comments)); ogg_stream_packetin(&(sd->os), &(sd->header_codebooks)); - audioOutput->open = 1; - while(ogg_stream_flush(&(sd->os), &(sd->og))) { write_page(sd); } - memcpy(&(sd->inAudioFormat), audioFormat, sizeof(AudioFormat)); - - if(0 == memcmp(&(sd->inAudioFormat), &(sd->outAudioFormat), - sizeof(AudioFormat))) - { - sd->audioFormatConvert = 0; - } - else sd->audioFormatConvert = 1; + sd->opened = 1; return 0; } -- cgit v1.2.3