Beispiel #1
0
static int Open( vlc_object_t *p_this )
{
    stream_t *s = (stream_t*)p_this;
    stream_sys_t *p_sys;

    if( !isSmoothStreaming( s ) || s->psz_url == NULL )
        return VLC_EGENERIC;

    msg_Info( p_this, "Smooth Streaming (%s)", s->psz_url );

    s->p_sys = p_sys = calloc( 1, sizeof(*p_sys ) );
    if( unlikely( p_sys == NULL ) )
        return VLC_ENOMEM;

    char *uri = strdup( s->psz_url );
    if( unlikely( uri == NULL ) )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }

    /* remove the last part of the url */
    char *pos = strrchr( uri, '/');
    *pos = '\0';
    p_sys->download.base_url = uri;

    ARRAY_INIT( p_sys->sms );
    ARRAY_INIT( p_sys->sms_selected );

    /* Parse SMS ismc content. */
    if( parse_Manifest( s ) != VLC_SUCCESS )
    {
        SysCleanup( p_sys );
        free( p_sys );
        return VLC_EGENERIC;
    }

    if( !p_sys->vod_duration )
       p_sys->b_live = true;

    /* Choose first video / audio / subtitle stream available */
    sms_stream_t *selected = NULL;
    FOREACH_ARRAY( sms_stream_t *sms, p_sys->sms );
    selected = SMS_GET_SELECTED_ST( sms->type );
    if( !selected )
        ARRAY_APPEND( p_sys->sms_selected, sms );
    FOREACH_END();

    /* Choose lowest quality for the first chunks */
    FOREACH_ARRAY( sms_stream_t *sms, p_sys->sms );
    quality_level_t *wanted = NULL;
    if ( sms->qlevels.i_size )
    {
        wanted = sms->qlevels.p_elems[0];
        for( int i=1; i < sms->qlevels.i_size; i++ )
        {
            if( sms->qlevels.p_elems[i]->Bitrate < wanted->Bitrate )
                wanted = sms->qlevels.p_elems[i];
        }
        sms->current_qlvl = wanted;
    }
    FOREACH_END();

    /* Init our playback queue */
    p_sys->p_current_stream = next_playback_stream( p_sys );
    if ( !p_sys->p_current_stream )
    {
        SysCleanup( p_sys );
        free( p_sys );
        return VLC_EGENERIC;
    }
    p_sys->playback.next_chunk_offset = CHUNK_OFFSET_UNSET;
    p_sys->i_probe_length = SMS_PROBE_LENGTH;

    vlc_mutex_init( &p_sys->lock );
    vlc_cond_init( &p_sys->download.wait );
    vlc_cond_init( &p_sys->playback.wait );
    vlc_mutex_init( &p_sys->playback.lock );

    /* */
    s->pf_read = Read;
    s->pf_control = Control;

    if( vlc_clone( &p_sys->download.thread, sms_Thread, s, VLC_THREAD_PRIORITY_INPUT ) )
    {
        SysCleanup( p_sys );
        vlc_mutex_destroy( &p_sys->lock );
        vlc_cond_destroy( &p_sys->download.wait );
        vlc_mutex_destroy( &p_sys->playback.lock );
        vlc_cond_destroy( &p_sys->playback.wait );
        free( p_sys );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
Beispiel #2
0
static int Open( vlc_object_t *p_this )
{
    stream_t *s = (stream_t*)p_this;
    stream_sys_t *p_sys;

    if( !isSmoothStreaming( s ) )
        return VLC_EGENERIC;

    msg_Info( p_this, "Smooth Streaming (%s)", s->psz_path );

    s->p_sys = p_sys = calloc( 1, sizeof(*p_sys ) );
    if( unlikely( p_sys == NULL ) )
        return VLC_ENOMEM;

    char *uri = NULL;
    if( unlikely( asprintf( &uri, "%s://%s", s->psz_access, s->psz_path ) < 0 ) )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }

    /* remove the last part of the url */
    char *pos = strrchr( uri, '/');
    *pos = '\0';
    p_sys->base_url = uri;

    /* XXX I don't know wether or not we should allow caching */
    p_sys->b_cache = false;

    p_sys->sms_streams = vlc_array_new();
    p_sys->selected_st = vlc_array_new();
    p_sys->download.chunks = vlc_array_new();
    p_sys->init_chunks = vlc_array_new();
    if( unlikely( !p_sys->sms_streams || !p_sys->download.chunks ||
                  !p_sys->selected_st || !p_sys->init_chunks ) )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }

    /* Parse SMS ismc content. */
    if( parse_Manifest( s ) != VLC_SUCCESS )
    {
        free( p_sys );
        return VLC_EGENERIC;
    }

    if( !p_sys->vod_duration )
       p_sys->b_live = true;

    p_sys->i_tracks = vlc_array_count( p_sys->sms_streams );

    /* Choose first video / audio / subtitle stream available */
    sms_stream_t *tmp = NULL, *selected = NULL;
    for( unsigned i = 0; i < p_sys->i_tracks; i++ )
    {
        tmp = vlc_array_item_at_index( p_sys->sms_streams, i );
        selected = SMS_GET_SELECTED_ST( tmp->type );
        if( !selected )
            vlc_array_append( p_sys->selected_st, tmp );
    }

    /* Choose lowest quality for the first chunks */
    quality_level_t *wanted, *qlvl;
    sms_stream_t *sms = NULL;

    for( unsigned i = 0; i < p_sys->i_tracks; i++ )
    {
        wanted = qlvl = NULL;
        sms = vlc_array_item_at_index( p_sys->sms_streams, i );
        wanted = vlc_array_item_at_index( sms->qlevels, 0 );
        for( unsigned i=1; i < sms->qlevel_nb; i++ )
        {
            qlvl = vlc_array_item_at_index( sms->qlevels, i );
            if( qlvl->Bitrate < wanted->Bitrate )
                wanted = qlvl;
        }
        sms->download_qlvl = wanted->id;
    }

    vlc_mutex_init( &p_sys->download.lock_wait );
    vlc_cond_init( &p_sys->download.wait );

    /* */
    s->pf_read = Read;
    s->pf_peek = Peek;
    s->pf_control = Control;

    if( vlc_clone( &p_sys->thread, sms_Thread, s, VLC_THREAD_PRIORITY_INPUT ) )
    {
        free( p_sys );
        vlc_mutex_destroy( &p_sys->download.lock_wait );
        vlc_cond_destroy( &p_sys->download.wait );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}