From: <rn...@gm...> - 2008-01-01 15:56:37
|
# HG changeset patch # User Reinhard Nißl <rn...@gm...> # Date 1176667878 -7200 # Node ID f6a62a79c3fcbb1c70b417fc91a87eb1beb751ad # Parent eb2836e596c9f4d9ef536f9b0fdbdc2c82ca3f64 Choose maximum for frame drop limit depending on the number of allocated frames. The current code uses a hard coded frame drop limit of 3 and doesn't adhere to it's documentation when testing whether frames shall be dropped. As a result frame drop limit is actually 4, which means that the decoder is asked to drop some frames when the number of frames waiting for displaying is less then 4. Consider a video out device like xxmc which only supplies 8 frames. For MPEG2 decoding, two frames will be used by the decoder (for the current frame and the forward reference frame) and two further frames will be used in the video out loop (the current and the previous frame) so that at any given time (under perfect conditions) there will be 4 frames waiting to be displayed. But when there are delays in scheduling, it might happen that there are only 3 frames ready for displaying and thus will result in asking the decoder to drop frames. The changes therefore determine the maximum frame drop limit in dependence of the number of allocated frames and make the detection work like documented. In the above scenario, the maximum number actually used for frame drop limit will then be 2 which allows to compensate some scheduling delays without causing the decoder to drop frames. (transplanted from 2936fd493eafe3f176f2e791340167513b4e8048) diff -r f6a62a79c3fcbb1c70b417fc91a87eb1beb751ad -r eb2836e596c9f4d9ef536f9b0fdbdc2c82ca3f64 src/xine-engine/video_out.c --- a/src/xine-engine/video_out.c Sun Apr 15 22:11:18 2007 +0200 +++ b/src/xine-engine/video_out.c Sun Apr 15 21:39:37 2007 +0200 @@ -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 *im 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_ 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, @@ -1810,6 +1812,23 @@ xine_video_port_t *_x_vo_new_port (xine_ /* we need at least 5 frames */ 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)); |