summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2011-08-22 11:51:20 +0200
committerTorsten Jager <t.jager@gmx.de>2011-08-22 11:51:20 +0200
commitedb68926aced0739f3e62ea2501bc32326c02f86 (patch)
treeebce4f31bf17486bc1ffffb55e183eeef1b7db20
parent7e6f30b0062375c30db8e67b464c7fe003ed15d5 (diff)
downloadxine-lib-edb68926aced0739f3e62ea2501bc32326c02f86.tar.gz
xine-lib-edb68926aced0739f3e62ea2501bc32326c02f86.tar.bz2
Video deadlock fix
When watching TV with Kaffeine I frequently had complete engine lockups. Multiple mutexes were waiting on each other. net_buf_ctrl requires the demuxer to keep running while playback is still paused. The diff might look a bit confusing. Basically, all I did was to replace phtread_mutex_lock (); ... pthread_mutex_unlock (); with if (pthread_mutex_trylock ()) { ... pthread_mutex_unlock (); } at a place where it does the least damage.
-rw-r--r--src/xine-engine/video_out.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index f3e24537e..a6d39f23f 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -572,25 +572,28 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
* check for first frame after seek and mark it
*/
img->is_first = 0;
- pthread_mutex_lock(&this->streams_lock);
- for (ite = xine_list_front(this->streams); ite;
- ite = xine_list_next(this->streams, ite)) {
- stream = xine_list_get_value(this->streams, ite);
- if (stream == XINE_ANON_STREAM) continue;
- pthread_mutex_lock (&stream->first_frame_lock);
- if (stream->first_frame_flag == 2) {
- if (this->grab_only) {
- stream->first_frame_flag = 0;
- pthread_cond_broadcast(&stream->first_frame_reached);
- } else
- stream->first_frame_flag = 1;
- img->is_first = FIRST_FRAME_MAX_POLL;
-
- lprintf ("get_next_video_frame first_frame_reached\n");
+ /* avoid a complex deadlock situation caused by net_buf_control */
+ if (!pthread_mutex_trylock(&this->streams_lock)) {
+ for (ite = xine_list_front(this->streams); ite;
+ ite = xine_list_next(this->streams, ite)) {
+ stream = xine_list_get_value(this->streams, ite);
+ if (stream == XINE_ANON_STREAM) continue;
+ pthread_mutex_lock (&stream->first_frame_lock);
+ if (stream->first_frame_flag == 2) {
+ if (this->grab_only) {
+ stream->first_frame_flag = 0;
+ pthread_cond_broadcast(&stream->first_frame_reached);
+ } else {
+ stream->first_frame_flag = 1;
+ }
+ img->is_first = FIRST_FRAME_MAX_POLL;
+
+ lprintf ("get_next_video_frame first_frame_reached\n");
+ }
+ pthread_mutex_unlock (&stream->first_frame_lock);
}
- pthread_mutex_unlock (&stream->first_frame_lock);
+ pthread_mutex_unlock(&this->streams_lock);
}
- pthread_mutex_unlock(&this->streams_lock);
if (!img_already_locked)
vo_frame_inc_lock( img );