/* http://www.linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf or not... * Read the dvb-apps source code for reference. */ static input_item_t *ParseLine(char *line) { char *str, *end; line += strspn(line, " \t\r"); /* skip leading white spaces */ if (*line == '#') return NULL; /* skip comments */ /* Extract channel cute name */ char *name = strsep(&line, ":"); assert(name != NULL); EnsureUTF8(name); /* Extract central frequency */ str = strsep(&line, ":"); if (str == NULL) return NULL; unsigned long freq = strtoul(str, &end, 10); if (*end) return NULL; /* Extract tuning parameters */ str = strsep(&line, ":"); if (str == NULL) return NULL; char *mrl; if (!strcmp(str, "h") || !strcmp(str, "v")) { /* DVB-S */ char polarization = toupper(*str); /* TODO: sat no. */ str = strsep(&line, ":"); if (str == NULL) return NULL; /* baud rate */ str = strsep(&line, ":"); if (str == NULL) return NULL; unsigned long rate = strtoul(str, &end, 10); if (*end || rate > (ULONG_MAX / 1000u)) return NULL; rate *= 1000; if (asprintf(&mrl, "dvb-s://frequency=%"PRIu64":polarization=%c:srate=%lu", freq * UINT64_C(1000000), polarization, rate) == -1) mrl = NULL; } else if (!strncmp(str, "INVERSION_", 10)) { /* DVB-C or DVB-T */ int inversion; str += 10; if (strcmp(str, "AUTO")) inversion = -1; else if (strcmp(str, "OFF")) inversion = 0; else if (strcmp(str, "ON")) inversion = 1; else return NULL; str = strsep(&line, ":"); if (str == NULL) return NULL; if (strncmp(str, "BANDWIDTH_", 10)) { /* DVB-C */ unsigned long rate = strtoul(str, &end, 10); if (*end) return NULL; str = strsep(&line, ":"); const char *fec = ParseFEC(str); str = strsep(&line, ":"); const char *mod = ParseModulation(str); if (fec == NULL || mod == NULL) return NULL; if (asprintf(&mrl, "dvb-c://frequency=%lu:inversion:%d:srate=%lu:" "fec=%s:modulation=%s", freq, inversion, rate, fec, mod) == -1) mrl = NULL; } else { /* DVB-T */ unsigned bandwidth = atoi(str + 10); str = strsep(&line, ":"); const char *hp = ParseFEC(str); str = strsep(&line, ":"); const char *lp = ParseFEC(str); str = strsep(&line, ":"); const char *mod = ParseModulation(str); if (hp == NULL || lp == NULL || mod == NULL) return NULL; str = strsep(&line, ":"); if (str == NULL || strncmp(str, "TRANSMISSION_MODE_", 18)) return NULL; int xmit = atoi(str); if (xmit == 0) xmit = -1; /* AUTO */ str = strsep(&line, ":"); const char *guard = ParseGuard(str); if (guard == NULL) return NULL; str = strsep(&line, ":"); if (str == NULL || strncmp(str, "HIERARCHY_", 10)) return NULL; str += 10; int hierarchy = atoi(str); if (!strcmp(str, "AUTO")) hierarchy = -1; if (asprintf(&mrl, "dvb-t://frequency=%lu:inversion=%d:" "bandwidth=%u:code-rate-hp=%s:code-rate-lp=%s:" "modulation=%s:transmission=%d:guard=%s:" "hierarchy=%d", freq, inversion, bandwidth, hp, lp, mod, xmit, guard, hierarchy) == -1) mrl = NULL; } } else { /* ATSC */ const char *mod = ParseModulation(str); if (mod == NULL) return NULL; if (asprintf(&mrl, "atsc://frequency=%lu:modulation=%s", freq, mod) == -1) mrl = NULL; } if (unlikely(mrl == NULL)) return NULL; /* Video PID (TODO? set video track) */ strsep(&line, ":"); /* Audio PID (TODO? set audio track) */ strsep(&line, ":"); /* Extract SID */ str = strsep(&line, ":"); if (str == NULL) { free(mrl); return NULL; } unsigned long sid = strtoul(str, &end, 10); if (*end || sid > 65535) { free(mrl); return NULL; } char sid_opt[sizeof("program=65535")]; snprintf(sid_opt, sizeof(sid_opt), "program=%lu", sid); input_item_t *item = input_item_NewCard(mrl, name); free(mrl); if (item != NULL) input_item_AddOption(item, sid_opt, 0); return item; }
bool MLModel::action( QAction *action, const QModelIndexList &indexes ) { actionsContainerType a = action->data().value<actionsContainerType>(); input_item_t *p_input; switch ( a.action ) { case ACTION_PLAY: if ( ! indexes.empty() && indexes.first().isValid() ) { activateItem( indexes.first() ); return true; } break; case ACTION_ADDTOPLAYLIST: foreach( const QModelIndex &index, indexes ) { if( !index.isValid() ) return false; AddItemToPlaylist( itemId( index, MLMEDIA_ID ), false, p_ml, true ); } return true; case ACTION_REMOVE: doDelete( indexes ); return true; case ACTION_SORT: break; case ACTION_CLEAR: removeAll(); return true; case ACTION_ENQUEUEFILE: foreach( const QString &uri, a.uris ) playlist_Add( THEPL, uri.toAscii().constData(), NULL, PLAYLIST_APPEND | PLAYLIST_PREPARSE, PLAYLIST_END, false, pl_Unlocked ); return true; case ACTION_ENQUEUEDIR: if( a.uris.isEmpty() ) return false; p_input = input_item_New( a.uris.first().toAscii().constData(), NULL ); if( unlikely( p_input == NULL ) ) return false; /* FIXME: playlist_AddInput() can fail */ playlist_AddInput( THEPL, p_input, PLAYLIST_APPEND, PLAYLIST_END, true, pl_Unlocked ); vlc_gc_decref( p_input ); return true; case ACTION_ENQUEUEGENERIC: foreach( const QString &uri, a.uris ) { p_input = input_item_New( qtu( uri ), NULL ); /* Insert options */ foreach( const QString &option, a.options.split( " :" ) ) { QString temp = colon_unescape( option ); if( !temp.isEmpty() ) input_item_AddOption( p_input, qtu( temp ), VLC_INPUT_OPTION_TRUSTED ); } /* FIXME: playlist_AddInput() can fail */ playlist_AddInput( THEPL, p_input, PLAYLIST_APPEND | PLAYLIST_PREPARSE, PLAYLIST_END, false, pl_Unlocked ); vlc_gc_decref( p_input ); } return true; default: break; } return false; }
static void ParseUrls( services_discovery_t *p_sd, char *psz_urls ) { services_discovery_sys_t *p_sys = p_sd->p_sys; int i_new_items = 0; input_item_t **pp_new_items = NULL; int i_new_urls = 0; char **ppsz_new_urls = NULL; int i, j; for( ;; ) { if( !psz_urls ) break; char *psz_tok = strchr( psz_urls, '|' ); if( psz_tok ) *psz_tok = '\0'; for( i = 0; i < p_sys->i_urls; i++ ) if( !strcmp( psz_urls, p_sys->ppsz_urls[i] ) ) break; if( i == p_sys->i_urls ) { INSERT_ELEM( ppsz_new_urls, i_new_urls, i_new_urls, strdup( psz_urls ) ); input_item_t *p_input; p_input = input_item_New( psz_urls, psz_urls ); input_item_AddOption( p_input, "demux=podcast", VLC_INPUT_OPTION_TRUSTED ); INSERT_ELEM( pp_new_items, i_new_items, i_new_items, p_input ); services_discovery_AddItem( p_sd, p_input, NULL /* no cat */ ); INSERT_ELEM( p_sys->pp_input, p_sys->i_input, p_sys->i_input, input_CreateAndStart( p_sd, p_input, NULL ) ); } else { INSERT_ELEM( ppsz_new_urls, i_new_urls, i_new_urls, strdup( p_sys->ppsz_urls[i]) ); INSERT_ELEM( pp_new_items, i_new_items, i_new_items, p_sys->pp_items[i] ); } if( psz_tok ) psz_urls = psz_tok+1; else break; } /* delete removed items and signal the removal */ for( i = 0; i<p_sys->i_items; ++i ) { for( j = 0; j < i_new_items; ++j ) if( pp_new_items[j] == p_sys->pp_items[i] ) break; if( j == i_new_items ) { services_discovery_RemoveItem( p_sd, p_sys->pp_items[i] ); vlc_gc_decref( p_sys->pp_items[i] ); } } free( p_sys->pp_items ); for( int i = 0; i < p_sys->i_urls; i++ ) free( p_sys->ppsz_urls[i] ); free( p_sys->ppsz_urls ); p_sys->ppsz_urls = ppsz_new_urls; p_sys->i_urls = i_new_urls; p_sys->pp_items = pp_new_items; p_sys->i_items = i_new_items; }
/************************************************************************** * Same as libvlc_media_add_option but with configurable flags. **************************************************************************/ void libvlc_media_add_option_flag( libvlc_media_t * p_md, const char * ppsz_option, unsigned i_flags ) { input_item_AddOption( p_md->p_input_item, ppsz_option, i_flags ); }
static void ParseRequest( services_discovery_t *p_sd ) { services_discovery_sys_t *p_sys = p_sd->p_sys; char *psz_request = p_sys->psz_request; int i; char *psz_tok = strchr( psz_request, ':' ); if( !psz_tok ) return; *psz_tok = '\0'; if ( ! p_sys->b_savedurls_loaded ) { char *psz_urls = var_GetNonEmptyString( p_sd->p_parent, "podcast-urls" ); ParseUrls( p_sd, psz_urls ); free( psz_urls ); } if( !strcmp( psz_request, "ADD" ) ) { psz_request = psz_tok + 1; for( i = 0; i<p_sys->i_urls; i++ ) if( !strcmp(p_sys->ppsz_urls[i],psz_request) ) break; if( i == p_sys->i_urls ) { INSERT_ELEM( p_sys->ppsz_urls, p_sys->i_urls, p_sys->i_urls, strdup( psz_request ) ); input_item_t *p_input; p_input = input_item_New( psz_request, psz_request ); input_item_AddOption( p_input, "demux=podcast", VLC_INPUT_OPTION_TRUSTED ); INSERT_ELEM( p_sys->pp_items, p_sys->i_items, p_sys->i_items, p_input ); services_discovery_AddItem( p_sd, p_input, NULL /* no cat */ ); INSERT_ELEM( p_sys->pp_input, p_sys->i_input, p_sys->i_input, input_CreateAndStart( p_sd, p_input, NULL ) ); SaveUrls( p_sd ); } } else if ( !strcmp( psz_request, "RM" ) ) { psz_request = psz_tok + 1; for( i = 0; i<p_sys->i_urls; i++ ) if( !strcmp(p_sys->ppsz_urls[i],psz_request) ) break; if( i != p_sys->i_urls ) { services_discovery_RemoveItem( p_sd, p_sys->pp_items[i] ); vlc_gc_decref( p_sys->pp_items[i] ); REMOVE_ELEM( p_sys->ppsz_urls, p_sys->i_urls, i ); REMOVE_ELEM( p_sys->pp_items, p_sys->i_items, i ); } SaveUrls( p_sd ); } free( p_sys->psz_request ); p_sys->psz_request = NULL; }
/***************************************************************************** * Demux: reads and demuxes data packets ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, 1 otherwise *****************************************************************************/ static int Demux ( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; input_item_t *p_child = NULL; char *psz_line; input_item_t *p_current_input = GetCurrentItem(p_demux); while( ( psz_line = stream_ReadLine( p_demux->s ) ) ) { ParseLine( p_demux, psz_line ); free( psz_line ); } if( p_sys->psz_mcast_ip ) { /* Definetly schedules multicast session */ /* We don't care if it's live or not */ free( p_sys->psz_uri ); if( asprintf( &p_sys->psz_uri, "udp://@" "%s:%i", p_sys->psz_mcast_ip, p_sys->i_mcast_port ) == -1 ) { p_sys->psz_uri = NULL; return -1; } } if( p_sys->psz_uri == NULL ) { if( p_sys->psz_server && p_sys->psz_location ) { if( asprintf( &p_sys->psz_uri, "rtsp://" "%s:%i%s", p_sys->psz_server, p_sys->i_port > 0 ? p_sys->i_port : 554, p_sys->psz_location ) == -1 ) { p_sys->psz_uri = NULL; return -1; } } } if( p_sys->b_concert ) { /* It's definetly a simulcasted scheduled stream */ /* We don't care if it's live or not */ if( p_sys->psz_uri == NULL ) { msg_Err( p_demux, "no URI was found" ); return -1; } char *uri; if( asprintf( &uri, "%s%%3FMeDiAbAsEshowingId=%d%%26MeDiAbAsEconcert" "%%3FMeDiAbAsE", p_sys->psz_uri, p_sys->i_sid ) == -1 ) return -1; free( p_sys->psz_uri ); p_sys->psz_uri = uri; } p_child = input_item_NewWithType( p_sys->psz_uri, p_sys->psz_name ? p_sys->psz_name : p_sys->psz_uri, 0, NULL, 0, p_sys->i_duration, ITEM_TYPE_NET ); if( !p_child ) { msg_Err( p_demux, "A valid playlistitem could not be created" ); return -1; } input_item_CopyOptions( p_current_input, p_child ); if( p_sys->i_packet_size && p_sys->psz_mcast_ip ) { char *psz_option; p_sys->i_packet_size += 1000; if( asprintf( &psz_option, "mtu=%i", p_sys->i_packet_size ) != -1 ) { input_item_AddOption( p_child, psz_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_option ); } } if( !p_sys->psz_mcast_ip ) input_item_AddOption( p_child, "rtsp-caching=5000", VLC_INPUT_OPTION_TRUSTED ); if( !p_sys->psz_mcast_ip && p_sys->b_rtsp_kasenna ) input_item_AddOption( p_child, "rtsp-kasenna", VLC_INPUT_OPTION_TRUSTED ); input_item_PostSubItem( p_current_input, p_child ); vlc_gc_decref( p_child ); vlc_gc_decref(p_current_input); return 0; /* Needed for correct operation of go back */ }
static void DoFingerprint( fingerprinter_thread_t *p_fingerprinter, acoustid_fingerprint_t *fp, const char *psz_uri ) { input_item_t *p_item = input_item_New( NULL, NULL ); if ( unlikely(p_item == NULL) ) return; char *psz_sout_option; /* Note: need at -max- 2 channels, but we can't guess it before playing */ /* the stereo upmix could make the mono tracks fingerprint to differ :/ */ if ( asprintf( &psz_sout_option, "sout=#transcode{acodec=%s,channels=2}:chromaprint", ( VLC_CODEC_S16L == VLC_CODEC_S16N ) ? "s16l" : "s16b" ) == -1 ) { input_item_Release( p_item ); return; } input_item_AddOption( p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_sout_option ); input_item_AddOption( p_item, "vout=dummy", VLC_INPUT_OPTION_TRUSTED ); input_item_AddOption( p_item, "aout=dummy", VLC_INPUT_OPTION_TRUSTED ); if ( fp->i_duration ) { if ( asprintf( &psz_sout_option, "stop-time=%u", fp->i_duration ) == -1 ) { input_item_Release( p_item ); return; } input_item_AddOption( p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_sout_option ); } input_item_SetURI( p_item, psz_uri ) ; input_thread_t *p_input = input_Create( p_fingerprinter, p_item, "fingerprinter", NULL, NULL ); input_item_Release( p_item ); if( p_input == NULL ) return; chromaprint_fingerprint_t chroma_fingerprint; chroma_fingerprint.psz_fingerprint = NULL; chroma_fingerprint.i_duration = fp->i_duration; var_Create( p_input, "fingerprint-data", VLC_VAR_ADDRESS ); var_SetAddress( p_input, "fingerprint-data", &chroma_fingerprint ); var_AddCallback( p_input, "intf-event", InputEventHandler, p_fingerprinter->p_sys ); if( input_Start( p_input ) != VLC_SUCCESS ) { var_DelCallback( p_input, "intf-event", InputEventHandler, p_fingerprinter->p_sys ); input_Close( p_input ); } else { p_fingerprinter->p_sys->processing.b_working = true; while( p_fingerprinter->p_sys->processing.b_working ) { vlc_cond_wait( &p_fingerprinter->p_sys->processing.cond, &p_fingerprinter->p_sys->processing.lock ); } var_DelCallback( p_input, "intf-event", InputEventHandler, p_fingerprinter->p_sys ); input_Stop( p_input ); input_Close( p_input ); fp->psz_fingerprint = chroma_fingerprint.psz_fingerprint; if( !fp->i_duration ) /* had not given hint */ fp->i_duration = chroma_fingerprint.i_duration; } }
static int ReadDir( stream_t *p_demux, input_item_node_t *node ) { demux_sys_t *p_sys = p_demux->p_sys; input_item_t *p_child = NULL; char *psz_line; while( ( psz_line = vlc_stream_ReadLine( p_demux->p_source ) ) ) { ParseLine( p_demux, psz_line ); free( psz_line ); } if( p_sys->psz_mcast_ip ) { /* Definetly schedules multicast session */ /* We don't care if it's live or not */ free( p_sys->psz_uri ); if( asprintf( &p_sys->psz_uri, "udp://@" "%s:%i", p_sys->psz_mcast_ip, p_sys->i_mcast_port ) == -1 ) { p_sys->psz_uri = NULL; return -1; } } if( p_sys->psz_uri == NULL ) { if( p_sys->psz_server && p_sys->psz_location ) { if( asprintf( &p_sys->psz_uri, "rtsp://" "%s:%i%s", p_sys->psz_server, p_sys->i_port > 0 ? p_sys->i_port : 554, p_sys->psz_location ) == -1 ) { p_sys->psz_uri = NULL; return -1; } } } if( p_sys->b_concert ) { /* It's definetly a simulcasted scheduled stream */ /* We don't care if it's live or not */ if( p_sys->psz_uri == NULL ) { msg_Err( p_demux, "no URI was found" ); return -1; } char *uri; if( asprintf( &uri, "%s%%3FMeDiAbAsEshowingId=%d%%26MeDiAbAsEconcert" "%%3FMeDiAbAsE", p_sys->psz_uri, p_sys->i_sid ) == -1 ) return -1; free( p_sys->psz_uri ); p_sys->psz_uri = uri; } p_child = input_item_NewStream( p_sys->psz_uri, p_sys->psz_name ? p_sys->psz_name : p_sys->psz_uri, p_sys->i_duration ); if( !p_child ) { msg_Err( p_demux, "A valid playlistitem could not be created" ); return -1; } if( p_sys->i_packet_size && p_sys->psz_mcast_ip ) { char *psz_option; p_sys->i_packet_size += 1000; if( asprintf( &psz_option, "mtu=%i", p_sys->i_packet_size ) != -1 ) { input_item_AddOption( p_child, psz_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_option ); } } if( !p_sys->psz_mcast_ip ) input_item_AddOption( p_child, "rtsp-caching=5000", VLC_INPUT_OPTION_TRUSTED ); if( !p_sys->psz_mcast_ip && p_sys->b_rtsp_kasenna ) input_item_AddOption( p_child, "rtsp-kasenna", VLC_INPUT_OPTION_TRUSTED ); input_item_node_AppendItem( node, p_child ); input_item_Release( p_child ); return VLC_SUCCESS; }
static int GetTracks( access_t *p_access, input_item_t *p_current ) { access_sys_t *p_sys = p_access->p_sys; const int i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access), p_sys->vcddev, &p_sys->p_sectors ); if( i_titles <= 0 ) { if( i_titles < 0 ) msg_Err( p_access, "unable to count tracks" ); else if( i_titles <= 0 ) msg_Err( p_access, "no audio tracks found" ); return VLC_EGENERIC;; } /* */ input_item_SetName( p_current, "Audio CD" ); const char *psz_album = NULL; const char *psz_year = NULL; const char *psz_genre = NULL; const char *psz_artist = NULL; const char *psz_description = NULL; /* Return true if the given string is not NULL and not empty */ #define NONEMPTY( psz ) ( (psz) && *(psz) ) /* If the given string is NULL or empty, fill it by the return value of 'code' */ #define ON_EMPTY( psz, code ) do { if( !NONEMPTY( psz) ) { (psz) = code; } } while(0) /* Retreive CDDB information */ #ifdef HAVE_LIBCDDB char psz_year_buffer[4+1]; msg_Dbg( p_access, "fetching infos with CDDB" ); cddb_disc_t *p_disc = GetCDDBInfo( p_access, i_titles, p_sys->p_sectors ); if( p_disc ) { psz_album = cddb_disc_get_title( p_disc ); psz_genre = cddb_disc_get_genre( p_disc ); /* */ const unsigned i_year = cddb_disc_get_year( p_disc ); if( i_year > 0 ) { psz_year = psz_year_buffer; _snprintf( psz_year_buffer, sizeof(psz_year_buffer), "%u", i_year ); // sunqueen modify } /* Set artist only if unique */ for( int i = 0; i < i_titles; i++ ) { cddb_track_t *t = cddb_disc_get_track( p_disc, i ); if( !t ) continue; const char *psz_track_artist = cddb_track_get_artist( t ); if( psz_artist && psz_track_artist && strcmp( psz_artist, psz_track_artist ) ) { psz_artist = NULL; break; } psz_artist = psz_track_artist; } } #endif /* CD-Text */ vlc_meta_t **pp_cd_text; int i_cd_text; if( ioctl_GetCdText( VLC_OBJECT(p_access), p_sys->vcddev, &pp_cd_text, &i_cd_text ) ) { msg_Dbg( p_access, "CD-TEXT information missing" ); i_cd_text = 0; pp_cd_text = NULL; } /* Retrieve CD-TEXT information but prefer CDDB */ if( i_cd_text > 0 && pp_cd_text[0] ) { const vlc_meta_t *p_disc = pp_cd_text[0]; ON_EMPTY( psz_album, vlc_meta_Get( p_disc, vlc_meta_Album ) ); ON_EMPTY( psz_genre, vlc_meta_Get( p_disc, vlc_meta_Genre ) ); ON_EMPTY( psz_artist, vlc_meta_Get( p_disc, vlc_meta_Artist ) ); ON_EMPTY( psz_description, vlc_meta_Get( p_disc, vlc_meta_Description ) ); } if( NONEMPTY( psz_album ) ) { input_item_SetName( p_current, psz_album ); input_item_SetAlbum( p_current, psz_album ); } if( NONEMPTY( psz_genre ) ) input_item_SetGenre( p_current, psz_genre ); if( NONEMPTY( psz_artist ) ) input_item_SetArtist( p_current, psz_artist ); if( NONEMPTY( psz_year ) ) input_item_SetDate( p_current, psz_year ); if( NONEMPTY( psz_description ) ) input_item_SetDescription( p_current, psz_description ); const mtime_t i_duration = (int64_t)( p_sys->p_sectors[i_titles] - p_sys->p_sectors[0] ) * CDDA_DATA_SIZE * 1000000 / 44100 / 2 / 2; input_item_SetDuration( p_current, i_duration ); input_item_node_t *p_root = input_item_node_Create( p_current ); /* Build title table */ for( int i = 0; i < i_titles; i++ ) { input_item_t *p_input_item; char *psz_uri, *psz_opt, *psz_first, *psz_last; char *psz_name; msg_Dbg( p_access, "track[%d] start=%d", i, p_sys->p_sectors[i] ); /* */ if( asprintf( &psz_uri, "cdda://%s", p_access->psz_location ) == -1 ) psz_uri = NULL; if( asprintf( &psz_opt, "cdda-track=%i", i+1 ) == -1 ) psz_opt = NULL; if( asprintf( &psz_first, "cdda-first-sector=%i",p_sys->p_sectors[i] ) == -1 ) psz_first = NULL; if( asprintf( &psz_last, "cdda-last-sector=%i", p_sys->p_sectors[i+1] ) == -1 ) psz_last = NULL; /* Define a "default name" */ if( asprintf( &psz_name, _("Audio CD - Track %02i"), (i+1) ) == -1 ) psz_name = NULL; /* Create playlist items */ const mtime_t i_duration = (int64_t)( p_sys->p_sectors[i+1] - p_sys->p_sectors[i] ) * CDDA_DATA_SIZE * 1000000 / 44100 / 2 / 2; p_input_item = input_item_NewWithType( psz_uri, psz_name, 0, NULL, 0, i_duration, ITEM_TYPE_DISC ); input_item_CopyOptions( p_current, p_input_item ); input_item_AddOption( p_input_item, psz_first, VLC_INPUT_OPTION_TRUSTED ); input_item_AddOption( p_input_item, psz_last, VLC_INPUT_OPTION_TRUSTED ); input_item_AddOption( p_input_item, psz_opt, VLC_INPUT_OPTION_TRUSTED ); const char *psz_track_title = NULL; const char *psz_track_artist = NULL; const char *psz_track_genre = NULL; const char *psz_track_description = NULL; #ifdef HAVE_LIBCDDB /* Retreive CDDB information */ if( p_disc ) { cddb_track_t *t = cddb_disc_get_track( p_disc, i ); if( t != NULL ) { psz_track_title = cddb_track_get_title( t ); psz_track_artist = cddb_track_get_artist( t ); } } #endif /* Retreive CD-TEXT information but prefer CDDB */ if( i+1 < i_cd_text && pp_cd_text[i+1] ) { const vlc_meta_t *t = pp_cd_text[i+1]; ON_EMPTY( psz_track_title, vlc_meta_Get( t, vlc_meta_Title ) ); ON_EMPTY( psz_track_artist, vlc_meta_Get( t, vlc_meta_Artist ) ); ON_EMPTY( psz_track_genre, vlc_meta_Get( t, vlc_meta_Genre ) ); ON_EMPTY( psz_track_description, vlc_meta_Get( t, vlc_meta_Description ) ); } /* */ ON_EMPTY( psz_track_artist, psz_artist ); ON_EMPTY( psz_track_genre, psz_genre ); ON_EMPTY( psz_track_description, psz_description ); /* */ if( NONEMPTY( psz_track_title ) ) { input_item_SetName( p_input_item, psz_track_title ); input_item_SetTitle( p_input_item, psz_track_title ); } if( NONEMPTY( psz_track_artist ) ) input_item_SetArtist( p_input_item, psz_track_artist ); if( NONEMPTY( psz_track_genre ) ) input_item_SetGenre( p_input_item, psz_track_genre ); if( NONEMPTY( psz_track_description ) ) input_item_SetDescription( p_input_item, psz_track_description ); if( NONEMPTY( psz_album ) ) input_item_SetAlbum( p_input_item, psz_album ); if( NONEMPTY( psz_year ) ) input_item_SetDate( p_input_item, psz_year ); char psz_num[3+1]; _snprintf( psz_num, sizeof(psz_num), "%d", 1+i ); // sunqueen modify input_item_SetTrackNum( p_input_item, psz_num ); input_item_node_AppendItem( p_root, p_input_item ); vlc_gc_decref( p_input_item ); free( psz_uri ); free( psz_opt ); free( psz_name ); free( psz_first ); free( psz_last ); } #undef ON_EMPTY #undef NONEMPTY input_item_node_PostAndDelete( p_root ); /* */ for( int i = 0; i < i_cd_text; i++ ) { vlc_meta_t *p_meta = pp_cd_text[i]; if( !p_meta ) continue; vlc_meta_Delete( p_meta ); } free( pp_cd_text ); #ifdef HAVE_LIBCDDB if( p_disc ) cddb_disc_destroy( p_disc ); #endif return VLC_SUCCESS; }
static void DoFingerprint( vlc_object_t *p_this, fingerprinter_sys_t *p_sys, acoustid_fingerprint_t *fp ) { p_sys->p_input = NULL; p_sys->p_item = NULL; p_sys->chroma_fingerprint.psz_fingerprint = NULL; vlc_cleanup_push( cancelDoFingerprint, p_sys ); p_sys->p_item = input_item_New( NULL, NULL ); if ( ! p_sys->p_item ) goto end; char *psz_sout_option; /* Note: need at -max- 2 channels, but we can't guess it before playing */ /* the stereo upmix could make the mono tracks fingerprint to differ :/ */ if ( asprintf( &psz_sout_option, "sout=#transcode{acodec=%s,channels=2}:chromaprint", ( VLC_CODEC_S16L == VLC_CODEC_S16N ) ? "s16l" : "s16b" ) == -1 ) goto end; input_item_AddOption( p_sys->p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_sout_option ); input_item_AddOption( p_sys->p_item, "vout=dummy", VLC_INPUT_OPTION_TRUSTED ); input_item_AddOption( p_sys->p_item, "aout=dummy", VLC_INPUT_OPTION_TRUSTED ); if ( fp->i_duration ) { if ( asprintf( &psz_sout_option, "stop-time=%u", fp->i_duration ) == -1 ) goto end; input_item_AddOption( p_sys->p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_sout_option ); } input_item_SetURI( p_sys->p_item, p_sys->psz_uri ) ; p_sys->p_input = input_Create( p_this, p_sys->p_item, "fingerprinter", NULL ); if ( p_sys->p_input ) { p_sys->chroma_fingerprint.i_duration = fp->i_duration; var_Create( p_sys->p_input, "fingerprint-data", VLC_VAR_ADDRESS ); var_SetAddress( p_sys->p_input, "fingerprint-data", & p_sys->chroma_fingerprint ); input_Start( p_sys->p_input ); /* Wait for input to start && end */ p_sys->condwait.i_input_state = var_GetInteger( p_sys->p_input, "state" ); if ( likely( var_AddCallback( p_sys->p_input, "intf-event", inputStateCallback, p_sys ) == VLC_SUCCESS ) ) { while( p_sys->condwait.i_input_state <= PAUSE_S ) { vlc_mutex_lock( &p_sys->condwait.lock ); mutex_cleanup_push( &p_sys->condwait.lock ); vlc_cond_wait( &p_sys->condwait.wait, &p_sys->condwait.lock ); vlc_cleanup_run(); } var_DelCallback( p_sys->p_input, "intf-event", inputStateCallback, p_sys ); } input_Stop( p_sys->p_input, true ); input_Close( p_sys->p_input ); p_sys->p_input = NULL; if ( p_sys->chroma_fingerprint.psz_fingerprint ) { fp->psz_fingerprint = strdup( p_sys->chroma_fingerprint.psz_fingerprint ); if ( ! fp->i_duration ) /* had not given hint */ fp->i_duration = p_sys->chroma_fingerprint.i_duration; } } end: vlc_cleanup_run( ); }