[vlc-devel] [PATCH 39/48] hls: Reworking segment download synchronization.
Hugo Beauzée-Luyssen
beauze.h at gmail.com
Mon Jan 9 16:16:48 CET 2012
---
modules/stream_filter/httplive.c | 45 ++++++++++++++++++++++++-------------
1 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index 14bb159..77a0b3c 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -77,6 +77,9 @@ typedef struct segment_s
vlc_mutex_t lock;
block_t *data; /* data */
+
+ vlc_cond_t wait; /* A condition to wait for segment data download
+ This wait cond is locked by the segment mutex */
} segment_t;
typedef struct hls_stream_s
@@ -317,11 +320,13 @@ static segment_t *segment_New(hls_stream_t* hls, const int duration, const char
segment->psz_key_path = NULL;
if (hls->psz_current_key_path)
segment->psz_key_path = strdup(hls->psz_current_key_path);
+ vlc_cond_init( &segment->wait );
return segment;
}
static void segment_Free(segment_t *segment)
{
+ vlc_cond_destroy( &segment->wait );
vlc_mutex_destroy(&segment->lock);
free(segment->uri);
@@ -1456,9 +1461,7 @@ static int hls_DownloadSegmentData(stream_t *s, hls_stream_t *hls, segment_t *se
{
msg_Err(s, "downloaded segment %d from stream %d failed",
segment->sequence, *cur_stream);
- vlc_mutex_unlock(&segment->lock);
- p_sys->b_reset = true;
- return VLC_EGENERIC;
+ goto fail;
}
mtime_t duration = mdate() - start;
@@ -1470,13 +1473,14 @@ static int hls_DownloadSegmentData(stream_t *s, hls_stream_t *hls, segment_t *se
/* If the segment is encrypted, decode it */
if (hls_DecodeSegmentData(s, hls, segment) != VLC_SUCCESS)
{
- vlc_mutex_unlock(&segment->lock);
- p_sys->b_reset = true;
- return VLC_EGENERIC;
+ msg_Err( s, "Failed to decode segment data" );
+ goto fail;
}
duration = mdate() - start;
+ //Signal we just finished downloading a segment so the playback can go on.
+ vlc_cond_signal( &segment->wait );
vlc_mutex_unlock(&segment->lock);
msg_Info(s, "decode segment %d from stream %d in %dms",
@@ -1508,6 +1512,13 @@ static int hls_DownloadSegmentData(stream_t *s, hls_stream_t *hls, segment_t *se
}
}
return VLC_SUCCESS;
+
+fail:
+ //Don't make the playback thread wait forever
+ vlc_cond_signal( &segment->wait );
+ vlc_mutex_unlock(&segment->lock);
+ p_sys->b_reset = true;
+ return VLC_EGENERIC;
}
static void* hls_Thread(void *p_this)
@@ -1523,7 +1534,6 @@ static void* hls_Thread(void *p_this)
assert(hls);
/* Wait to be wake up when a new segment is needed */
- msg_Dbg(s, "Sleeping until we have a new segment to download");
vlc_mutex_lock(&p_sys->download.lock_wait);
vlc_cond_wait(&p_sys->download.wait, &p_sys->download.lock_wait);
vlc_mutex_unlock(&p_sys->download.lock_wait);
@@ -2087,18 +2097,21 @@ static segment_t *GetSegment(stream_t *s)
} while (segment == NULL);
/* Is this segment ready ? */
- while (vlc_object_alive(s) && p_sys->b_quit == false)
+ vlc_mutex_lock(&segment->lock);
+ if ( segment->data == NULL )
{
- vlc_mutex_lock(&segment->lock);
- if (segment->data)
- {
- vlc_mutex_unlock(&segment->lock);
- break;
- }
- vlc_mutex_unlock(&segment->lock);
+ //Awake the download thread:
+ vlc_mutex_lock( &p_sys->download.lock_wait );
+ vlc_cond_signal( &p_sys->download.wait );
+ vlc_mutex_unlock( &p_sys->download.lock_wait );
+ }
+ while ( segment->data == NULL && vlc_object_alive(s) && p_sys->b_quit == false )
+ {
+ //And wait for the download to be successfull...
msg_Warn(s, "The segment (%d) is not downloaded for stream %d. Waiting a little bit....", p_sys->playback.segment, p_sys->playback.stream);
- msleep(1000000);
+ vlc_cond_wait( &segment->wait, &segment->lock );
}
+ vlc_mutex_unlock(&segment->lock);
return segment;
}
--
1.7.8.3
More information about the vlc-devel
mailing list