/***************************************************************************** * Deactivate: frees unused data *****************************************************************************/ void Close_Shoutcast( 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->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 ); }
void CloseDemux( demux_t* p_demux ) { demux_sys_t* p_sys = p_demux->p_sys; if( p_sys->p_rootnode ) tt_node_RecursiveDelete( p_sys->p_rootnode ); if( p_sys->p_es ) es_out_Del( p_demux->out, p_sys->p_es ); if( p_sys->p_reader ) xml_ReaderDelete( p_sys->p_reader ); if( p_sys->p_xml ) xml_Delete( p_sys->p_xml ); free( p_sys->times.p_array ); free( p_sys ); }
/**************************************************************************** * FetchRSS (or Atom) feeds ***************************************************************************/ static rss_feed_t* FetchRSS( filter_t *p_filter ) { filter_sys_t *p_sys = p_filter->p_sys; stream_t *p_stream; xml_t *p_xml; xml_reader_t *p_xml_reader; int i_feed; /* These data are not modified after the creation of the module so we don't need to hold the lock */ int i_feeds = p_sys->i_feeds; bool b_images = p_sys->b_images; /* Allocate a new structure */ rss_feed_t *p_feeds = (rss_feed_t *)malloc( i_feeds * sizeof( rss_feed_t ) ); // sunqueen modify if( !p_feeds ) return NULL; p_xml = xml_Create( p_filter ); if( !p_xml ) { msg_Err( p_filter, "Failed to open XML parser" ); free( p_feeds ); return NULL; } /* Fetch all feeds and parse them */ for( i_feed = 0; i_feed < i_feeds; i_feed++ ) { rss_feed_t *p_feed = p_feeds + i_feed; rss_feed_t *p_old_feed = p_sys->p_feeds + i_feed; /* Initialize the structure */ p_feed->psz_title = NULL; p_feed->psz_description = NULL; p_feed->psz_link = NULL; p_feed->psz_image = NULL; p_feed->p_pic = NULL; p_feed->i_items = 0; p_feed->p_items = NULL; p_feed->psz_url = strdup( p_old_feed->psz_url ); /* Fetch the feed */ msg_Dbg( p_filter, "opening %s RSS/Atom feed ...", p_feed->psz_url ); p_stream = stream_UrlNew( p_filter, p_feed->psz_url ); if( !p_stream ) { msg_Err( p_filter, "Failed to open %s for reading", p_feed->psz_url ); p_xml_reader = NULL; goto error; } p_xml_reader = xml_ReaderCreate( p_xml, p_stream ); if( !p_xml_reader ) { msg_Err( p_filter, "Failed to open %s for parsing", p_feed->psz_url ); goto error; } /* Parse the feed */ if( !ParseFeed( p_filter, p_xml_reader, p_feed ) ) goto error; /* If we have a image: load it if requiere */ if( b_images && p_feed->psz_image && !p_feed->p_pic ) { p_feed->p_pic = LoadImage( p_filter, p_feed->psz_image ); } msg_Dbg( p_filter, "done with %s RSS/Atom feed", p_feed->psz_url ); xml_ReaderDelete( p_xml_reader ); stream_Delete( p_stream ); } xml_Delete( p_xml ); return p_feeds; error: FreeRSS( p_feeds, i_feed + 1 ); if( p_xml_reader ) xml_ReaderDelete( p_xml_reader ); if( p_stream ) stream_Delete( p_stream ); if( p_xml ) xml_Delete( p_xml ); return NULL; }
XMLParser::~XMLParser() { if( m_pReader ) xml_ReaderDelete( m_pReader ); if( m_pXML ) xml_Delete( m_pXML ); if( m_pStream ) stream_Delete( m_pStream ); }
static int Demux( demux_t *p_demux ) { int i_ret = -1; xml_t *p_xml; xml_reader_t *p_xml_reader = NULL; char *psz_elname = 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; input_item_t *p_current_input = GetCurrentItem(p_demux); p_xml = xml_Create( p_demux ); if( !p_xml ) goto end; psz_elname = stream_ReadLine( p_demux->s ); free( psz_elname ); psz_elname = NULL; p_xml_reader = xml_ReaderCreate( p_xml, 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)" ); goto end; } if( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM || ( psz_elname = xml_ReaderName( p_xml_reader ) ) == NULL || strcmp( psz_elname, "WinampXML" ) ) { msg_Err( p_demux, "invalid root node %i, %s", xml_ReaderNodeType( p_xml_reader ), psz_elname ); goto end; } FREENULL( psz_elname ); /* root node should not have any attributes, and should only * contain the "playlist node */ /* Skip until 1st child node */ while( (i_ret = xml_ReaderRead( p_xml_reader )) == 1 && xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ); if( i_ret != 1 ) { msg_Err( p_demux, "invalid file (no child node)" ); 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 ); goto end; } 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 ) { 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" ) ) { input_item_SetName( p_current_input, psz_value ); } else { msg_Warn( p_demux, "stray attribute %s with value %s in element" " 'playlist'", psz_name, psz_value ); } free( psz_name ); 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 switch( xml_ReaderNodeType( p_xml_reader ) ) { // Error case -1: goto end; case XML_READER_STARTELEM: { // Read the element name free( psz_elname ); psz_elname = xml_ReaderName( p_xml_reader ); 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 ) { free( psz_name ); free( psz_value ); goto end; } if( !strcmp( psz_elname, "entry" ) && !strcmp( psz_name, "Playstring" ) ) { psz_mrl = psz_value; } else { msg_Warn( p_demux, "unexpected attribute %s in element %s", psz_name, psz_elname ); free( psz_value ); } free( psz_name ); } break; } case XML_READER_TEXT: { char *psz_text = xml_ReaderValue( p_xml_reader ); if( IsWhitespace( psz_text ) ) { free( psz_text ); break; } if( !strcmp( psz_elname, "Name" ) ) { psz_title = psz_text; } else if( !strcmp( psz_elname, "Genre" ) ) { psz_genre = psz_text; } else if( !strcmp( psz_elname, "Nowplaying" ) ) { psz_now = psz_text; } else if( !strcmp( psz_elname, "Listeners" ) ) { psz_listeners = psz_text; } else if( !strcmp( psz_elname, "Bitrate" ) ) { 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 ); } break; } // End element case XML_READER_ENDELEM: { // Read the element name free( psz_elname ); psz_elname = xml_ReaderName( p_xml_reader ); if( !psz_elname ) goto end; if( !strcmp( psz_elname, "entry" ) ) { p_input = input_item_New( p_demux, psz_mrl, psz_title ); if( psz_now ) input_item_SetNowPlaying( p_input, psz_now ); if( psz_genre ) input_item_SetGenre( p_input, psz_genre ); if( psz_listeners ) msg_Err( p_demux, "Unsupported meta listeners" ); if( psz_bitrate ) 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( "" ); break; } } } if( i_ret != 0 ) { msg_Warn( p_demux, "error while parsing data" ); i_ret = 0; /* Needed for correct operation of go back */ } 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, p_xml_reader ); if( p_xml ) xml_Delete( p_xml ); return i_ret; }
static int parse_Manifest( stream_t *s ) { stream_sys_t *p_sys = s->p_sys; xml_t *vlc_xml = NULL; xml_reader_t *vlc_reader = NULL; int type = UNKNOWN_ES; const char *name, *value; stream_t *st = s->p_source; msg_Dbg( s, "Manifest parsing\n" ); vlc_xml = xml_Create( st ); if( !vlc_xml ) { msg_Err( s, "Failed to open XML parser" ); return VLC_EGENERIC; } vlc_reader = xml_ReaderCreate( vlc_xml, st ); if( !vlc_reader ) { msg_Err( s, "Failed to open source for parsing" ); xml_Delete( vlc_xml ); return VLC_EGENERIC; } const char *node; uint8_t *WaveFormatEx; sms_stream_t *sms = NULL; quality_level_t *ql = NULL; int64_t start_time = 0, duration = 0; int64_t computed_start_time = 0, computed_duration = 0; unsigned next_track_id = 1; unsigned next_qid = 1; int loop_count = 0; bool b_weird = false; #define TIMESCALE 10000000 while( (type = xml_ReaderNextNode( vlc_reader, &node )) > 0 ) { switch( type ) { case XML_READER_STARTELEM: if( !strcmp( node, "SmoothStreamingMedia" ) ) { while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "Duration" ) ) p_sys->vod_duration = strtoull( value, NULL, 10 ); if( !strcmp( name, "TimeScale" ) ) p_sys->timescale = strtoull( value, NULL, 10 ); } if( !p_sys->timescale ) p_sys->timescale = TIMESCALE; } if( !strcmp( node, "StreamIndex" ) ) { sms = sms_New(); if( unlikely( !sms ) ) return VLC_ENOMEM; sms->id = next_track_id; next_track_id++; while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "Type" ) ) { if( !strcmp( value, "video" ) ) sms->type = VIDEO_ES; else if( !strcmp( value, "audio" ) ) sms->type = AUDIO_ES; else if( !strcmp( value, "text" ) ) sms->type = SPU_ES; } if( !strcmp( name, "Name" ) ) sms->name = strdup( value ); if( !strcmp( name, "TimeScale" ) ) sms->timescale = strtoull( value, NULL, 10 ); if( !strcmp( name, "FourCC" ) ) sms->default_FourCC = VLC_FOURCC( value[0], value[1], value[2], value[3] ); if( !strcmp( name, "Chunks" ) ) { sms->vod_chunks_nb = strtol( value, NULL, 10 ); if( sms->vod_chunks_nb == 0 ) /* live */ sms->vod_chunks_nb = UINT32_MAX; } if( !strcmp( name, "QualityLevels" ) ) sms->qlevel_nb = strtoul( value, NULL, 10 ); if( !strcmp( name, "Url" ) ) sms->url_template = strdup(value); } if( sms && !sms->timescale ) sms->timescale = TIMESCALE; if( !sms->name ) { if( sms->type == VIDEO_ES ) sms->name = strdup( "video" ); else if( sms->type == AUDIO_ES ) sms->name = strdup( "audio" ); else if( sms->type == SPU_ES ) sms->name = strdup( "text" ); } vlc_array_append( p_sys->sms_streams, sms ); } if( !strcmp( node, "QualityLevel" ) ) { ql = ql_New(); if( !ql ) return VLC_ENOMEM; ql->id = next_qid; next_qid++; while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "Index" ) ) ql->Index = strtol( value, NULL, 10 ); if( !strcmp( name, "Bitrate" ) ) ql->Bitrate = strtoull( value, NULL, 10 ); if( !strcmp( name, "PacketSize" ) ) ql->nBlockAlign = strtoull( value, NULL, 10 ); if( !strcmp( name, "FourCC" ) ) ql->FourCC = VLC_FOURCC( value[0], value[1], value[2], value[3] ); if( !strcmp( name, "CodecPrivateData" ) ) ql->CodecPrivateData = strdup( value ); if( !strcmp( name, "WaveFormatEx" ) ) { WaveFormatEx = decode_string_hex_to_binary( value ); uint16_t data_len = ((uint16_t *)WaveFormatEx)[8]; ql->CodecPrivateData = strndup( value + 36, data_len * 2 ); uint16_t wf_tag = ((uint16_t *)WaveFormatEx)[0]; wf_tag_to_fourcc( wf_tag, &ql->FourCC, NULL ); ql->Channels = ((uint16_t *)WaveFormatEx)[1]; ql->SamplingRate = ((uint32_t *)WaveFormatEx)[1]; ql->nBlockAlign = ((uint16_t *)WaveFormatEx)[6]; ql->BitsPerSample = ((uint16_t *)WaveFormatEx)[7]; free( WaveFormatEx ); } if( !strcmp( name, "MaxWidth" ) || !strcmp( name, "Width" ) ) ql->MaxWidth = strtoul( value, NULL, 10 ); if( !strcmp( name, "MaxHeight" ) || !strcmp( name, "Height" ) ) ql->MaxHeight = strtoul( value, NULL, 10 ); if( !strcmp( name, "Channels" ) ) ql->Channels = strtoul( value, NULL, 10 ); if( !strcmp( name, "SamplingRate" ) ) ql->SamplingRate = strtoul( value, NULL, 10 ); if( !strcmp( name, "BitsPerSample" ) ) ql->BitsPerSample = strtoul( value, NULL, 10 ); } vlc_array_append( sms->qlevels, ql ); } if( !strcmp( node, "c" ) ) { loop_count++; start_time = duration = -1; while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "t" ) ) start_time = strtoull( value, NULL, 10 ); if( !strcmp( name, "d" ) ) duration = strtoull( value, NULL, 10 ); } if( start_time == -1 ) { assert( duration != -1 ); computed_start_time += computed_duration; computed_duration = duration; } else if( duration == -1 ) { assert( start_time != -1 ); /* Handle weird Manifests which give only the start time * of the first segment. In those cases, we have to look * at the start time of the second segment to compute * the duration of the first one. */ if( loop_count == 1 ) { b_weird = true; computed_start_time = start_time; continue; } computed_duration = start_time - computed_start_time; if( !b_weird ) computed_start_time = start_time; } else { if( b_weird ) computed_duration = start_time - computed_start_time; else { computed_start_time = start_time; computed_duration = duration; } } if( unlikely( chunk_New( sms, computed_duration, computed_start_time ) == NULL ) ) { return VLC_ENOMEM; } if( b_weird && start_time != -1 ) computed_start_time = start_time; } break; case XML_READER_ENDELEM: if( strcmp( node, "StreamIndex" ) ) break; computed_start_time = 0; computed_duration = 0; loop_count = 0; if( b_weird && !chunk_New( sms, computed_duration, computed_start_time ) ) return VLC_ENOMEM; b_weird = false; next_qid = 1; if( sms->qlevel_nb == 0 ) sms->qlevel_nb = vlc_array_count( sms->qlevels ); break; case XML_READER_NONE: break; case XML_READER_TEXT: break; default: return VLC_EGENERIC; } } #undef TIMESCALE xml_ReaderDelete( vlc_reader ); xml_Delete( vlc_xml ); return VLC_SUCCESS; }
/** * \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 */ }
/** * \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 */ }