summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/audio_decoder.c3
-rw-r--r--src/xine-engine/buffer_types.c8
-rw-r--r--src/xine-engine/video_out.c59
3 files changed, 52 insertions, 18 deletions
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index e2d0acd04..e36f576bd 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.c
@@ -283,6 +283,9 @@ static void *audio_decoder_loop (void *stream_gen) {
}
stream->audio_track_map[i] = buf->type;
stream->audio_track_map_entries++;
+ /* implicit channel change - reopen decoder below */
+ if ((i == 0) && (audio_channel_user == -1) && (stream->audio_channel_auto < 0))
+ stream->audio_decoder_streamtype = -1;
ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
ui_event.data_length = 0;
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index dc8550ca1..6f45672ee 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.c
@@ -791,6 +791,14 @@ static const video_db_t video_db[] = {
BUF_VIDEO_SNOW,
"Snow"
},
+{
+ {
+ ME_FOURCC('V','P','8','0'),
+ 0
+ },
+ BUF_VIDEO_VP8,
+ "On2 VP8"
+},
{ { 0 }, 0, "last entry" }
};
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index f348da3f5..cc428137e 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -880,25 +880,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 );
@@ -1110,7 +1113,7 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) {
while (img) {
- if (img->is_first) {
+ if (img->is_first > 0) {
lprintf("expire_frames: first_frame !\n");
/*
@@ -1127,6 +1130,8 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) {
img->vpts = cur_vpts + FIRST_FRAME_POLL_DELAY;
}
img->is_first--;
+ /* make sure to wake up xine_play even if this first frame gets discarded */
+ if (img->is_first == 0) img->is_first = -1;
break;
}
@@ -1156,6 +1161,24 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) {
pthread_mutex_lock( &img->stream->current_extra_info_lock );
_x_extra_info_merge( img->stream->current_extra_info, img->extra_info );
pthread_mutex_unlock( &img->stream->current_extra_info_lock );
+ /* wake up xine_play now if we just discarded first frame */
+ if (img->is_first != 0) {
+ xine_list_iterator_t ite;
+ pthread_mutex_lock (&this->streams_lock);
+ for (ite = xine_list_front(this->streams); ite;
+ ite = xine_list_next(this->streams, ite)) {
+ xine_stream_t *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) {
+ stream->first_frame_flag = 0;
+ pthread_cond_broadcast (&stream->first_frame_reached);
+ }
+ pthread_mutex_unlock (&stream->first_frame_lock);
+ }
+ pthread_mutex_unlock(&this->streams_lock);
+ xine_log (this->xine, XINE_LOG_MSG, _("video_out: just discarded first frame after seek\n"));
+ }
}
/* when flushing frames, keep the first one as backup */