Commit f67cdb74 authored by Frédéric Yhuel's avatar Frédéric Yhuel Committed by Jean-Baptiste Kempf

Smooth Streaming: clean / factorize code

and prepare subtitle support
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent f2cc02bf
This diff is collapsed.
...@@ -404,8 +404,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -404,8 +404,10 @@ static int Open( vlc_object_t *p_this )
p_sys->b_cache = false; p_sys->b_cache = false;
p_sys->sms_streams = vlc_array_new(); p_sys->sms_streams = vlc_array_new();
p_sys->selected_st = vlc_array_new();
p_sys->download.chunks = vlc_array_new(); p_sys->download.chunks = vlc_array_new();
if( unlikely( !p_sys->sms_streams || !p_sys->download.chunks ) ) if( unlikely( !p_sys->sms_streams || !p_sys->download.chunks ||
!p_sys->selected_st ) )
{ {
free( p_sys ); free( p_sys );
return VLC_ENOMEM; return VLC_ENOMEM;
...@@ -423,34 +425,14 @@ static int Open( vlc_object_t *p_this ) ...@@ -423,34 +425,14 @@ static int Open( vlc_object_t *p_this )
p_sys->i_tracks = vlc_array_count( p_sys->sms_streams ); p_sys->i_tracks = vlc_array_count( p_sys->sms_streams );
/* FIXME */ /* Choose first video / audio / subtitle stream available */
p_sys->i_selected_tracks = 2; /* one video track and one audio track */ sms_stream_t *tmp = NULL, *selected = NULL;
/* Choose first video stream available */
sms_stream_t *vsms = NULL;
for( unsigned i = 0; i < p_sys->i_tracks; i++ ) for( unsigned i = 0; i < p_sys->i_tracks; i++ )
{ {
vsms = vlc_array_item_at_index( p_sys->sms_streams, i ); tmp = vlc_array_item_at_index( p_sys->sms_streams, i );
if( vsms->type == VIDEO_ES ) selected = SMS_GET_SELECTED_ST( tmp->type );
{ if( !selected )
msg_Dbg( s, "Video stream chosen is %s", vsms->name ); vlc_array_append( p_sys->selected_st, tmp );
p_sys->vstream = vsms;
break;
}
}
/* Choose first audio stream available */
sms_stream_t *asms = NULL;
for( unsigned i = 0; i < p_sys->i_tracks; i++ )
{
asms = vlc_array_item_at_index( p_sys->sms_streams, i );
//if( asms->type == AUDIO_ES && !strcmp( asms->name, "audio_eng" ) )
if( asms->type == AUDIO_ES )
{
msg_Dbg( s, "Audio stream chosen is %s", asms->name );
p_sys->astream = asms;
break;
}
} }
/* Choose lowest quality for the first chunks */ /* Choose lowest quality for the first chunks */
...@@ -498,7 +480,8 @@ static void Close( vlc_object_t *p_this ) ...@@ -498,7 +480,8 @@ static void Close( vlc_object_t *p_this )
vlc_mutex_lock( &p_sys->download.lock_wait ); vlc_mutex_lock( &p_sys->download.lock_wait );
p_sys->b_close = true; p_sys->b_close = true;
/* Negate the condition variable's predicate */ /* Negate the condition variable's predicate */
p_sys->download.vlead = p_sys->download.alead = 0; for( int i = 0; i < 3; i++ )
p_sys->download.lead[i] = 0;
p_sys->playback.toffset = 0; p_sys->playback.toffset = 0;
vlc_cond_signal(&p_sys->download.wait); vlc_cond_signal(&p_sys->download.wait);
vlc_mutex_unlock( &p_sys->download.lock_wait ); vlc_mutex_unlock( &p_sys->download.lock_wait );
...@@ -544,9 +527,7 @@ static chunk_t *get_chunk( stream_t *s, const bool wait ) ...@@ -544,9 +527,7 @@ static chunk_t *get_chunk( stream_t *s, const bool wait )
p_sys->playback.index ); p_sys->playback.index );
return NULL; return NULL;
} }
if( !p_sys->b_live && if( NO_MORE_CHUNKS )
p_sys->download.aindex >= (p_sys->vstream->vod_chunks_nb -1) &&
p_sys->download.vindex >= (p_sys->astream->vod_chunks_nb -1) )
{ {
vlc_mutex_unlock( &p_sys->download.lock_wait ); vlc_mutex_unlock( &p_sys->download.lock_wait );
msg_Info( s, "No more chunks, end of the VOD" ); msg_Info( s, "No more chunks, end of the VOD" );
...@@ -580,7 +561,8 @@ static int sms_Read( stream_t *s, uint8_t *p_read, int i_read ) ...@@ -580,7 +561,8 @@ static int sms_Read( stream_t *s, uint8_t *p_read, int i_read )
if( chunk->read_pos >= (int)chunk->size ) if( chunk->read_pos >= (int)chunk->size )
{ {
if( chunk->type == VIDEO_ES || !p_sys->vstream ) if( chunk->type == VIDEO_ES ||
( !SMS_GET_SELECTED_ST( VIDEO_ES ) && chunk->type == AUDIO_ES ) )
{ {
vlc_mutex_lock( &p_sys->download.lock_wait ); vlc_mutex_lock( &p_sys->download.lock_wait );
p_sys->playback.toffset += chunk->duration; p_sys->playback.toffset += chunk->duration;
...@@ -727,7 +709,8 @@ static int chunk_Seek( stream_t *s, const uint64_t pos ) ...@@ -727,7 +709,8 @@ static int chunk_Seek( stream_t *s, const uint64_t pos )
p_sys->b_tseek = true; p_sys->b_tseek = true;
p_sys->time_pos = p_sys->vod_duration * pos / FAKE_STREAM_SIZE; p_sys->time_pos = p_sys->vod_duration * pos / FAKE_STREAM_SIZE;
p_sys->download.vlead = p_sys->download.alead = 0; for( int i = 0; i < 3; i++ )
p_sys->download.lead[i] = 0;
p_sys->playback.toffset = 0; p_sys->playback.toffset = 0;
vlc_cond_signal( &p_sys->download.wait); vlc_cond_signal( &p_sys->download.wait);
......
...@@ -89,12 +89,9 @@ struct stream_sys_t ...@@ -89,12 +89,9 @@ struct stream_sys_t
char *base_url; /* URL common part for chunks */ char *base_url; /* URL common part for chunks */
vlc_thread_t thread; /* SMS chunk download thread */ vlc_thread_t thread; /* SMS chunk download thread */
vlc_array_t *sms_streams; /* array of sms_stream_t */ vlc_array_t *sms_streams; /* available streams */
sms_stream_t *vstream; /* current video stream */ vlc_array_t *selected_st; /* selected streams */
sms_stream_t *astream; /* current audio stream */
sms_stream_t *tstream; /* current text stream */
unsigned i_tracks; /* Total number of tracks in the Manifest */ unsigned i_tracks; /* Total number of tracks in the Manifest */
unsigned i_selected_tracks;
sms_queue_t *bws; /* Measured bandwidths of the N last chunks */ sms_queue_t *bws; /* Measured bandwidths of the N last chunks */
uint64_t vod_duration; /* total duration of the VOD media */ uint64_t vod_duration; /* total duration of the VOD media */
int64_t time_pos; int64_t time_pos;
...@@ -103,13 +100,10 @@ struct stream_sys_t ...@@ -103,13 +100,10 @@ struct stream_sys_t
/* Download */ /* Download */
struct sms_download_s struct sms_download_s
{ {
uint64_t alead; // how much audio/video/text data is uint64_t lead[3]; /* how much audio/video/text data is available
uint64_t vlead; // available (downloaded), (downloaded), in seconds / TimeScale */
uint64_t tlead; // in seconds / TimeScale
unsigned aindex; /* current audio chunk for download */ unsigned ck_index[3]; /* current chunk for download */
unsigned vindex; /* video */
unsigned sindex; /* spu */
uint64_t next_chunk_offset; uint64_t next_chunk_offset;
vlc_array_t *chunks; /* chunks that have been downloaded */ vlc_array_t *chunks; /* chunks that have been downloaded */
...@@ -164,6 +158,12 @@ struct stream_sys_t ...@@ -164,6 +158,12 @@ struct stream_sys_t
slice += 4; \ slice += 4; \
} while(0) } while(0)
#define SMS_GET_SELECTED_ST( cat ) \
sms_get_stream_by_cat( p_sys->selected_st, cat )
#define NO_MORE_CHUNKS !p_sys->b_live && \
no_more_chunks( p_sys->download.ck_index, p_sys->selected_st )
sms_queue_t *sms_queue_init( const int ); sms_queue_t *sms_queue_init( const int );
int sms_queue_put( sms_queue_t *, const uint64_t ); int sms_queue_put( sms_queue_t *, const uint64_t );
uint64_t sms_queue_avg( sms_queue_t *); uint64_t sms_queue_avg( sms_queue_t *);
...@@ -176,5 +176,9 @@ void chunk_Free( chunk_t *); ...@@ -176,5 +176,9 @@ void chunk_Free( chunk_t *);
sms_stream_t * sms_New( void ); sms_stream_t * sms_New( void );
void sms_Free( sms_stream_t *); void sms_Free( sms_stream_t *);
uint8_t *decode_string_hex_to_binary( const char * ); uint8_t *decode_string_hex_to_binary( const char * );
sms_stream_t * sms_get_stream_by_cat( vlc_array_t *, int );
bool no_more_chunks( unsigned[], vlc_array_t *);
int index_to_es_cat( int );
int es_cat_to_index( int );
#endif #endif
...@@ -202,3 +202,63 @@ uint64_t sms_queue_avg( sms_queue_t *queue ) ...@@ -202,3 +202,63 @@ uint64_t sms_queue_avg( sms_queue_t *queue )
} }
return sum / queue->length; return sum / queue->length;
} }
sms_stream_t * sms_get_stream_by_cat( vlc_array_t *streams, int i_cat )
{
sms_stream_t *ret = NULL;
int count = vlc_array_count( streams );
assert( count >= 0 && count <= 3 );
for( int i = 0; i < count; i++ )
{
ret = vlc_array_item_at_index( streams, i );
if( ret->type == i_cat )
return ret;
}
return NULL;
}
int es_cat_to_index( int i_cat )
{
switch( i_cat )
{
case VIDEO_ES:
return 0;
case AUDIO_ES:
return 1;
case SPU_ES:
return 2;
default:
return -1;
}
}
int index_to_es_cat( int index )
{
switch( index )
{
case 0:
return VIDEO_ES;
case 1:
return AUDIO_ES;
case 2:
return SPU_ES;
default:
return -1;
}
}
bool no_more_chunks( unsigned *indexes, vlc_array_t *streams )
{
sms_stream_t *sms = NULL;
int count = vlc_array_count( streams );
unsigned ck_index;
for( int i = 0; i < count; i++ )
{
sms = vlc_array_item_at_index( streams, i );
ck_index = indexes[es_cat_to_index( sms->type )];
if( ck_index < sms->vod_chunks_nb - 1 )
return false;
}
return true;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment