void MediaServer::_buildPlaylist( Container* parent ) { for ( unsigned int i = 0; i < parent->getNumContainers(); i++ ) { Container* container = parent->getContainer( i ); input_item_t* p_input_item = input_item_New( _p_sd, "vlc://nop", parent->getTitle() ); input_item_AddSubItem( parent->getInputItem(), p_input_item ); container->setInputItem( p_input_item ); _buildPlaylist( container ); } for ( unsigned int i = 0; i < parent->getNumItems(); i++ ) { Item* item = parent->getItem( i ); input_item_t* p_input_item = input_item_New( _p_sd, item->getResource(), item->getTitle() ); assert( p_input_item ); input_item_AddSubItem( parent->getInputItem(), p_input_item ); item->setInputItem( p_input_item ); } }
static int Demux( demux_t *p_demux ) { char *psz_line; char *psz_uri = NULL; char *psz_parse; input_item_t *p_input; INIT_PLAYLIST_STUFF; psz_line = stream_ReadLine( p_demux->s ); while( psz_line ) { psz_parse = psz_line; /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++; /* if the line is the uri of the media item */ if( !strncasecmp( psz_parse, "<media src=\"", strlen( "<media src=\"" ) ) ) { psz_uri = ParseUriValue( psz_parse ); if( !EMPTY_STR(psz_uri) ) { psz_uri = ProcessMRL( psz_uri, p_demux->p_sys->psz_prefix ); MaybeFromLocaleRep( &psz_uri ); p_input = input_item_NewExt( p_demux, psz_uri, psz_uri, 0, NULL, 0, -1 ); input_item_AddSubItem( p_current_input, p_input ); } free( psz_uri ); } /* Fetch another line */ free( psz_line ); psz_line = stream_ReadLine( p_demux->s ); } HANDLE_PLAY_AND_RELEASE; var_Destroy( p_demux, "wpl-extvlcopt" ); return 0; /* Needed for correct operation of go back */ }
static int Demux( demux_t *p_demux ) { char *psz_url = NULL; size_t len = 0; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); len = strlen( "dvd://" ) + strlen( p_demux->psz_path ) - strlen( "VIDEO_TS.IFO" ); psz_url = (char *)malloc( len+1 ); snprintf( psz_url, len+1, "dvd://%s", p_demux->psz_path ); p_input = input_item_New( p_demux, psz_url, psz_url ); input_item_AddSubItem( p_current_input, p_input ); vlc_gc_decref( p_input ); vlc_gc_decref(p_current_input); return 0; /* Needed for correct operation of go back */ }
/* radio stations: * <stationlist> * <tunein base="/sbin/tunein-station.pls"></tunein> * <station name="the name" * mt="mime type" * id="the id" * br="bit rate" * genre="A big genre string" * ct="current track name/author/..." * lc="listener count"></station> * </stationlist> * * TV stations: * <stationlist> * <tunein base="/sbin/tunein-station.pls"></tunein> * <station name="the name" * id="the id" * br="bit rate" * rt="rating" * load="server load ?" * ct="current track name/author/..." * genre="A big genre string" * lc="listener count"></station> * </stationlist> **/ static int DemuxStation( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; input_item_t *p_input; char *psz_base = NULL; /* */ char *psz_name = NULL; /* genre name */ char *psz_mt = NULL; /* mime type */ char *psz_id = NULL; /* id */ char *psz_br = NULL; /* bit rate */ char *psz_genre = NULL; /* genre */ char *psz_ct = NULL; /* current track */ char *psz_lc = NULL; /* listener count */ /* If these are set then it's *not* a radio but a TV */ char *psz_rt = NULL; /* rating for shoutcast TV */ char *psz_load = NULL; /* load for shoutcast TV */ char *psz_eltname = NULL; /* tag name */ while( xml_ReaderRead( p_sys->p_xml_reader ) == 1 ) { int i_type; // Get the node type i_type = xml_ReaderNodeType( p_sys->p_xml_reader ); switch( i_type ) { // Error case -1: return -1; break; case XML_READER_STARTELEM: // Read the element name psz_eltname = xml_ReaderName( p_sys->p_xml_reader ); if( !psz_eltname ) return -1; // Read the attributes if( !strcmp( psz_eltname, "tunein" ) ) { while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS ) { char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader ); char *psz_attrvalue = xml_ReaderValue( p_sys->p_xml_reader ); if( !psz_attrname || !psz_attrvalue ) { free( psz_eltname ); free( psz_attrname ); free( psz_attrvalue ); return -1; } GET_VALUE( base ) else { msg_Warn( p_demux, "unexpected attribure %s in element %s", psz_attrname, psz_eltname ); } free( psz_attrname ); free( psz_attrvalue ); } } else if( !strcmp( psz_eltname, "station" ) ) { while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS ) { char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader ); char *psz_attrvalue = xml_ReaderValue( p_sys->p_xml_reader ); if( !psz_attrname || !psz_attrvalue ) { free( psz_eltname ); free( psz_attrname ); free( psz_attrvalue ); return -1; } GET_VALUE( name ) else GET_VALUE( mt ) else GET_VALUE( id ) else GET_VALUE( br ) else GET_VALUE( genre ) else GET_VALUE( ct ) else GET_VALUE( lc ) else GET_VALUE( rt ) else GET_VALUE( load ) else { msg_Warn( p_demux, "unexpected attribute %s in element %s", psz_attrname, psz_eltname ); } free( psz_attrname ); free( psz_attrvalue ); } } free( psz_eltname ); break; case XML_READER_TEXT: break; // End element case XML_READER_ENDELEM: // Read the element name psz_eltname = xml_ReaderName( p_sys->p_xml_reader ); if( !psz_eltname ) return -1; if( !strcmp( psz_eltname, "station" ) && ( psz_base || ( psz_rt && psz_load && ( p_sys->b_adult || strcmp( psz_rt, "NC17" ) ) ) ) ) { char *psz_mrl = NULL; if( psz_rt || psz_load ) { /* tv */ if( asprintf( &psz_mrl, SHOUTCAST_TV_TUNEIN_URL "%s", psz_id ) == -1) psz_mrl = NULL; } else { /* radio */ if( asprintf( &psz_mrl, SHOUTCAST_TUNEIN_BASE_URL "%s?id=%s", psz_base, psz_id ) == -1 ) psz_mrl = NULL; } p_input = input_item_New( p_demux, psz_mrl, psz_name ); input_item_CopyOptions( p_sys->p_current_input, p_input ); free( psz_mrl ); #define SADD_INFO( type, field ) \ if( field ) \ input_item_AddInfo( p_input, _("Shoutcast"), \ vlc_gettext(type), "%s", field ) SADD_INFO( N_("Mime"), psz_mt ); SADD_INFO( N_("Bitrate"), psz_br ); SADD_INFO( N_("Listeners"), psz_lc ); SADD_INFO( N_("Load"), psz_load ); if( psz_genre ) input_item_SetGenre( p_input, psz_genre ); if( psz_ct ) input_item_SetNowPlaying( p_input, psz_ct ); if( psz_rt ) input_item_SetRating( p_input, psz_rt ); input_item_AddSubItem( p_sys->p_current_input, p_input ); vlc_gc_decref( p_input ); FREENULL( psz_name ); FREENULL( psz_mt ); FREENULL( psz_id ); FREENULL( psz_br ); FREENULL( psz_genre ); FREENULL( psz_ct ); FREENULL( psz_lc ); FREENULL( psz_rt ); } free( psz_eltname ); break; } }
/* <genrelist> * <genre name="the name"></genre> * ... * </genrelist> **/ static int DemuxGenre( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; char *psz_name = NULL; /* genre name */ char *psz_eltname = NULL; /* tag name */ input_item_t *p_input; while( xml_ReaderRead( p_sys->p_xml_reader ) == 1 ) { int i_type; // Get the node type i_type = xml_ReaderNodeType( p_sys->p_xml_reader ); switch( i_type ) { // Error case -1: return -1; break; case XML_READER_STARTELEM: // Read the element name psz_eltname = xml_ReaderName( p_sys->p_xml_reader ); if( !psz_eltname ) return -1; if( !strcmp( psz_eltname, "genre" ) ) { // Read the attributes while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS ) { char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader ); char *psz_attrvalue = xml_ReaderValue( p_sys->p_xml_reader ); if( !psz_attrname || !psz_attrvalue ) { FREENULL(psz_attrname); FREENULL(psz_attrvalue); free(psz_eltname); /*FIXME: isn't return a bit too much. what about break*/ return -1; } GET_VALUE( name ) else { msg_Warn( p_demux, "unexpected attribure %s in element %s", psz_attrname,psz_eltname ); } free( psz_attrname ); free( psz_attrvalue ); } } free( psz_eltname ); psz_eltname = NULL; break; case XML_READER_TEXT: break; // End element case XML_READER_ENDELEM: // Read the element name psz_eltname = xml_ReaderName( p_sys->p_xml_reader ); if( !psz_eltname ) return -1; if( !strcmp( psz_eltname, "genre" ) ) { char* psz_mrl; if( asprintf( &psz_mrl, SHOUTCAST_BASE_URL "?genre=%s", psz_name ) != -1 ) { p_input = input_item_New( p_demux, psz_mrl, psz_name ); input_item_CopyOptions( p_sys->p_current_input, p_input ); free( psz_mrl ); input_item_AddSubItem( p_sys->p_current_input, p_input ); vlc_gc_decref( p_input ); } FREENULL( psz_name ); } FREENULL( psz_eltname ); break; } } return 0; }
static int Demux( demux_t *p_demux ) { char *psz_line; mtime_t i_duration = -1; char *psz_title = NULL, *psz_genre = NULL, *psz_tracknum = NULL, *psz_language = NULL, *psz_artist = NULL, *psz_album = NULL, *psz_date = NULL, *psz_publicher = NULL, *psz_encodedby = NULL, *psz_description = NULL, *psz_url = NULL, *psz_copyright = NULL, *psz_mrl = NULL; input_item_t *p_current_input = GetCurrentItem(p_demux); psz_line = stream_ReadLine( p_demux->s ); char *psz_parse = psz_line; /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++; /* if the 1st line is "AC", skip it */ /* TODO: using this information ? */ if( !strncasecmp( psz_parse, "AC", strlen( "AC" ) ) ) { free( psz_line ); psz_line = stream_ReadLine( p_demux->s ); } /* Loop on all lines */ while( psz_line ) { psz_parse = psz_line; /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++; /* filename */ if( !strncasecmp( psz_parse, "NM", strlen( "NM" ) ) ) { char *psz_tabvalue = ParseTabValue( psz_parse ); if( !EMPTY_STR(psz_tabvalue) ) { psz_mrl = ProcessMRL( psz_tabvalue, p_demux->p_sys->psz_prefix ); if( psz_mrl ) MaybeFromLocaleRep( &psz_mrl ); } free( psz_tabvalue ); } /* duration */ else if( !strncasecmp( psz_parse, "DR", strlen( "DR" ) ) ) { char *psz_tabvalue = ParseTabValue( psz_parse ); if( !EMPTY_STR(psz_tabvalue) ) { int i_parsed_duration = atoi( psz_tabvalue ); if( i_parsed_duration >= 0 ) i_duration = i_parsed_duration * INT64_C(1000); } free( psz_tabvalue ); } #define PARSE(tag,variable) \ else if( !strncasecmp( psz_parse, tag, strlen( tag ) ) ) \ variable = ParseTabValue( psz_parse ); PARSE( "TT", psz_title ) PARSE( "TG", psz_genre ) PARSE( "TR", psz_tracknum ) PARSE( "TL", psz_language ) PARSE( "TA", psz_artist ) PARSE( "TB", psz_album ) PARSE( "TY", psz_date ) PARSE( "TH", psz_publicher ) PARSE( "TE", psz_encodedby ) PARSE( "TC", psz_description ) PARSE( "TU", psz_url ) PARSE( "TO", psz_copyright ) #undef PARSE /* force a duration ? */ else if( !strncasecmp( psz_parse, "FD", strlen( "FD" ) ) ) {} /* end of file entry */ else if( !strncasecmp( psz_parse, "BR!", strlen( "BR!" ) ) ) { /* create the input item */ input_item_t *p_input = input_item_NewExt( p_demux, psz_mrl, psz_title, 0, NULL, 0, i_duration ); input_item_AddSubItem( p_current_input, p_input ); FREENULL( psz_mrl ); FREENULL( psz_title ); i_duration = -1; #define SET(variable, type) \ if( !EMPTY_STR(variable) ) \ { \ input_item_Set##type( p_input, variable ); \ FREENULL( variable ); \ } /* set the meta */ SET( psz_genre, Genre ); SET( psz_tracknum, TrackNum ); SET( psz_language, Language ); SET( psz_artist, Artist ); SET( psz_album, Album ); SET( psz_date, Date ); SET( psz_encodedby, EncodedBy ); SET( psz_description, Description ); SET( psz_copyright, Copyright ); #undef SET } else msg_Warn( p_demux, "invalid line '%s'", psz_parse ); /* Fetch another line */ free( psz_line ); psz_line = stream_ReadLine( p_demux->s ); } vlc_gc_decref(p_current_input); var_Destroy( p_demux, "zpl-extvlcopt" ); return 0; /* Needed for correct operation of go back */ }
/** * \brief demuxer function for XSPF parsing */ int Demux( demux_t *p_demux ) { int i_ret = 1; xml_t *p_xml = NULL; xml_reader_t *p_xml_reader = NULL; char *psz_name = NULL; INIT_PLAYLIST_STUFF; p_demux->p_sys->pp_tracklist = NULL; p_demux->p_sys->i_tracklist_entries = 0; p_demux->p_sys->i_track_id = -1; p_demux->p_sys->psz_base = NULL; /* create new xml parser from stream */ p_xml = xml_Create( p_demux ); if( !p_xml ) i_ret = -1; else { p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s ); if( !p_xml_reader ) i_ret = -1; } /* locating the root node */ if( i_ret == 1 ) { do { if( xml_ReaderRead( p_xml_reader ) != 1 ) { msg_Err( p_demux, "can't read xml stream" ); i_ret = -1; } } while( i_ret == VLC_SUCCESS && xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ); } /* checking root node name */ if( i_ret == 1 ) { psz_name = xml_ReaderName( p_xml_reader ); if( !psz_name || strcmp( psz_name, "playlist" ) ) { msg_Err( p_demux, "invalid root node name: %s", psz_name ); i_ret = -1; } FREE_NAME(); } if( i_ret == 1 ) i_ret = parse_playlist_node( p_demux, p_current_input, p_xml_reader, "playlist" ) ? 0 : -1; int i; for( i = 0 ; i < p_demux->p_sys->i_tracklist_entries ; i++ ) { input_item_t *p_new_input = p_demux->p_sys->pp_tracklist[i]; if( p_new_input ) { input_item_AddSubItem( p_current_input, p_new_input ); } } HANDLE_PLAY_AND_RELEASE; if( p_xml_reader ) xml_ReaderDelete( p_xml, p_xml_reader ); if( p_xml ) xml_Delete( p_xml ); return i_ret; /* Needed for correct operation of go back */ }
/** * Main demux callback function * @param p_demux: this demux object */ static int Demux( demux_t *p_demux ) { char *psz_line; char *psz_artist = NULL, *psz_album = NULL, *psz_genre = NULL, *psz_year = NULL; char *psz_author = NULL, *psz_title = NULL, *psz_copyright = NULL, *psz_cdnum = NULL, *psz_comments = NULL; int i_parsed_duration = 0; mtime_t i_duration = -1; const char **ppsz_options = NULL; int i_options = 0, i_start = 0, i_stop = 0; bool b_cleanup = false; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); psz_line = stream_ReadLine( p_demux->s ); while( psz_line ) { char *psz_parse = psz_line; /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++; if( *psz_parse == '#' ) { /* Ignore comments */ } else if( *psz_parse ) { char *psz_mrl, *psz_option_next, *psz_option; char *psz_param, *psz_value; /* Get the MRL from the file. Note that this might contain parameters of form ?param1=value1¶m2=value2 in a RAM file */ psz_mrl = ProcessMRL( psz_parse, p_demux->p_sys->psz_prefix ); b_cleanup = true; if ( !psz_mrl ) goto error; /* We have the MRL, now we have to check for options and parse them from MRL */ psz_option = strchr( psz_mrl, '?' ); /* Look for start of options */ if( psz_option ) { /* Remove options from MRL because VLC can't get the file otherwise */ *psz_option = '\0'; psz_option++; psz_option_next = psz_option; while( 1 ) /* Process each option */ { /* Look for end of first option which maybe a & or \0 */ psz_option = psz_option_next; psz_option_next = strchr( psz_option, '&' ); if( psz_option_next ) { *psz_option_next = '\0'; psz_option_next++; } else psz_option_next = strchr( psz_option, '\0' ); /* Quit if options are over */ if( psz_option_next == psz_option ) break; /* Parse out param and value */ psz_param = psz_option; psz_value = strchr( psz_option, '=' ); if( psz_value == NULL ) break; *psz_value = '\0'; psz_value++; /* Take action based on parameter value in the below if else structure */ /* TODO: Remove any quotes surrounding values if required */ if( !strcmp( psz_param, "clipinfo" ) ) { ParseClipInfo( psz_value, &psz_artist, &psz_title, &psz_album, &psz_genre, &psz_year, &psz_cdnum, &psz_comments ); /* clipinfo has various sub parameters, which is parsed by this function */ } else if( !strcmp( psz_param, "author" ) ) psz_author = decode_URI(psz_value); else if( !strcmp( psz_param, "start" ) ) { i_start = ParseTime( psz_value, strlen( psz_value ) ); char *temp; if( i_start ) { if( asprintf( &temp, ":start-time=%d", i_start ) != -1 ) INSERT_ELEM( ppsz_options, i_options, i_options, temp ); } } else if( !strcmp( psz_param, "end" ) ) { i_stop = ParseTime( psz_value, strlen( psz_value ) ); char *temp; if( i_stop ) { if( asprintf( &temp, ":stop-time=%d", i_stop ) != -1 ) INSERT_ELEM( ppsz_options, i_options, i_options, temp ); } } else if( !strcmp( psz_param, "title" ) ) psz_title = decode_URI(psz_value); else if( !strcmp( psz_param, "copyright" ) ) psz_copyright = decode_URI(psz_value); else { /* TODO: insert option anyway? Currently ignores*/ /* INSERT_ELEM( ppsz_options, i_options, i_options, psz_option ); */ } } } /* Create the input item and pump in all the options into playlist item */ p_input = input_item_NewExt( p_demux, psz_mrl, psz_title, i_options, ppsz_options, 0, i_duration ); if( !EMPTY_STR( psz_artist ) ) input_item_SetArtist( p_input, psz_artist ); if( !EMPTY_STR( psz_author ) ) input_item_SetPublisher( p_input, psz_author ); if( !EMPTY_STR( psz_title ) ) input_item_SetTitle( p_input, psz_title ); if( !EMPTY_STR( psz_copyright ) ) input_item_SetCopyright( p_input, psz_copyright ); if( !EMPTY_STR( psz_album ) ) input_item_SetAlbum( p_input, psz_album ); if( !EMPTY_STR( psz_genre ) ) input_item_SetGenre( p_input, psz_genre ); if( !EMPTY_STR( psz_year ) ) input_item_SetDate( p_input, psz_copyright ); if( !EMPTY_STR( psz_cdnum ) ) input_item_SetTrackNum( p_input, psz_cdnum ); if( !EMPTY_STR( psz_comments ) ) input_item_SetDescription( p_input, psz_comments ); input_item_AddSubItem( p_current_input, p_input ); vlc_gc_decref( p_input ); free( psz_mrl ); } error: /* Fetch another line */ free( psz_line ); psz_line = stream_ReadLine( p_demux->s ); if( !psz_line ) b_cleanup = true; if( b_cleanup ) { /* Cleanup state */ while( i_options-- ) free( (char*)ppsz_options[i_options] ); FREENULL( ppsz_options ); FREENULL( psz_artist ); FREENULL( psz_title ); FREENULL( psz_author ); FREENULL( psz_copyright ); FREENULL( psz_album ); FREENULL( psz_genre ); FREENULL( psz_year ); FREENULL( psz_cdnum ); FREENULL( psz_comments ); i_options = 0; i_parsed_duration = 0; i_duration = -1; i_start = 0; i_stop = 0; b_cleanup = false; } } vlc_gc_decref(p_current_input); var_Destroy( p_demux, "m3u-extvlcopt" ); return 0; /* Needed for correct operation of go back */ }
/** * \brief demuxer function for XSPF parsing */ int Demux( demux_t *p_demux ) { int i_ret = -1; xml_t *p_xml = NULL; xml_reader_t *p_xml_reader = NULL; char *psz_name = NULL; input_item_t *p_current_input = GetCurrentItem(p_demux); p_demux->p_sys->pp_tracklist = NULL; p_demux->p_sys->i_tracklist_entries = 0; p_demux->p_sys->i_track_id = -1; p_demux->p_sys->psz_base = NULL; /* create new xml parser from stream */ p_xml = xml_Create( p_demux ); if( !p_xml ) goto end; p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s ); if( !p_xml_reader ) goto end; /* locating the root node */ do { if( xml_ReaderRead( p_xml_reader ) != 1 ) { msg_Err( p_demux, "can't read xml stream" ); goto end; } } while( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ); /* checking root node name */ psz_name = xml_ReaderName( p_xml_reader ); if( !psz_name || strcmp( psz_name, "playlist" ) ) { msg_Err( p_demux, "invalid root node name: %s", psz_name ); free( psz_name ); goto end; } free( psz_name ); i_ret = parse_playlist_node( p_demux, p_current_input, p_xml_reader, "playlist" ) ? 0 : -1; for( int i = 0 ; i < p_demux->p_sys->i_tracklist_entries ; i++ ) { input_item_t *p_new_input = p_demux->p_sys->pp_tracklist[i]; if( p_new_input ) { input_item_AddSubItem( p_current_input, p_new_input ); } } end: vlc_gc_decref(p_current_input); if( p_xml_reader ) xml_ReaderDelete( p_xml, p_xml_reader ); if( p_xml ) xml_Delete( p_xml ); return i_ret; /* Needed for correct operation of go back */ }
static int Demux( demux_t *p_demux ) { char *psz_line; char *psz_name = NULL; char *psz_artist = NULL; int i_parsed_duration = 0; mtime_t i_duration = -1; const char**ppsz_options = NULL; char * (*pf_dup) (const char *) = p_demux->p_sys->pf_dup; int i_options = 0; bool b_cleanup = false; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); psz_line = stream_ReadLine( p_demux->s ); while( psz_line ) { char *psz_parse = psz_line; /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++; if( *psz_parse == '#' ) { /* Parse extra info */ /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' || *psz_parse == '#' ) psz_parse++; if( !*psz_parse ) goto error; if( !strncasecmp( psz_parse, "EXTINF:", sizeof("EXTINF:") -1 ) ) { /* Extended info */ psz_parse += sizeof("EXTINF:") - 1; parseEXTINF( psz_parse, &psz_artist, &psz_name, &i_parsed_duration ); if( i_parsed_duration >= 0 ) i_duration = i_parsed_duration * INT64_C(1000000); if( psz_name ) psz_name = pf_dup( psz_name ); if( psz_artist ) psz_artist = pf_dup( psz_artist ); } else if( !strncasecmp( psz_parse, "EXTVLCOPT:", sizeof("EXTVLCOPT:") -1 ) ) { /* VLC Option */ char *psz_option; psz_parse += sizeof("EXTVLCOPT:") -1; if( !*psz_parse ) goto error; psz_option = pf_dup( psz_parse ); if( psz_option ) INSERT_ELEM( ppsz_options, i_options, i_options, psz_option ); } } else if( !strncasecmp( psz_parse, "RTSPtext", sizeof("RTSPtext") -1 ) ) { ;/* special case to handle QuickTime RTSPtext redirect files */ } else if( *psz_parse ) { char *psz_mrl; psz_parse = pf_dup( psz_parse ); if( !psz_name && psz_parse ) /* Use filename as name for relative entries */ psz_name = strdup( psz_parse ); psz_mrl = ProcessMRL( psz_parse, p_demux->p_sys->psz_prefix ); b_cleanup = true; if( !psz_mrl ) goto error; p_input = input_item_NewExt( p_demux, psz_mrl, psz_name, i_options, ppsz_options, 0, i_duration ); LocaleFree( psz_parse ); free( psz_mrl ); if ( psz_artist && *psz_artist ) input_item_SetArtist( p_input, psz_artist ); if( psz_name ) input_item_SetTitle( p_input, psz_name ); input_item_AddSubItem( p_current_input, p_input ); vlc_gc_decref( p_input ); } error: /* Fetch another line */ free( psz_line ); psz_line = stream_ReadLine( p_demux->s ); if( !psz_line ) b_cleanup = true; if( b_cleanup ) { /* Cleanup state */ while( i_options-- ) free( (char*)ppsz_options[i_options] ); free( ppsz_options ); ppsz_options = NULL; i_options = 0; free( psz_name ); psz_name = NULL; free( psz_artist ); psz_artist = NULL; i_parsed_duration = 0; i_duration = -1; b_cleanup = false; } } vlc_gc_decref(p_current_input); var_Destroy( p_demux, "m3u-extvlcopt" ); return 0; /* Needed for correct operation of go back */ }