X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fplaylist%2Fb4s.c;h=0d550c4cafc27f0ff6e919e1d60085782c41cc71;hb=15172e6867ea91a40628edea89dce5d4d7039d79;hp=14b2d78a19f24faa1de515fc2f716235eb9a3989;hpb=fe087a38282e93addb25fa9598393e40ea233b09;p=vlc diff --git a/modules/demux/playlist/b4s.c b/modules/demux/playlist/b4s.c index 14b2d78a19..0d550c4caf 100644 --- a/modules/demux/playlist/b4s.c +++ b/modules/demux/playlist/b4s.c @@ -1,10 +1,10 @@ /***************************************************************************** * b4s.c : B4S playlist format import ***************************************************************************** - * Copyright (C) 2005 the VideoLAN team + * Copyright (C) 2005-2009 the VideoLAN team * $Id$ * - * Authors: Sigmund Augdal + * Authors: Sigmund Augdal Helberg * * 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 @@ -18,30 +18,25 @@ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* malloc(), free() */ -#include /* isspace() */ -#include -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include -#include /* ENOMEM */ #include "playlist.h" -#include "vlc_xml.h" struct demux_sys_t { - char *psz_prefix; - playlist_t *p_playlist; - xml_t *p_xml; - xml_reader_t *p_xml_reader; - int b_shout; }; /***************************************************************************** @@ -49,128 +44,56 @@ struct demux_sys_t *****************************************************************************/ static int Demux( demux_t *p_demux); static int Control( demux_t *p_demux, int i_query, va_list args ); -static char *get_next_token(char *cur_string); static int IsWhitespace( char *psz_string ); -static void ShoutcastAdd( playlist_t *p_playlist, playlist_item_t* p_genre, - playlist_item_t *p_bitrate, playlist_item_t *p_item, - char *psz_genre, char *psz_bitrate ); /***************************************************************************** * Import_B4S: main import function *****************************************************************************/ -int E_(Import_B4S)( vlc_object_t *p_this ) +int Import_B4S( vlc_object_t *p_this ) { - demux_t *p_demux = (demux_t *)p_this; - demux_sys_t *p_sys; - - char *psz_ext; - - psz_ext = strrchr ( p_demux->psz_path, '.' ); - - if( ( psz_ext && !strcasecmp( psz_ext, ".b4s") ) || - ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "b4s-open") ) || - ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "shout-b4s") ) ) - { - ; - } - else - { - return VLC_EGENERIC; - } - msg_Dbg( p_demux, "using b4s playlist import"); - - p_demux->pf_control = Control; - p_demux->pf_demux = Demux; - p_demux->p_sys = p_sys = malloc( sizeof(demux_sys_t) ); - if( p_sys == NULL ) - { - msg_Err( p_demux, "Out of memory" ); - return VLC_ENOMEM; - } - p_sys->b_shout = p_demux->psz_demux && - !strcmp(p_demux->psz_demux, "shout-b4s"); - p_sys->psz_prefix = E_(FindPrefix)( p_demux ); - p_sys->p_playlist = NULL; - p_sys->p_xml = NULL; - p_sys->p_xml_reader = NULL; - + DEMUX_BY_EXTENSION_OR_FORCED_MSG( ".b4s", "b4s-open", + "using B4S playlist reader" ); return VLC_SUCCESS; } /***************************************************************************** * Deactivate: frees unused data *****************************************************************************/ -void E_(Close_B4S)( vlc_object_t *p_this ) +void Close_B4S( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; demux_sys_t *p_sys = p_demux->p_sys; - if( p_sys->psz_prefix ) free( p_sys->psz_prefix ); - if( p_sys->p_playlist ) vlc_object_release( p_sys->p_playlist ); - if( p_sys->p_xml_reader ) xml_ReaderDelete( p_sys->p_xml, p_sys->p_xml_reader ); - if( p_sys->p_xml ) xml_Delete( p_sys->p_xml ); free( p_sys ); } static int Demux( demux_t *p_demux ) { - demux_sys_t *p_sys = p_demux->p_sys; - playlist_t *p_playlist; - playlist_item_t *p_item, *p_current; - playlist_item_t *p_bitrate = NULL, *p_genre = NULL; + int i_ret = -1; - vlc_bool_t b_play; - int i_ret; - - xml_t *p_xml; - xml_reader_t *p_xml_reader; + xml_reader_t *p_xml_reader = NULL; char *psz_elname = NULL; - int i_type, b_shoutcast; - char *psz_mrl = NULL, *psz_name = NULL, *psz_genre = NULL; + input_item_t *p_input; + char *psz_mrl = NULL, *psz_title = NULL, *psz_genre = NULL; char *psz_now = NULL, *psz_listeners = NULL, *psz_bitrate = NULL; + input_item_node_t *p_subitems = NULL; - - b_shoutcast = p_sys->b_shout; - - p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST, - FIND_PARENT ); - if( !p_playlist ) - { - msg_Err( p_demux, "can't find playlist" ); - return -1; - } - p_sys->p_playlist = p_playlist; - - b_play = E_(FindItem)( p_demux, p_playlist, &p_current ); - - playlist_ItemToNode( p_playlist, p_current ); - p_current->input.i_type = ITEM_TYPE_PLAYLIST; - if( b_shoutcast ) - { - p_genre = playlist_NodeCreate( p_playlist, p_current->pp_parents[0]->i_view, "Genre", p_current ); - playlist_CopyParents( p_current, p_genre ); - - p_bitrate = playlist_NodeCreate( p_playlist, p_current->pp_parents[0]->i_view, "Bitrate", p_current ); - playlist_CopyParents( p_current, p_bitrate ); - } - - p_xml = p_sys->p_xml = xml_Create( p_demux ); - if( !p_xml ) return -1; + input_item_t *p_current_input = GetCurrentItem(p_demux); psz_elname = stream_ReadLine( p_demux->s ); - if( psz_elname ) free( psz_elname ); - psz_elname = 0; + free( psz_elname ); + psz_elname = NULL; - p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s ); - if( !p_xml_reader ) return -1; - p_sys->p_xml_reader = p_xml_reader; + p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s ); + if( !p_xml_reader ) + goto end; /* xml */ /* check root node */ if( xml_ReaderRead( p_xml_reader ) != 1 ) { msg_Err( p_demux, "invalid file (no root node)" ); - return -1; + goto end; } if( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM || @@ -179,10 +102,9 @@ static int Demux( demux_t *p_demux ) { msg_Err( p_demux, "invalid root node %i, %s", xml_ReaderNodeType( p_xml_reader ), psz_elname ); - if( psz_elname ) free( psz_elname ); - return -1; + goto end; } - free( psz_elname ); + FREENULL( psz_elname ); /* root node should not have any attributes, and should only * contain the "playlist node */ @@ -193,31 +115,35 @@ static int Demux( demux_t *p_demux ) if( i_ret != 1 ) { msg_Err( p_demux, "invalid file (no child node)" ); - return -1; + goto end; } if( ( psz_elname = xml_ReaderName( p_xml_reader ) ) == NULL || strcmp( psz_elname, "playlist" ) ) { msg_Err( p_demux, "invalid child node %s", psz_elname ); - if( psz_elname ) free( psz_elname ); - return -1; + goto end; } - free( psz_elname ); psz_elname = 0; + FREENULL( psz_elname ); // Read the attributes while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { char *psz_name = xml_ReaderName( p_xml_reader ); char *psz_value = xml_ReaderValue( p_xml_reader ); - if( !psz_name || !psz_value ) return -1; + if( !psz_name || !psz_value ) + { + free( psz_name ); + free( psz_value ); + goto end; + } if( !strcmp( psz_name, "num_entries" ) ) { msg_Dbg( p_demux, "playlist has %d entries", atoi(psz_value) ); } else if( !strcmp( psz_name, "label" ) ) { - playlist_ItemSetName( p_current, psz_value ); + input_item_SetName( p_current_input, psz_value ); } else { @@ -228,43 +154,48 @@ static int Demux( demux_t *p_demux ) free( psz_value ); } + p_subitems = input_item_node_Create( p_current_input ); + while( (i_ret = xml_ReaderRead( p_xml_reader )) == 1 ) { // Get the node type - i_type = xml_ReaderNodeType( p_xml_reader ); - switch( i_type ) + switch( xml_ReaderNodeType( p_xml_reader ) ) { // Error case -1: - return -1; - break; + goto end; case XML_READER_STARTELEM: { // Read the element name - if( psz_elname ) free( psz_elname ); + free( psz_elname ); psz_elname = xml_ReaderName( p_xml_reader ); - if( !psz_elname ) return -1; - + if( !psz_elname ) + goto end; // Read the attributes while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { char *psz_name = xml_ReaderName( p_xml_reader ); char *psz_value = xml_ReaderValue( p_xml_reader ); - if( !psz_name || !psz_value ) return -1; + if( !psz_name || !psz_value ) + { + free( psz_name ); + free( psz_value ); + goto end; + } if( !strcmp( psz_elname, "entry" ) && !strcmp( psz_name, "Playstring" ) ) { - psz_mrl = strdup( psz_value ); + psz_mrl = psz_value; } else { - msg_Warn( p_demux, "unexpected attribure %s in element %s", + msg_Warn( p_demux, "unexpected attribute %s in element %s", psz_name, psz_elname ); + free( psz_value ); } free( psz_name ); - free( psz_value ); } break; } @@ -278,34 +209,34 @@ static int Demux( demux_t *p_demux ) } if( !strcmp( psz_elname, "Name" ) ) { - psz_name = strdup( psz_text ); + psz_title = psz_text; } else if( !strcmp( psz_elname, "Genre" ) ) { - psz_genre = strdup( psz_text ); + psz_genre = psz_text; } else if( !strcmp( psz_elname, "Nowplaying" ) ) { - psz_now = strdup( psz_text ); + psz_now = psz_text; } else if( !strcmp( psz_elname, "Listeners" ) ) { - psz_listeners = strdup( psz_text ); + psz_listeners = psz_text; } else if( !strcmp( psz_elname, "Bitrate" ) ) { - psz_bitrate = strdup( psz_text ); + psz_bitrate = psz_text; } else if( !strcmp( psz_elname, "" ) ) { - ; + free( psz_text ); } else { msg_Warn( p_demux, "unexpected text in element '%s'", psz_elname ); + free( psz_text ); } - free( psz_text ); break; } // End element @@ -314,97 +245,31 @@ static int Demux( demux_t *p_demux ) // Read the element name free( psz_elname ); psz_elname = xml_ReaderName( p_xml_reader ); - if( !psz_elname ) return -1; + if( !psz_elname ) + goto end; if( !strcmp( psz_elname, "entry" ) ) { - p_item = playlist_ItemNew( p_playlist, psz_mrl, psz_name ); + p_input = input_item_New( p_demux, psz_mrl, psz_title ); if( psz_now ) - { - vlc_input_item_AddInfo( &(p_item->input), - _("Meta-information"), - _( VLC_META_NOW_PLAYING ), - "%s", - psz_now ); - } + input_item_SetNowPlaying( p_input, psz_now ); if( psz_genre ) - { - vlc_input_item_AddInfo( &p_item->input, - _("Meta-information"), - _( VLC_META_GENRE ), - "%s", - psz_genre ); - } + input_item_SetGenre( p_input, psz_genre ); if( psz_listeners ) - { - vlc_input_item_AddInfo( &p_item->input, - _("Meta-information"), - _( "Listeners" ), - "%s", - psz_listeners ); - } + msg_Err( p_demux, "Unsupported meta listeners" ); if( psz_bitrate ) - { - vlc_input_item_AddInfo( &p_item->input, - _("Meta-information"), - _( "Bitrate" ), - "%s", - psz_bitrate ); - } - playlist_NodeAddItem( p_playlist, p_item, - p_current->pp_parents[0]->i_view, - p_current, PLAYLIST_APPEND, - PLAYLIST_END ); - - /* We need to declare the parents of the node as the - * * same of the parent's ones */ - playlist_CopyParents( p_current, p_item ); - - vlc_input_item_CopyOptions( &p_current->input, - &p_item->input ); - if( b_shoutcast ) - { - char *psz_genreToken; - char *psz_otherToken; - int i = 0; - - psz_genreToken = psz_genre; - - /* split up the combined genre string form - shoutcast and add the individual genres */ - while ( psz_genreToken && - ( psz_otherToken = get_next_token(psz_genreToken ))) - { - if( strlen(psz_genreToken)>2 ) - /* We dont want genres below 2 letters, - this gets rid of alot of junk*/ - { - /* lowercase everything */ - for( i=0; psz_genreToken[i]!=0; i++ ) - psz_genreToken[i] = - tolower(psz_genreToken[i]); - /* Make first letter uppercase, purely cosmetical */ - psz_genreToken[0] = - toupper( psz_genreToken[0] ); - ShoutcastAdd( p_playlist, p_genre, - p_bitrate, p_item, - psz_genreToken, psz_bitrate ); - - psz_genreToken = psz_otherToken; - } - } - } - -#define FREE(a) if( a ) free( a ); a = NULL; - FREE( psz_name ); - FREE( psz_mrl ); - FREE( psz_genre ); - FREE( psz_bitrate ); - FREE( psz_listeners ); - FREE( psz_now ); -#undef FREE + msg_Err( p_demux, "Unsupported meta bitrate" ); + + input_item_node_AppendItem( p_subitems, p_input ); + vlc_gc_decref( p_input ); + FREENULL( psz_title ); + FREENULL( psz_mrl ); + FREENULL( psz_genre ); + FREENULL( psz_bitrate ); + FREENULL( psz_listeners ); + FREENULL( psz_now ); } free( psz_elname ); - psz_elname = strdup(""); + psz_elname = strdup( "" ); break; } @@ -414,42 +279,27 @@ static int Demux( demux_t *p_demux ) if( i_ret != 0 ) { msg_Warn( p_demux, "error while parsing data" ); - } - if( b_shoutcast ) - { - vlc_mutex_lock( &p_playlist->object_lock ); - playlist_NodeSort( p_playlist, p_bitrate, SORT_TITLE_NUMERIC, ORDER_NORMAL ); - vlc_mutex_unlock( &p_playlist->object_lock ); + i_ret = 0; /* Needed for correct operation of go back */ } - /* Go back and play the playlist */ - if( b_play && p_playlist->status.p_item && - p_playlist->status.p_item->i_children > 0 ) - { - playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, - p_playlist->status.i_view, - p_playlist->status.p_item, - p_playlist->status.p_item->pp_children[0] ); - } - - vlc_object_release( p_playlist ); - p_sys->p_playlist = NULL; - return VLC_SUCCESS; +end: + free( psz_elname ); + + if( p_subitems ) + input_item_node_PostAndDelete( p_subitems ); + + vlc_gc_decref( p_current_input ); + if( p_xml_reader ) + xml_ReaderDelete( p_xml_reader ); + return i_ret; } static int Control( demux_t *p_demux, int i_query, va_list args ) { + VLC_UNUSED(p_demux); VLC_UNUSED(i_query); VLC_UNUSED(args); return VLC_EGENERIC; } -static char *get_next_token(char *cur_string) { - while (*cur_string && !isspace(*cur_string)) cur_string++; - if (!*cur_string) return NULL; - *cur_string++ = '\0'; - while (*cur_string && isspace(*cur_string)) cur_string++; - return cur_string; -} - static int IsWhitespace( char *psz_string ) { while( *psz_string ) @@ -457,44 +307,9 @@ static int IsWhitespace( char *psz_string ) if( *psz_string != ' ' && *psz_string != '\t' && *psz_string != '\r' && *psz_string != '\n' ) { - return VLC_FALSE; + return false; } psz_string++; } - return VLC_TRUE; -} - -static void ShoutcastAdd( playlist_t *p_playlist, playlist_item_t* p_genre, - playlist_item_t *p_bitrate, playlist_item_t *p_item, - char *psz_genre, char *psz_bitrate ) -{ - playlist_item_t *p_parent; - if( psz_bitrate ) - { - playlist_item_t *p_copy = playlist_ItemCopy(p_playlist,p_item); - p_parent = playlist_ChildSearchName( p_bitrate, psz_bitrate ); - if( !p_parent ) - { - p_parent = playlist_NodeCreate( p_playlist, p_genre->pp_parents[0]->i_view, psz_bitrate, - p_bitrate ); - playlist_CopyParents( p_bitrate, p_parent ); - } - playlist_NodeAddItem( p_playlist, p_copy, p_parent->pp_parents[0]->i_view, p_parent, PLAYLIST_APPEND, PLAYLIST_END ); - playlist_CopyParents( p_parent, p_copy ); - - } - - if( psz_genre ) - { - playlist_item_t *p_copy = playlist_ItemCopy(p_playlist,p_item); - p_parent = playlist_ChildSearchName( p_genre, psz_genre ); - if( !p_parent ) - { - p_parent = playlist_NodeCreate( p_playlist, p_genre->pp_parents[0]->i_view, psz_genre, - p_genre ); - playlist_CopyParents( p_genre, p_parent ); - } - playlist_NodeAddItem( p_playlist, p_copy, p_parent->pp_parents[0]->i_view, p_parent, PLAYLIST_APPEND, PLAYLIST_END ); - playlist_CopyParents( p_parent, p_copy ); - } + return true; }