static chunk_t * gotoNextChunk( stream_sys_t *p_sys ) { assert(p_sys->p_current_stream); chunk_t *p_prev = p_sys->p_current_stream->p_playback; if ( p_prev ) { if ( p_sys->b_live ) { /* Discard chunk and update stream pointers */ assert( p_sys->p_current_stream->p_chunks == p_sys->p_current_stream->p_playback ); p_sys->p_current_stream->p_playback = p_sys->p_current_stream->p_playback->p_next; p_sys->p_current_stream->p_chunks = p_sys->p_current_stream->p_chunks->p_next; if ( p_sys->p_current_stream->p_lastchunk == p_prev ) p_sys->p_current_stream->p_lastchunk = NULL; chunk_Free( p_prev ); } else { /* Just cleanup chunk for reuse on seek */ p_sys->p_current_stream->p_playback = p_sys->p_current_stream->p_playback->p_next; FREENULL(p_prev->data); p_prev->read_pos = 0; p_prev->offset = CHUNK_OFFSET_UNSET; p_prev->size = 0; } } /* Select new current pointer among streams playback heads */ p_sys->p_current_stream = next_playback_stream( p_sys ); if ( !p_sys->p_current_stream ) return NULL; return p_sys->p_current_stream->p_playback; }
void sms_Free( sms_stream_t *sms ) { if( sms->qlevels ) { for( int n = 0; n < vlc_array_count( sms->qlevels ); n++ ) { quality_level_t *qlevel = (quality_level_t *)vlc_array_item_at_index( sms->qlevels, n ); // sunqueen modify if( qlevel ) ql_Free( qlevel ); } vlc_array_destroy( sms->qlevels ); } if( sms->chunks ) { for( int n = 0; n < vlc_array_count( sms->chunks ); n++ ) { chunk_t *chunk = (chunk_t *)vlc_array_item_at_index( sms->chunks, n ); // sunqueen modify if( chunk) chunk_Free( chunk ); } vlc_array_destroy( sms->chunks ); } free( sms->name ); free( sms->url_template ); free( sms ); sms = NULL; }
static void SysCleanup( stream_sys_t *p_sys ) { if ( p_sys->sms.i_size ) { FOREACH_ARRAY( sms_stream_t *sms, p_sys->sms ); sms_Free( sms ); FOREACH_END(); ARRAY_RESET( p_sys->sms ); } ARRAY_RESET( p_sys->sms_selected ); if ( p_sys->playback.init.p_datachunk ) chunk_Free( p_sys->playback.init.p_datachunk ); free( p_sys->download.base_url ); }
static void Close( vlc_object_t *p_this ) { stream_t *s = (stream_t*)p_this; stream_sys_t *p_sys = s->p_sys; vlc_mutex_lock( &p_sys->download.lock_wait ); p_sys->b_close = true; /* Negate the condition variable's predicate */ for( int i = 0; i < 3; i++ ) p_sys->download.lead[i] = 0; p_sys->playback.toffset = 0; vlc_cond_signal(&p_sys->download.wait); vlc_mutex_unlock( &p_sys->download.lock_wait ); vlc_join( p_sys->thread, NULL ); vlc_mutex_destroy( &p_sys->download.lock_wait ); vlc_cond_destroy( &p_sys->download.wait ); /* Free sms streams */ sms_stream_t *sms; for( int i = 0; i < vlc_array_count( p_sys->sms_streams ); i++ ) { sms = vlc_array_item_at_index( p_sys->sms_streams, i ); if( sms ) sms_Free( sms ); } /* Free downloaded chunks */ chunk_t *chunk; for( int i = 0; i < vlc_array_count( p_sys->init_chunks ); i++ ) { chunk = vlc_array_item_at_index( p_sys->init_chunks, i ); chunk_Free( chunk ); } sms_queue_free( p_sys->bws ); vlc_array_destroy( p_sys->sms_streams ); vlc_array_destroy( p_sys->selected_st ); vlc_array_destroy( p_sys->download.chunks ); vlc_array_destroy( p_sys->init_chunks ); free( p_sys->base_url ); free( p_sys ); }
static void SysCleanup( stream_sys_t *p_sys ) { if ( p_sys->sms_streams ) { for ( int i=0; i< p_sys->sms_streams->i_count ; i++ ) sms_Free( p_sys->sms_streams->pp_elems[i] ); vlc_array_destroy( p_sys->sms_streams ); } vlc_array_destroy( p_sys->selected_st ); vlc_array_destroy( p_sys->download.chunks ); if ( p_sys->init_chunks ) { for ( int i=0; i< p_sys->init_chunks->i_count ; i++ ) chunk_Free( p_sys->init_chunks->pp_elems[i] ); vlc_array_destroy( p_sys->init_chunks ); } sms_queue_free( p_sys->bws ); free( p_sys->base_url ); }
void sms_Free( sms_stream_t *sms ) { if ( !sms ) return; FOREACH_ARRAY( quality_level_t *qlevel, sms->qlevels ); if( qlevel ) ql_Free( qlevel ); FOREACH_END(); ARRAY_RESET( sms->qlevels ); vlc_mutex_lock( &sms->chunks_lock ); while( sms->p_chunks ) { chunk_t *p_chunk = sms->p_chunks; sms->p_chunks = sms->p_chunks->p_next; chunk_Free( p_chunk ); } vlc_mutex_unlock( &sms->chunks_lock ); vlc_mutex_destroy( &sms->chunks_lock ); free( sms->name ); free( sms->url_template ); free( sms ); }
static size_t sms_Read( stream_t *s, uint8_t *p_read, size_t i_read ) { stream_sys_t *p_sys = s->p_sys; size_t copied = 0; chunk_t *chunk = NULL; do { bool b_isinitchunk = false; chunk = get_chunk( s, true, &b_isinitchunk ); /* chunk here won't be processed further */ // msg_Dbg( s, "chunk %"PRIu64" init %d", (uint64_t) chunk, b_isinitchunk ); if( !chunk ) return copied; if( chunk->read_pos >= chunk->size ) { if ( b_isinitchunk ) { assert( chunk->read_pos == chunk->size ); vlc_mutex_lock( &p_sys->playback.lock ); p_sys->playback.init.p_startchunk = NULL; p_sys->playback.init.p_datachunk = NULL; chunk_Free( chunk ); vlc_mutex_unlock( &p_sys->playback.lock ); } else { vlc_mutex_lock( &p_sys->lock ); if( gotoNextChunk( p_sys ) == NULL ) { vlc_mutex_unlock( &p_sys->lock ); return 0; } vlc_mutex_unlock( &p_sys->lock ); } continue; } if( chunk->read_pos == 0 ) { const char *verb = p_read == NULL ? "skipping" : "reading"; msg_Dbg( s, "%s chunk time %"PRIu64" (%zu bytes), type %i", verb, chunk->start_time, i_read, chunk->type ); } uint64_t len = 0; uint8_t *src = chunk->data + chunk->read_pos; if( i_read <= chunk->size - chunk->read_pos ) len = i_read; else len = chunk->size - chunk->read_pos; if( len > 0 ) { if( p_read ) /* otherwise caller skips data */ memcpy( p_read + copied, src, len ); chunk->read_pos += len; copied += len; i_read -= len; p_sys->playback.boffset += len; } } while ( i_read > 0 ); return copied; }