diff options
-rw-r--r-- | src/xine-engine/video_out.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index f0664210e..81d7f3a3b 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.c @@ -127,6 +127,7 @@ typedef struct { int current_width, current_height; int64_t current_duration; + int frame_drop_limit_max; int frame_drop_limit; int frame_drop_cpt; int crop_left, crop_right, crop_top, crop_bottom; @@ -471,25 +472,28 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) { duration = img->duration; /* Frame dropping slow start: - * The engine starts to drop frames if there is less than frame_drop_limit + * The engine starts to drop frames if there are less than frame_drop_limit * frames in advance. There might be a problem just after a seek because * there is no frame in advance yet. * The following code increases progressively the frame_drop_limit (-2 -> 3) * after a seek to give a chance to the engine to display the first frames - * smootly before starting to drop frames if the decoder is really too + * smoothly before starting to drop frames if the decoder is really too * slow. + * The above numbers are the result of frame_drop_limit_max beeing 3. They + * will be (-4 -> 1) when frame_drop_limit_max is only 1. This maximum value + * depends on the number of video buffers which the output device provides. */ if (stream && stream->first_frame_flag == 2) this->frame_drop_cpt = 10; if (this->frame_drop_cpt) { - this->frame_drop_limit = 3 - (this->frame_drop_cpt / 2); + this->frame_drop_limit = this->frame_drop_limit_max - (this->frame_drop_cpt / 2); this->frame_drop_cpt--; } frames_to_skip = ((-1 * diff) / duration + this->frame_drop_limit) * 2; /* do not skip decoding until output fifo frames are consumed */ - if (this->display_img_buf_queue->num_buffers > this->frame_drop_limit || + if (this->display_img_buf_queue->num_buffers >= this->frame_drop_limit || frames_to_skip < 0) frames_to_skip = 0; @@ -1789,8 +1793,6 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon this->overlay_source->init (this->overlay_source); this->overlay_enabled = 1; - this->frame_drop_limit = 3; - this->frame_drop_cpt = 0; /* default number of video frames from config */ num_frame_buffers = xine->config->register_num (xine->config, @@ -1811,6 +1813,23 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon if (num_frame_buffers<5) num_frame_buffers = 5; + /* Choose a frame_drop_limit which matches num_frame_buffers. + * xxmc for example supplies only 8 buffers. 2 are occupied by + * MPEG2 decoding, further 2 for displaying and the remaining 4 can + * hardly be filled all the time. + * The below constants reserve buffers for decoding, displaying and + * buffer fluctuation. + * A frame_drop_limit_max below 1 will disable frame drops at all. + */ + this->frame_drop_limit_max = num_frame_buffers - 2 - 2 - 1; + if (this->frame_drop_limit_max < 1) + this->frame_drop_limit_max = 1; + else if (this->frame_drop_limit_max > 3) + this->frame_drop_limit_max = 3; + + this->frame_drop_limit = this->frame_drop_limit_max; + this->frame_drop_cpt = 0; + this->extra_info_base = calloc (num_frame_buffers, sizeof(extra_info_t)); |