summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/xine-engine/video_out.c31
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));