Beispiel #1
0
static void pshoutobj_free(PyObject* self) {
  ShoutObject* me = (ShoutObject*)self;

  Py_XDECREF(me->attr);
  shout_free(me->conn);
  PyObject_Del(self);
}
Beispiel #2
0
OutputIceCast::~OutputIceCast()
{
    if (getState() == CONNECTED)
        disconnectStream();
    shout_free(_shout);
    shout_shutdown();
}
static void free_shout_data(struct shout_data *sd)
{
	if (sd->shout_meta)
		shout_metadata_free(sd->shout_meta);
	if (sd->shout_conn)
		shout_free(sd->shout_conn);

	g_free(sd);
}
Beispiel #4
0
/*****************************************************************************
 * Close: close the target
 *****************************************************************************/
static void Close( vlc_object_t * p_this )
{
    sout_access_out_t *p_access = (sout_access_out_t*)p_this;
    sout_access_out_sys_t *p_sys = p_access->p_sys;

    if( p_sys->p_shout )
    {
        shout_close( p_sys->p_shout );
        shout_free( p_sys->p_shout );
        shout_shutdown();
    }
    free( p_sys );
    msg_Dbg( p_access, "shout access output closed" );
}
Beispiel #5
0
/* Frees ices_stream_t data (but not the object itself) */
static void
ices_setup_free_stream (ices_stream_t* stream)
{
  if (stream->conn)
    shout_free (stream->conn);
  ices_util_free (stream->host);
  ices_util_free (stream->password);

  ices_util_free (stream->mount);
  ices_util_free (stream->dumpfile);

  ices_util_free (stream->name);
  ices_util_free (stream->genre);
  ices_util_free (stream->description);
  ices_util_free (stream->url);
}
Beispiel #6
0
EngineShoutcast::~EngineShoutcast() {
    if (m_encoder) {
        m_encoder->flush();
        delete m_encoder;
    }

    delete m_pUpdateShoutcastFromPrefs;
    delete m_pShoutcastNeedUpdateFromPrefs;
    delete m_pShoutcastStatus;
    delete m_pMasterSamplerate;

    if (m_pShoutMetaData) {
        shout_metadata_free(m_pShoutMetaData);
    }
    if (m_pShout) {
        shout_close(m_pShout);
        shout_free(m_pShout);
    }
    shout_shutdown();
}
static gboolean
gst_shout2send_stop (GstBaseSink * basesink)
{
  GstShout2send *sink = GST_SHOUT2SEND (basesink);

  if (sink->conn) {
    if (sink->connected)
      shout_close (sink->conn);
    shout_free (sink->conn);
    sink->conn = NULL;
  }

  if (sink->songmetadata) {
    g_free (sink->songmetadata);
    sink->songmetadata = NULL;
  }

  sink->connected = FALSE;

  return TRUE;
}
Beispiel #8
0
/*****************************************************************************
 * Open: open the shout connection
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    sout_access_out_t *p_access = (sout_access_out_t*)p_this;
    sout_access_out_sys_t *p_sys;
    shout_t *p_shout;
    long i_ret;
    char *psz_val;

    char *psz_name;
    char *psz_description;
    char *psz_genre;
    char *psz_url;
    vlc_url_t url;

    config_ChainParse( p_access, SOUT_CFG_PREFIX, ppsz_sout_options, p_access->p_cfg );

    if( !p_access->psz_path )
    {
        msg_Err( p_access,
                 "please specify url=user:password@host:port/mountpoint" );
        return VLC_EGENERIC;
    }

    vlc_UrlParse( &url , p_access->psz_path, 0 );
    if( url.i_port <= 0 )
        url.i_port = 8000;

    p_sys = p_access->p_sys = malloc( sizeof( sout_access_out_sys_t ) );
    if( !p_sys )
    {
        vlc_UrlClean( &url );
        return VLC_ENOMEM;
    }

    psz_name = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "name" );
    psz_description = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "description" );
    psz_genre = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "genre" );
    psz_url = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "url" );

    p_shout = p_sys->p_shout = shout_new();
    if( !p_shout
         || shout_set_host( p_shout, url.psz_host ) != SHOUTERR_SUCCESS
         || shout_set_protocol( p_shout, SHOUT_PROTOCOL_ICY ) != SHOUTERR_SUCCESS
         || shout_set_port( p_shout, url.i_port ) != SHOUTERR_SUCCESS
         || shout_set_password( p_shout, url.psz_password ) != SHOUTERR_SUCCESS
         || shout_set_mount( p_shout, url.psz_path ) != SHOUTERR_SUCCESS
         || shout_set_user( p_shout, url.psz_username ) != SHOUTERR_SUCCESS
         || shout_set_agent( p_shout, "VLC media player " VERSION ) != SHOUTERR_SUCCESS
         || shout_set_name( p_shout, psz_name ) != SHOUTERR_SUCCESS
         || shout_set_description( p_shout, psz_description ) != SHOUTERR_SUCCESS
         || shout_set_genre( p_shout, psz_genre ) != SHOUTERR_SUCCESS
         || shout_set_url( p_shout, psz_url ) != SHOUTERR_SUCCESS
         /* || shout_set_nonblocking( p_shout, 1 ) != SHOUTERR_SUCCESS */
      )
    {
        msg_Err( p_access, "failed to initialize shout streaming to %s:%i/%s",
                 url.psz_host, url.i_port, url.psz_path );

        free( psz_name );
        free( psz_description );
        free( psz_genre );
        free( psz_url );
        goto error;
    }

    free( psz_name );
    free( psz_description );
    free( psz_genre );
    free( psz_url );

    i_ret = shout_set_format( p_shout, var_GetBool( p_access, SOUT_CFG_PREFIX "mp3" ) ?
                                       SHOUT_FORMAT_MP3 : SHOUT_FORMAT_OGG );

    if( i_ret != SHOUTERR_SUCCESS )
    {
        msg_Err( p_access, "failed to set the shoutcast streaming format" );
        goto error;
    }

    /* Don't force bitrate to 0 but only use when specified. This will otherwise
       show an empty field on icecast directory listing instead of NA */
    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "bitrate" );
    if( psz_val )
    {
        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_BITRATE, psz_val );
        free( psz_val );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the information about the bitrate" );
            goto error;
        }
    }
    else
    {
        /* Bitrate information is used for icecast/shoutcast servers directory
           listings (sorting, stream info etc.) */
        msg_Warn( p_access, "no bitrate information specified (required for listing " \
                            "the server as public on the shoutcast website)" );
    }

    /* Information about samplerate, channels and quality will not be propagated
       through the YP protocol for icecast to the public directory listing when
       the icecast server is operating in shoutcast compatibility mode */

    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "samplerate" );
    if( psz_val )
    {
        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_SAMPLERATE, psz_val );
        free( psz_val );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the information about the samplerate" );
            goto error;
        }
    }

    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "channels" );
    if( psz_val )
    {
        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_CHANNELS, psz_val );
        free( psz_val );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the information about the number of channels" );
            goto error;
        }
    }

    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "quality" );
    if( psz_val )
    {
        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_QUALITY, psz_val );
        free( psz_val );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the information about Ogg Vorbis quality" );
            goto error;
        }
    }

    if( var_GetBool( p_access, SOUT_CFG_PREFIX "public" ) )
    {
        i_ret = shout_set_public( p_shout, 1 );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the server status setting to public" );
            goto error;
        }
    }

    /* Connect at startup. Cycle through the possible protocols. */
    i_ret = shout_get_connected( p_shout );
    while ( i_ret != SHOUTERR_CONNECTED )
    {
        /* Shout parameters cannot be changed on an open connection */
        i_ret = shout_close( p_shout );
        if( i_ret == SHOUTERR_SUCCESS )
        {
            i_ret = SHOUTERR_UNCONNECTED;
        }

        /* Re-initialize for Shoutcast using ICY protocol. Not needed for initial connection
           but it is when we are reconnecting after other protocol was tried. */
        i_ret = shout_set_protocol( p_shout, SHOUT_PROTOCOL_ICY );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the protocol to 'icy'" );
            goto error;
        }
        i_ret = shout_open( p_shout );
        if( i_ret == SHOUTERR_SUCCESS )
        {
            i_ret = SHOUTERR_CONNECTED;
            msg_Dbg( p_access, "connected using 'icy' (shoutcast) protocol" );
        }
        else
        {
            msg_Warn( p_access, "failed to connect using 'icy' (shoutcast) protocol" );

            /* Shout parameters cannot be changed on an open connection */
            i_ret = shout_close( p_shout );
            if( i_ret == SHOUTERR_SUCCESS )
            {
                i_ret = SHOUTERR_UNCONNECTED;
            }

            /* IceCAST using HTTP protocol */
            i_ret = shout_set_protocol( p_shout, SHOUT_PROTOCOL_HTTP );
            if( i_ret != SHOUTERR_SUCCESS )
            {
                msg_Err( p_access, "failed to set the protocol to 'http'" );
                goto error;
            }
            i_ret = shout_open( p_shout );
            if( i_ret == SHOUTERR_SUCCESS )
            {
                i_ret = SHOUTERR_CONNECTED;
                msg_Dbg( p_access, "connected using 'http' (icecast 2.x) protocol" );
            }
            else
                msg_Warn( p_access, "failed to connect using 'http' (icecast 2.x) protocol " );
        }
/*
        for non-blocking, use:
        while( i_ret == SHOUTERR_BUSY )
        {
            sleep( 1 );
            i_ret = shout_get_connected( p_shout );
        }
*/
        if ( i_ret != SHOUTERR_CONNECTED )
    	{
    	    msg_Warn( p_access, "unable to establish connection, retrying..." );
            msleep( 30000000 );
        }
    }

    if( i_ret != SHOUTERR_CONNECTED )
    {
        msg_Err( p_access, "failed to open shout stream to %s:%i/%s: %s",
                 url.psz_host, url.i_port, url.psz_path, shout_get_error(p_shout) );
        goto error;
    }

    p_access->pf_write = Write;
    p_access->pf_seek  = Seek;
    p_access->pf_control = Control;

    msg_Dbg( p_access, "shout access output opened (%s@%s:%i/%s)",
             url.psz_username, url.psz_host, url.i_port, url.psz_path );

    vlc_UrlClean( &url );
    return VLC_SUCCESS;

error:
    if( p_sys->p_shout )
        shout_free( p_sys->p_shout );
    vlc_UrlClean( &url );
    free( p_sys );
    return VLC_EGENERIC;
}
Beispiel #9
0
Shouter::~Shouter() {
    func("Shouter::~Shouter");
    stop();
    shout_free(ice);
}
Beispiel #10
0
shout_t *
stream_setup(const char *host, unsigned short port, const char *mount)
{
	shout_t *shout = NULL;

	if ((shout = shout_new()) == NULL) {
		printf("%s: shout_new(): %s", __progname, strerror(ENOMEM));
		return (NULL);
	}

	if (shout_set_host(shout, host) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_host(): %s\n", __progname,
		       shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_protocol(): %s\n", __progname,
			shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (shout_set_port(shout, port) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_port: %s\n", __progname,
			shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (shout_set_password(shout, pezConfig->password) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_password(): %s\n", __progname,
			shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (shout_set_mount(shout, mount) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_mount(): %s\n", __progname,
			shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_user(): %s\n", __progname,
			shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}

	if (!strcmp(pezConfig->format, MP3_FORMAT) &&
	    shout_set_format(shout, SHOUT_FORMAT_MP3) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_format(MP3): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if ((!strcmp(pezConfig->format, VORBIS_FORMAT) ||
	     !strcmp(pezConfig->format, THEORA_FORMAT)) &&
	    shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_format(OGG): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}

	if (pezConfig->username &&
	    shout_set_user(shout, pezConfig->username) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_user(): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (pezConfig->serverName &&
	    shout_set_name(shout, pezConfig->serverName) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_name(): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (pezConfig->serverURL &&
	    shout_set_url(shout, pezConfig->serverURL) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_url(): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (pezConfig->serverGenre &&
	    shout_set_genre(shout, pezConfig->serverGenre) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_genre(): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (pezConfig->serverDescription &&
	    shout_set_description(shout, pezConfig->serverDescription) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_description(): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (pezConfig->serverBitrate &&
	    shout_set_audio_info(shout, SHOUT_AI_BITRATE, pezConfig->serverBitrate) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_audio_info(AI_BITRATE): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (pezConfig->serverChannels &&
	    shout_set_audio_info(shout, SHOUT_AI_CHANNELS, pezConfig->serverChannels) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_audio_info(AI_CHANNELS): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (pezConfig->serverSamplerate &&
	    shout_set_audio_info(shout, SHOUT_AI_SAMPLERATE, pezConfig->serverSamplerate) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_audio_info(AI_SAMPLERATE): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}
	if (pezConfig->serverQuality &&
	    shout_set_audio_info(shout, SHOUT_AI_QUALITY, pezConfig->serverQuality) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_audio_info(AI_QUALITY): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}

	if (shout_set_public(shout, (unsigned int)pezConfig->serverPublic) != SHOUTERR_SUCCESS) {
		printf("%s: shout_set_public(): %s\n",
		       __progname, shout_get_error(shout));
		shout_free(shout);
		return (NULL);
	}

	return (shout);
}
Beispiel #11
0
static SCM open_vorbis_stream(SCM server, SCM port, SCM password,
			SCM mount, SCM config) {
	SCM smob;
	double qual;
	char stream_name[32];
	VORBIS_STREAM *stream;
	stream = (VORBIS_STREAM *)my_gc_malloc(sizeof(VORBIS_STREAM),
				"vorbis_stream", "vorbis stream");
	stream->header.shutdown = vorbis_shutdown;
	vorbis_info_init(&(stream->vi));
	SCM quality = get_property(config, "quality");
	if (scm_is_number(quality)) qual = scm_to_double(quality);
	else qual = 0.6;
	scm_remember_upto_here_1(quality);
	stream->header.shoutbuf = NULL;
	stream->header.shoutbuf_size = 0;
	stream->header.rb_size = sizeof(sample_t) * RB_SECS * sampling_rate 
				* QMX_CHANNELS + 0.5;
	stream->header.ringbuf = jack_ringbuffer_create(stream->header.rb_size);
	if (vorbis_encode_init_vbr(&(stream->vi), QMX_CHANNELS,
				sampling_rate, qual) != 0) {
		log_msg("vorbis init failed\n");
		return SCM_BOOL_F;
		}
	if ((stream->header.shout = shout_new()) == NULL) {
		log_msg("can't create shout instance\n");
		return SCM_BOOL_F;
		}
	vorbis_analysis_init(&(stream->vd), &(stream->vi));
	vorbis_block_init(&(stream->vd), &(stream->vb));
	ogg_stream_init(&(stream->os), rand());
	vorbis_comment_init(&(stream->vc));
	vorbis_comment_add_tag(&(stream->vc), "ENCODER", "QMX");
	shout_set_protocol(stream->header.shout, SHOUT_PROTOCOL_HTTP);
	shout_set_format(stream->header.shout, SHOUT_FORMAT_OGG);
	char *server_s = scm_to_locale_string(server); // server
	shout_set_host(stream->header.shout, server_s);
	free(server_s);
	shout_set_port(stream->header.shout, scm_to_int(port)); // port
	shout_set_user(stream->header.shout, "source"); // user
	char *password_s = scm_to_locale_string(password); // password
	shout_set_password(stream->header.shout, password_s);
	free(password_s);
	char *mount_s = scm_to_locale_string(mount); // mount pt
	shout_set_mount(stream->header.shout, mount_s);
	SCM title = get_property(config, "title");
	if (scm_is_string(title)) {
		char *title_s = scm_to_locale_string(title);
		if (strlen(title_s) > 0)
			vorbis_comment_add_tag(&(stream->vc), "TITLE", title_s);
		free(title_s);
		}
	scm_remember_upto_here_1(title);
	SCM name = get_property(config, "name");
	stream_name[0] = '\0';
	if (scm_is_string(name)) {
		char *name_s = scm_to_locale_string(name);
		shout_set_name(stream->header.shout, name_s);
		snprintf(stream_name, sizeof(stream_name), "'%s' ", name_s);
		free(name_s);
		}
	scm_remember_upto_here_1(name);
	SCM description = get_property(config, "description");
	if (scm_is_string(description)) {
		char *description_s = scm_to_locale_string(description);
		shout_set_description(stream->header.shout, description_s);
		free(description_s);
		}
	scm_remember_upto_here_1(description);
	SCM genre = get_property(config, "genre");
	if (scm_is_string(genre)) {
		char *genre_s = scm_to_locale_string(genre);
		shout_set_genre(stream->header.shout, genre_s);
		free(genre_s);
		}
	scm_remember_upto_here_1(genre);
	shout_set_audio_info(stream->header.shout,
			SHOUT_AI_CHANNELS, encode_int(QMX_CHANNELS));
	shout_set_audio_info(stream->header.shout,
			SHOUT_AI_SAMPLERATE, encode_int(sampling_rate));
	if (shout_open(stream->header.shout) == SHOUTERR_SUCCESS) {
		log_msg("vorbis stream %smounted at %s\n", stream_name, mount_s);
		free(mount_s);
		}
	else {
		log_msg("vorbis stream %sfailed to open: %s\n", stream_name,
				shout_get_error(stream->header.shout));
		free(mount_s);
		shout_free(stream->header.shout);
		return SCM_BOOL_F;
		}
	vorbis_streams += 1;
	stream->header.eos = 0;
	SCM_NEWSMOB(smob, vorbis_stream_tag, stream);
	streams = link_in(streams, smob);
	stream->header.do_prep = need_prepper;
	need_prepper = 0;
	stream->header.bookmark = 0;
	add_outbuf_client(load_frames, process_frames, (void *)stream,
						"Ogg-Vorbis stream");
	spawn_detached_thread(shout_thread, (void *)&(stream->header));
	scm_remember_upto_here_1(smob);
	return smob;
	}
Beispiel #12
0
/* The main loop for each instance. Gets data passed to it from the stream
 * manager (which gets it from the input module), and streams it to the
 * specified server
 */
void *ices_instance_stream(void *arg)
{
	int ret, shouterr;
	ref_buffer *buffer;
	char *connip;
	stream_description *sdsc = arg;
	instance_t *stream = sdsc->stream;
	input_module_t *inmod = sdsc->input;
	int reencoding = (inmod->type == ICES_INPUT_VORBIS) && stream->encode;
	int encoding = (inmod->type == ICES_INPUT_PCM) && stream->encode;
    char *stream_name = NULL, *stream_genre = NULL, *stream_description = NULL;
    char *user = NULL;
	
	vorbis_comment_init(&sdsc->vc);

	sdsc->shout = shout_new();

	/* we only support the ice protocol and vorbis streams currently */
	shout_set_format(sdsc->shout, SHOUT_FORMAT_VORBIS);
	//shout_set_protocol(sdsc->shout, SHOUT_PROTOCOL_ICE);
	shout_set_protocol(sdsc->shout, SHOUT_PROTOCOL_HTTP);

    signal(SIGPIPE, signal_hup_handler);

	connip = malloc(16);
	if(!resolver_getip(stream->hostname, connip, 16))
	{
		LOG_ERROR1("Could not resolve hostname \"%s\"", stream->hostname);
		free(connip);
		stream->died = 1;
		return NULL;
	}

	if (!(shout_set_host(sdsc->shout, connip)) == SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
	}

	shout_set_port(sdsc->shout, stream->port);
	if (!(shout_set_password(sdsc->shout, stream->password)) == SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
	}
    if (stream->user)
        user = stream->user;
    else
        user = "******";

    if(shout_set_user(sdsc->shout, user) != SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
    }

	if (!(shout_set_agent(sdsc->shout, VERSIONSTRING)) == SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
	}

	if (!(shout_set_mount(sdsc->shout, stream->mount)) == SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
	}

	/* set the metadata for the stream */
    if(stream->stream_name)
        stream_name = stream->stream_name;
    else if (ices_config->stream_name)
        stream_name = ices_config->stream_name;

    if(stream->stream_description)
        stream_description = stream->stream_description;
    else if (ices_config->stream_description)
        stream_description = ices_config->stream_description;

    if(stream->stream_genre)
        stream_genre = stream->stream_genre;
    else if (ices_config->stream_genre)
        stream_genre = ices_config->stream_genre;

    if(stream_name)
		if (!(shout_set_name(sdsc->shout, stream_name)) == SHOUTERR_SUCCESS) {
			LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
			free(connip);
			stream->died = 1;
			return NULL;
		}
	if (stream_genre)
		if (!(shout_set_genre(sdsc->shout, stream_genre)) == SHOUTERR_SUCCESS) {
			LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
			free(connip);
			stream->died = 1;
			return NULL;
		}
	if (stream_description)
		if (!(shout_set_description(sdsc->shout, stream_description)) == SHOUTERR_SUCCESS) {
			LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
			free(connip);
			stream->died = 1;
			return NULL;
		}

    if(stream->downmix && encoding && stream->channels == 1) {
        stream->channels = 1;
        sdsc->downmix = downmix_initialise();
    }

    if(stream->resampleinrate && stream->resampleoutrate && encoding) {
        stream->samplerate = stream->resampleoutrate;
        sdsc->resamp = resample_initialise(stream->channels, 
                stream->resampleinrate, stream->resampleoutrate);
    }

	if(encoding)
	{
		if(inmod->metadata_update)
			inmod->metadata_update(inmod->internal, &sdsc->vc);
		sdsc->enc = encode_initialise(stream->channels, stream->samplerate,
				stream->managed, stream->min_br, stream->nom_br, stream->max_br,
                stream->quality, stream->serial++, &sdsc->vc);
        if(!sdsc->enc) {
            LOG_ERROR0("Failed to configure encoder");
		    stream->died = 1;
            return NULL; /* FIXME: probably leaking some memory here */
        }
	}
	else if(reencoding)
		sdsc->reenc = reencode_init(stream);

    if(stream->savefilename != NULL) 
    {
        stream->savefile = fopen(stream->savefilename, "wb");
        if(!stream->savefile)
            LOG_ERROR2("Failed to open stream save file %s: %s", 
                    stream->savefilename, strerror(errno));
        else
            LOG_INFO1("Saving stream to file %s", stream->savefilename);
    }

	if((shouterr = shout_open(sdsc->shout)) == SHOUTERR_SUCCESS)
	{
		LOG_INFO3("Connected to server: %s:%d%s", 
				shout_get_host(sdsc->shout), shout_get_port(sdsc->shout), shout_get_mount(sdsc->shout));

		while(1)
		{
			if(stream->buffer_failures > MAX_ERRORS)
			{
				LOG_WARN0("Too many errors, shutting down");
				break;
			}

			buffer = stream_wait_for_data(stream);

			/* buffer being NULL means that either a fatal error occured,
			 * or we've been told to shut down
			 */
			if(!buffer)
				break;

			/* If data is NULL or length is 0, we should just skip this one.
			 * Probably, we've been signalled to shut down, and that'll be
			 * caught next iteration. Add to the error count just in case,
			 * so that we eventually break out anyway 
			 */
			if(!buffer->buf || !buffer->len)
			{
				LOG_WARN0("Bad buffer dequeued!");
				stream->buffer_failures++;
				continue; 
			}

            if(stream->wait_for_critical)
            {
                LOG_INFO0("Trying restart on new substream");
                stream->wait_for_critical = 0;
            }

            ret = process_and_send_buffer(sdsc, buffer);

            /* No data produced, do nothing */
            if(ret == -1)
                ;
            /* Fatal error */
            else if(ret == -2)
            {
                LOG_ERROR0("Serious error, waiting to restart on "
                           "next substream. Stream temporarily suspended.");
                /* Set to wait until a critical buffer comes through (start of
                 * a new substream, typically), and flush existing queue.
                 */
                thread_mutex_lock(&ices_config->flush_lock);
                stream->wait_for_critical = 1;
                input_flush_queue(stream->queue, 0);
                thread_mutex_unlock(&ices_config->flush_lock);
            }
            /* Non-fatal shout error */
            else if(ret == 0)
			{
				LOG_ERROR2("Send error: %s (%s)", 
                        shout_get_error(sdsc->shout), strerror(errno));
				if(shout_get_errno(sdsc->shout) == SHOUTERR_SOCKET)
				{
					int i=0;

					/* While we're trying to reconnect, don't receive data
					 * to this instance, or we'll overflow once reconnect
					 * succeeds
					 */
					thread_mutex_lock(&ices_config->flush_lock);
					stream->skip = 1;

					/* Also, flush the current queue */
					input_flush_queue(stream->queue, 1);
					thread_mutex_unlock(&ices_config->flush_lock);
					
					while((i < stream->reconnect_attempts ||
							stream->reconnect_attempts==-1) && 
                            !ices_config->shutdown)
					{
						i++;
						LOG_WARN0("Trying reconnect after server socket error");
						shout_close(sdsc->shout);
						if((shouterr = shout_open(sdsc->shout)) == SHOUTERR_SUCCESS)
						{
							LOG_INFO3("Connected to server: %s:%d%s", 
                                    shout_get_host(sdsc->shout), shout_get_port(sdsc->shout), 
                                    shout_get_mount(sdsc->shout));
                            /* This stream can't restart until the next
                             * logical stream comes along, since the
                             * server won't have any cached headers for
                             * this source/connection. So, don't continue
                             * yet.
                             */
                            thread_mutex_lock(&ices_config->flush_lock);
                            stream->wait_for_critical = 1;
                            input_flush_queue(stream->queue, 0);
                            thread_mutex_unlock(&ices_config->flush_lock);
							break;
						}
						else
						{
							LOG_ERROR3("Failed to reconnect to %s:%d (%s)",
								shout_get_host(sdsc->shout),shout_get_port(sdsc->shout),
								shout_get_error(sdsc->shout));
							if(i==stream->reconnect_attempts)
							{
								LOG_ERROR0("Reconnect failed too many times, "
										  "giving up.");
                                /* We want to die now */
								stream->buffer_failures = MAX_ERRORS+1; 
							}
							else /* Don't try again too soon */
								sleep(stream->reconnect_delay); 
						}
					}
					stream->skip = 0;
				}
				stream->buffer_failures++;
			}
			stream_release_buffer(buffer);
		}
	}
	else
	{
		LOG_ERROR3("Failed initial connect to %s:%d (%s)", 
				shout_get_host(sdsc->shout),shout_get_port(sdsc->shout), shout_get_error(sdsc->shout));
	}
	
	shout_close(sdsc->shout);

    if(stream->savefile != NULL) 
        fclose(stream->savefile);

    shout_free(sdsc->shout);
	encode_clear(sdsc->enc);
	reencode_clear(sdsc->reenc);
    downmix_clear(sdsc->downmix);
    resample_clear(sdsc->resamp);
	vorbis_comment_clear(&sdsc->vc);

	stream->died = 1;
	return NULL;
}