diff options
author | Torsten Jager <t.jager@gmx.de> | 2011-08-22 11:51:20 +0200 |
---|---|---|
committer | Torsten Jager <t.jager@gmx.de> | 2011-08-22 11:51:20 +0200 |
commit | edb68926aced0739f3e62ea2501bc32326c02f86 (patch) | |
tree | ebce4f31bf17486bc1ffffb55e183eeef1b7db20 | |
parent | 7e6f30b0062375c30db8e67b464c7fe003ed15d5 (diff) | |
download | xine-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.c | 37 |
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 ); |