summaryrefslogtreecommitdiff
path: root/src/xine-engine/video_out.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine/video_out.c')
-rw-r--r--src/xine-engine/video_out.c64
1 files changed, 46 insertions, 18 deletions
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 598b48830..65a7f7d56 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.c,v 1.189 2004/03/23 15:38:04 mroi Exp $
+ * $Id: video_out.c,v 1.190 2004/04/22 23:19:04 tmattern Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -51,7 +51,9 @@
#include "metronom.h"
#include "xineutils.h"
-#define NUM_FRAME_BUFFERS 15
+#define NUM_FRAME_BUFFERS 15
+#define MAX_USEC_TO_SLEEP 20000
+#define DEFAULT_FRAME_DURATION 3000 /* 30 frames per second */
#define NULL_STREAM (xine_stream_t *)-1
@@ -373,9 +375,10 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
this->num_frames_delivered++;
diff = pic_vpts - cur_vpts;
+
/* avoid division by zero */
if( img->duration <= 0 )
- img->duration = 3000;
+ img->duration = DEFAULT_FRAME_DURATION;
/* Frame dropping slow start:
* The engine starts to drop frames if there is less than frame_drop_limit
@@ -619,6 +622,7 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) {
int64_t pts;
int64_t diff;
vo_frame_t *img;
+ int duration;
pthread_mutex_lock(&this->display_img_buf_queue->mutex);
@@ -629,8 +633,9 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) {
*/
diff = 1000000; /* always enter the while-loop */
+ duration = 0;
- while (img && (diff > img->duration || this->discard_frames)) {
+ while (img) {
if (img->is_first) {
lprintf("expire_frames: first_frame !\n");
@@ -645,10 +650,18 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) {
break;
}
+ if( !img->duration ) {
+ if( img->next )
+ duration = img->next->vpts - img->vpts;
+ else
+ duration = DEFAULT_FRAME_DURATION;
+ } else
+ duration = img->duration;
+
pts = img->vpts;
diff = cur_vpts - pts;
- if (diff > img->duration || this->discard_frames) {
+ if (diff > duration || this->discard_frames) {
if( !this->discard_frames ) {
xine_log(this->xine, XINE_LOG_MSG,
@@ -700,13 +713,19 @@ static void expire_frames (vos_t *this, int64_t cur_vpts) {
}
}
img = this->display_img_buf_queue->first;
- }
+
+ } else
+ break;
}
pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
}
-static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
+/* If it's not the time to display the next frame,
+ * the vpts of the next frame (if any) is returned, 0 otherwise.
+ */
+static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts,
+ int64_t *next_frame_vpts) {
vo_frame_t *img;
@@ -714,6 +733,8 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
img = this->display_img_buf_queue->first;
+ *next_frame_vpts = 0;
+
/*
* still frame detection:
*/
@@ -764,6 +785,7 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
lprintf ("diff %" PRId64 "\n", diff);
if (diff < 0) {
+ *next_frame_vpts = img->vpts;
pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
return NULL;
}
@@ -933,7 +955,7 @@ static void *video_out_loop (void *this_gen) {
int64_t vpts, diff;
vo_frame_t *img;
vos_t *this = (vos_t *) this_gen;
- int64_t next_frame_vpts;
+ int64_t next_frame_vpts = 0;
int64_t usec_to_sleep;
#ifndef WIN32
@@ -950,8 +972,6 @@ static void *video_out_loop (void *this_gen) {
* of xine) : the video output loop
*/
- next_frame_vpts = this->clock->get_current_time (this->clock);
-
lprintf ("loop starting...\n");
while ( this->video_loop_running ) {
@@ -965,7 +985,8 @@ static void *video_out_loop (void *this_gen) {
lprintf ("loop iteration at %" PRId64 "\n", vpts);
expire_frames (this, vpts);
- img = get_next_frame (this, vpts);
+
+ img = get_next_frame (this, vpts, &next_frame_vpts);
/*
* if we have found a frame, display it
@@ -1015,13 +1036,10 @@ static void *video_out_loop (void *this_gen) {
/*
* wait until it's time to display next frame
*/
-
if (img) {
next_frame_vpts = img->vpts + img->duration;
- } else {
- /* we do not know, when the next frame is due, so only wait a little */
- next_frame_vpts += 1000;
}
+ /* else next_frame_vpts is returned by get_next_frame */
lprintf ("next_frame_vpts is %" PRId64 "\n", next_frame_vpts);
@@ -1031,7 +1049,17 @@ static void *video_out_loop (void *this_gen) {
if (this->clock->speed == XINE_SPEED_PAUSE)
paused_loop (this, vpts);
- usec_to_sleep = (next_frame_vpts - vpts) * 100 / 9;
+ if (next_frame_vpts) {
+ usec_to_sleep = (next_frame_vpts - vpts) * 100 / 9;
+ } else {
+ /* we don't know when the next frame is due, only wait a little */
+ usec_to_sleep = 1000;
+ next_frame_vpts = vpts; /* wait only once */
+ }
+
+ /* limit usec_to_sleep to maintain responsiveness */
+ if (usec_to_sleep > MAX_USEC_TO_SLEEP)
+ usec_to_sleep = MAX_USEC_TO_SLEEP;
lprintf ("%" PRId64 " usec to sleep at master vpts %" PRId64 "\n", usec_to_sleep, vpts);
@@ -1039,8 +1067,8 @@ static void *video_out_loop (void *this_gen) {
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
"video_out: vpts/clock error, next_vpts=%" PRId64 " cur_vpts=%" PRId64 "\n", next_frame_vpts,vpts);
- if (usec_to_sleep>0)
- xine_usec_sleep (usec_to_sleep);
+ if (usec_to_sleep > 0)
+ xine_usec_sleep (usec_to_sleep);
} while ( (usec_to_sleep > 0) && this->video_loop_running);
}