]> git.sesse.net Git - vlc/blobdiff - modules/access_output/shout.c
revert [23722]
[vlc] / modules / access_output / shout.c
index c07e437e23e6bfc23c4dba016f5404a7b3cad749..d3eea7f894d16444c31dbee29bdb88245aa01fd9 100644 (file)
@@ -144,9 +144,8 @@ static const char *ppsz_sout_options[] = {
 /*****************************************************************************
  * Exported prototypes
  *****************************************************************************/
-static int Write( sout_access_out_t *, block_t * );
+static ssize_t Write( sout_access_out_t *, block_t * );
 static int Seek ( sout_access_out_t *, off_t  );
-static int Read ( sout_access_out_t *, block_t * );
 
 struct sout_access_out_sys_t
 {
@@ -364,17 +363,10 @@ static int Open( vlc_object_t *p_this )
         }
     }
 
-    /* Shoutcast using ICY protocol */
-    i_ret = shout_open( p_shout );
-    if( i_ret == SHOUTERR_SUCCESS )
+    /* Connect at startup. Cycle through the possible protocols. */
+    i_ret = shout_get_connected( p_shout );
+    while ( i_ret != SHOUTERR_CONNECTED )
     {
-        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 )
@@ -382,34 +374,66 @@ static int Open( vlc_object_t *p_this )
             i_ret = SHOUTERR_UNCONNECTED;
         }
 
-        /* IceCAST using HTTP protocol */
-        i_ret = shout_set_protocol( p_shout, SHOUT_PROTOCOL_HTTP );
+        /* 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 'http'" );
+            msg_Err( p_access, "failed to set the protocol to 'icy'" );
             free( p_access->p_sys );
             free( psz_accessname );
             return VLC_EGENERIC;
         }
-
         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" );
+            msg_Dbg( p_access, "connected using 'icy' (shoutcast) protocol" );
         }
         else
-            msg_Warn( p_access, "failed to connect using 'http' (icecast 2.x) protocol " );
-    }
+        {
+            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'" );
+                free( p_access->p_sys );
+                free( psz_accessname );
+                return VLC_EGENERIC;
+            }
+            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 );
-    }
+        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",
@@ -420,7 +444,6 @@ static int Open( vlc_object_t *p_this )
     }
 
     p_access->pf_write = Write;
-    p_access->pf_read  = Read;
     p_access->pf_seek  = Seek;
 
     msg_Dbg( p_access, "shout access output opened (%s@%s:%i/%s)",
@@ -460,22 +483,12 @@ static void Close( vlc_object_t * p_this )
     msg_Dbg( p_access, "shout access output closed" );
 }
 
-/*****************************************************************************
- * Read: standard read -- not supported
- *****************************************************************************/
-static int Read( sout_access_out_t *p_access, block_t *p_buffer )
-{
-    msg_Err( p_access, "cannot read from shout" );
-    return VLC_EGENERIC;
-}
-
 /*****************************************************************************
  * Write: standard write
  *****************************************************************************/
-static int Write( sout_access_out_t *p_access, block_t *p_buffer )
+static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
 {
     size_t i_write = 0;
-    long i_ret;
 
     shout_sync( p_access->p_sys->p_shout );
     while( p_buffer )
@@ -493,12 +506,16 @@ static int Write( sout_access_out_t *p_access, block_t *p_buffer )
             msg_Err( p_access, "cannot write to stream: %s",
                      shout_get_error(p_access->p_sys->p_shout) );
 
-            /* This can be caused by a server disconnect. Reconnecting might help... */
+            /* The most common cause seems to be a server disconnect, resulting in a
+               Socket Error which can only be fixed by closing and reconnecting.
+               Since we already began with a working connection, the most feasable
+               approach to get out of this error status is a (timed) reconnect approach. */
             shout_close( p_access->p_sys->p_shout );
-            msg_Warn( p_access, "server unavailable? waiting 30 seconds to reconnect..." );
-            msleep( 30000000 );
+            msg_Warn( p_access, "server unavailable? trying to reconnect..." );
+            /* Re-open the connection (protocol params have already been set) and re-sync */
             if( shout_open( p_access->p_sys->p_shout ) == SHOUTERR_SUCCESS )
             {
+                shout_sync( p_access->p_sys->p_shout );
                 msg_Warn( p_access, "reconnected to server" );
             }
             else