]> git.sesse.net Git - vlc/blobdiff - modules/access_output/shout.c
voc: remove useless #include
[vlc] / modules / access_output / shout.c
index 5a73958666648492a5e91e98fb4c959482f76bca..1c0579b125296395e898a9e22c75c6d369102500 100644 (file)
@@ -49,6 +49,7 @@
 #include <vlc_plugin.h>
 #include <vlc_sout.h>
 #include <vlc_block.h>
+#include <vlc_url.h>
 
 #include <shout/shout.h>
 
@@ -106,36 +107,35 @@ static void Close( vlc_object_t * );
                            "website. Requires the bitrate information specified for " \
                            "shoutcast. Requires Ogg streaming for icecast." )
 
-vlc_module_begin();
-    set_description( N_("IceCAST output") );
-    set_shortname( "Shoutcast" );
-    set_capability( "sout access", 50 );
-    set_category( CAT_SOUT );
-    set_subcategory( SUBCAT_SOUT_ACO );
-    add_shortcut( "shout" );
-    add_string( SOUT_CFG_PREFIX "name", "VLC media player - Live stream", NULL,
-                NAME_TEXT, NAME_LONGTEXT, false );
-    add_string( SOUT_CFG_PREFIX "description",
-                 "Live stream from VLC media player", NULL,
-                DESCRIPTION_TEXT, DESCRIPTION_LONGTEXT, false );
-    add_bool(   SOUT_CFG_PREFIX "mp3", false, NULL,
-                MP3_TEXT, MP3_LONGTEXT, true );
-    add_string( SOUT_CFG_PREFIX "genre", "Alternative", NULL,
-                GENRE_TEXT, GENRE_LONGTEXT, false );
-    add_string( SOUT_CFG_PREFIX "url", "http://www.videolan.org/vlc", NULL,
-                URL_TEXT, URL_LONGTEXT, false );
-    add_string( SOUT_CFG_PREFIX "bitrate", "", NULL,
-                BITRATE_TEXT, BITRATE_LONGTEXT, false );
-    add_string( SOUT_CFG_PREFIX "samplerate", "", NULL,
-                SAMPLERATE_TEXT, SAMPLERATE_LONGTEXT, false );
-    add_string( SOUT_CFG_PREFIX "channels", "", NULL,
-                CHANNELS_TEXT, CHANNELS_LONGTEXT, false );
-    add_string( SOUT_CFG_PREFIX "quality", "", NULL,
-                QUALITY_TEXT, QUALITY_LONGTEXT, false );
-    add_bool(   SOUT_CFG_PREFIX "public", false, NULL,
-                PUBLIC_TEXT, PUBLIC_LONGTEXT, true );
-    set_callbacks( Open, Close );
-vlc_module_end();
+vlc_module_begin ()
+    set_description( N_("IceCAST output") )
+    set_shortname( "Shoutcast" )
+    set_capability( "sout access", 0 )
+    set_category( CAT_SOUT )
+    set_subcategory( SUBCAT_SOUT_ACO )
+    add_shortcut( "shout" )
+    add_string( SOUT_CFG_PREFIX "name", "VLC media player - Live stream",
+                NAME_TEXT, NAME_LONGTEXT, false )
+    add_string( SOUT_CFG_PREFIX "description", "Live stream from VLC media player",
+                DESCRIPTION_TEXT, DESCRIPTION_LONGTEXT, false )
+    add_bool(   SOUT_CFG_PREFIX "mp3", false,
+                MP3_TEXT, MP3_LONGTEXT, true )
+    add_string( SOUT_CFG_PREFIX "genre", "Alternative",
+                GENRE_TEXT, GENRE_LONGTEXT, false )
+    add_string( SOUT_CFG_PREFIX "url", "http://www.videolan.org/vlc",
+                URL_TEXT, URL_LONGTEXT, false )
+    add_string( SOUT_CFG_PREFIX "bitrate", "",
+                BITRATE_TEXT, BITRATE_LONGTEXT, false )
+    add_string( SOUT_CFG_PREFIX "samplerate", "",
+                SAMPLERATE_TEXT, SAMPLERATE_LONGTEXT, false )
+    add_string( SOUT_CFG_PREFIX "channels", "",
+                CHANNELS_TEXT, CHANNELS_LONGTEXT, false )
+    add_string( SOUT_CFG_PREFIX "quality", "",
+                QUALITY_TEXT, QUALITY_LONGTEXT, false )
+    add_bool(   SOUT_CFG_PREFIX "public", false,
+                PUBLIC_TEXT, PUBLIC_LONGTEXT, true )
+    set_callbacks( Open, Close )
+vlc_module_end ()
 
 /*****************************************************************************
  * Exported prototypes
@@ -167,20 +167,13 @@ static int Open( vlc_object_t *p_this )
     sout_access_out_sys_t *p_sys;
     shout_t *p_shout;
     long i_ret;
-    unsigned int i_port;
-    vlc_value_t val;
-
-    char *psz_accessname = NULL;
-    char *psz_parser = NULL;
-    char *psz_user = NULL;
-    char *psz_pass = NULL;
-    char *psz_host = NULL;
-    char *psz_mount = NULL;
-    char *psz_name = NULL;
-    char *psz_description = NULL;
-    char *tmp_port = NULL;
-    char *psz_genre = NULL;
-    char *psz_url = NULL;
+    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 );
 
@@ -191,66 +184,30 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
-    psz_accessname = psz_parser = strdup( p_access->psz_path );
-    if( !psz_parser )
-        return VLC_ENOMEM;
-
-    /* Parse connection data user:pwd@host:port/mountpoint */
-    psz_user = psz_parser;
-    while( psz_parser[0] && psz_parser[0] != ':' ) psz_parser++;
-    if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; }
-    psz_pass = psz_parser;
-    while( psz_parser[0] && psz_parser[0] != '@' ) psz_parser++;
-    if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; }
-    psz_host = psz_parser;
-    while( psz_parser[0] && psz_parser[0] != ':' ) psz_parser++;
-    if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; }
-    tmp_port = psz_parser;
-    while( psz_parser[0] && psz_parser[0] != '/' ) psz_parser++;
-    if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; }
-    psz_mount = psz_parser;
-
-    i_port = atoi( tmp_port );
+    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 )
     {
-        free( psz_accessname );
+        vlc_UrlClean( &url );
         return VLC_ENOMEM;
     }
 
-    var_Get( p_access, SOUT_CFG_PREFIX "name", &val );
-    if( *val.psz_string )
-        psz_name = val.psz_string;
-    else
-        free( val.psz_string );
-
-    var_Get( p_access, SOUT_CFG_PREFIX "description", &val );
-    if( *val.psz_string )
-        psz_description = val.psz_string;
-    else
-        free( val.psz_string );
-
-    var_Get( p_access, SOUT_CFG_PREFIX "genre", &val );
-    if( *val.psz_string )
-        psz_genre = val.psz_string;
-    else
-        free( val.psz_string );
-
-    var_Get( p_access, SOUT_CFG_PREFIX "url", &val );
-    if( *val.psz_string )
-        psz_url = val.psz_string;
-    else
-        free( val.psz_string );
+    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, psz_host ) != SHOUTERR_SUCCESS
+         || 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, i_port ) != SHOUTERR_SUCCESS
-         || shout_set_password( p_shout, psz_pass ) != SHOUTERR_SUCCESS
-         || shout_set_mount( p_shout, psz_mount ) != SHOUTERR_SUCCESS
-         || shout_set_user( p_shout, psz_user ) != 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
@@ -260,14 +217,13 @@ static int Open( vlc_object_t *p_this )
       )
     {
         msg_Err( p_access, "failed to initialize shout streaming to %s:%i/%s",
-                 psz_host, i_port, psz_mount );
-        free( p_access->p_sys );
-        free( psz_accessname );
+                 url.psz_host, url.i_port, url.psz_path );
+
         free( psz_name );
         free( psz_description );
         free( psz_genre );
         free( psz_url );
-        return VLC_EGENERIC;
+        goto error;
     }
 
     free( psz_name );
@@ -275,33 +231,26 @@ static int Open( vlc_object_t *p_this )
     free( psz_genre );
     free( psz_url );
 
-    var_Get( p_access, SOUT_CFG_PREFIX "mp3", &val );
-    if( val.b_bool == true )
-        i_ret = shout_set_format( p_shout, SHOUT_FORMAT_MP3 );
-    else
-        i_ret = shout_set_format( p_shout, SHOUT_FORMAT_OGG );
+    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" );
-        free( p_access->p_sys );
-        free( psz_accessname );
-        return VLC_EGENERIC;
+        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 */
-    var_Get( p_access, SOUT_CFG_PREFIX "bitrate", &val );
-    if( *val.psz_string )
+    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "bitrate" );
+    if( psz_val )
     {
-        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_BITRATE, val.psz_string );
+        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" );
-            free( val.psz_string );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
     else
@@ -310,71 +259,55 @@ static int Open( vlc_object_t *p_this )
            listings (sorting, stream info etc.) */
         msg_Warn( p_access, "no bitrate information specified (required for listing " \
                             "the server as public on the shoutcast website)" );
-        free( val.psz_string );
     }
 
     /* 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 */
 
-    var_Get( p_access, SOUT_CFG_PREFIX "samplerate", &val );
-    if( *val.psz_string )
+    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "samplerate" );
+    if( psz_val )
     {
-        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_SAMPLERATE, val.psz_string );
+        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" );
-            free( val.psz_string );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
-    else
-        free( val.psz_string );
 
-    var_Get( p_access, SOUT_CFG_PREFIX "channels", &val );
-    if( *val.psz_string )
+    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "channels" );
+    if( psz_val )
     {
-        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_CHANNELS, val.psz_string );
+        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" );
-            free( val.psz_string );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
-    else
-        free( val.psz_string );
 
-    var_Get( p_access, SOUT_CFG_PREFIX "quality", &val );
-    if( *val.psz_string )
+    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "quality" );
+    if( psz_val )
     {
-        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_QUALITY, val.psz_string );
+        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" );
-            free( val.psz_string );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
-    else
-        free( val.psz_string );
 
-    var_Get( p_access, SOUT_CFG_PREFIX "public", &val );
-    if( val.b_bool == true )
+    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" );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
 
@@ -395,9 +328,7 @@ static int Open( vlc_object_t *p_this )
         if( i_ret != SHOUTERR_SUCCESS )
         {
             msg_Err( p_access, "failed to set the protocol to 'icy'" );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
         i_ret = shout_open( p_shout );
         if( i_ret == SHOUTERR_SUCCESS )
@@ -421,9 +352,7 @@ static int Open( vlc_object_t *p_this )
             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;
+                goto error;
             }
             i_ret = shout_open( p_shout );
             if( i_ret == SHOUTERR_SUCCESS )
@@ -452,10 +381,8 @@ static int Open( vlc_object_t *p_this )
     if( i_ret != SHOUTERR_CONNECTED )
     {
         msg_Err( p_access, "failed to open shout stream to %s:%i/%s: %s",
-                 psz_host, i_port, psz_mount, shout_get_error(p_shout) );
-        free( p_access->p_sys );
-        free( psz_accessname );
-        return VLC_EGENERIC;
+                 url.psz_host, url.i_port, url.psz_path, shout_get_error(p_shout) );
+        goto error;
     }
 
     p_access->pf_write = Write;
@@ -463,10 +390,17 @@ static int Open( vlc_object_t *p_this )
     p_access->pf_control = Control;
 
     msg_Dbg( p_access, "shout access output opened (%s@%s:%i/%s)",
-             psz_user, psz_host, i_port, psz_mount );
-    free( psz_accessname );
+             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;
 }
 
 /*****************************************************************************
@@ -475,13 +409,15 @@ static int Open( vlc_object_t *p_this )
 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_access->p_sys && p_access->p_sys->p_shout )
+    if( p_sys->p_shout )
     {
-        shout_close( p_access->p_sys->p_shout );
+        shout_close( p_sys->p_shout );
+        shout_free( p_sys->p_shout );
         shout_shutdown();
     }
-    free( p_access->p_sys );
+    free( p_sys );
     msg_Dbg( p_access, "shout access output closed" );
 }
 
@@ -507,15 +443,15 @@ static int Control( sout_access_out_t *p_access, int i_query, va_list args )
  *****************************************************************************/
 static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
 {
+    sout_access_out_sys_t *p_sys = p_access->p_sys;
     size_t i_write = 0;
 
-    shout_sync( p_access->p_sys->p_shout );
+    shout_sync( p_sys->p_shout );
     while( p_buffer )
     {
         block_t *p_next = p_buffer->p_next;
 
-        if( shout_send( p_access->p_sys->p_shout,
-                        p_buffer->p_buffer, p_buffer->i_buffer )
+        if( shout_send( p_sys->p_shout, p_buffer->p_buffer, p_buffer->i_buffer )
              == SHOUTERR_SUCCESS )
         {
             i_write += p_buffer->i_buffer;
@@ -523,24 +459,24 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
         else
         {
             msg_Err( p_access, "cannot write to stream: %s",
-                     shout_get_error(p_access->p_sys->p_shout) );
+                     shout_get_error( p_sys->p_shout ) );
 
             /* 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 );
+            shout_close( p_sys->p_shout );
             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 )
+            if( shout_open( p_sys->p_shout ) == SHOUTERR_SUCCESS )
             {
-                shout_sync( p_access->p_sys->p_shout );
+                shout_sync( p_sys->p_shout );
                 msg_Warn( p_access, "reconnected to server" );
             }
             else
             {
                 msg_Err( p_access, "failed to reconnect to server" );
-                block_ChainRelease (p_buffer);
+                block_ChainRelease( p_buffer );
                 return VLC_EGENERIC;
             }
 
@@ -560,6 +496,7 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
  *****************************************************************************/
 static int Seek( sout_access_out_t *p_access, off_t i_pos )
 {
+    VLC_UNUSED(i_pos);
     msg_Err( p_access, "cannot seek on shout" );
     return VLC_EGENERIC;
 }