Example #1
0
File: dvb.c Project: 0xheart0/vlc
/* 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;
}
Example #2
0
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;
}
Example #4
0
/**************************************************************************
 * 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 );
}
Example #5
0
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;
}
Example #6
0
/*****************************************************************************
 * 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 */
}
Example #7
0
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;
    }
}
Example #8
0
File: sgimb.c Project: IAPark/vlc
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;
}
Example #9
0
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;
}
Example #10
0
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( );
}