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.c73
1 files changed, 66 insertions, 7 deletions
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index d06e82afa..e4af36e3c 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -44,10 +44,10 @@
#define LOG
*/
-#include "xine_internal.h"
-#include "video_out.h"
-#include "metronom.h"
-#include "xineutils.h"
+#include <xine/xine_internal.h>
+#include <xine/video_out.h>
+#include <xine/metronom.h>
+#include <xine/xineutils.h>
#define NUM_FRAME_BUFFERS 15
#define MAX_USEC_TO_SLEEP 20000
@@ -132,6 +132,9 @@ typedef struct {
int frame_drop_cpt;
int frame_drop_suggested;
int crop_left, crop_right, crop_top, crop_bottom;
+ pthread_mutex_t trigger_drawing_mutex;
+ pthread_cond_t trigger_drawing_cond;
+ int trigger_drawing;
} vos_t;
@@ -930,8 +933,8 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts,
img->vpts = cur_vpts;
/* extra info of the backup is thrown away, because it is not up to date */
_x_extra_info_reset(img->extra_info);
+ img->future_frame = NULL;
}
-
return img;
} else {
@@ -990,6 +993,13 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts,
* remove frame from display queue and show it
*/
+ if ( img ) {
+ if ( img->next )
+ img->future_frame = img->next;
+ else
+ img->future_frame = NULL;
+ }
+
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
@@ -1068,6 +1078,32 @@ static void check_redraw_needed (vos_t *this, int64_t vpts) {
this->redraw_needed = 1;
}
+static int interruptable_sleep(vos_t *this, int usec_to_sleep)
+{
+ int timedout = 0;
+
+ struct timeval now;
+ gettimeofday(&now, 0);
+
+ pthread_mutex_lock (&this->trigger_drawing_mutex);
+ if (!this->trigger_drawing) {
+ struct timespec abstime;
+ abstime.tv_sec = now.tv_sec + usec_to_sleep / 1000000;
+ abstime.tv_nsec = now.tv_usec * 1000 + (usec_to_sleep % 1000000) * 1000;
+
+ if (abstime.tv_nsec > 1000000000) {
+ abstime.tv_nsec -= 1000000000;
+ abstime.tv_sec++;
+ }
+
+ timedout = pthread_cond_timedwait(&this->trigger_drawing_cond, &this->trigger_drawing_mutex, &abstime);
+ }
+ this->trigger_drawing = 0;
+ pthread_mutex_unlock (&this->trigger_drawing_mutex);
+
+ return timedout;
+}
+
/* special loop for paused mode
* needed to update screen due overlay changes, resize, window
* movement, brightness adjusting etc.
@@ -1113,7 +1149,7 @@ static void paused_loop( vos_t *this, int64_t vpts )
}
pthread_mutex_unlock( &this->free_img_buf_queue->mutex );
- xine_usec_sleep (20000);
+ interruptable_sleep(this, 20000);
pthread_mutex_lock( &this->free_img_buf_queue->mutex );
}
@@ -1243,7 +1279,10 @@ static void *video_out_loop (void *this_gen) {
"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 (0 == interruptable_sleep(this, usec_to_sleep))
+ break;
+ }
if (this->discard_frames)
break;
@@ -1427,6 +1466,8 @@ static int vo_get_property (xine_video_port_t *this_gen, int property) {
ret = this->crop_bottom;
break;
+ case XINE_PARAM_VO_SHARPNESS:
+ case XINE_PARAM_VO_NOISE_REDUCTION:
case XINE_PARAM_VO_HUE:
case XINE_PARAM_VO_SATURATION:
case XINE_PARAM_VO_CONTRAST:
@@ -1519,6 +1560,8 @@ static int vo_set_property (xine_video_port_t *this_gen, int property, int value
ret = this->crop_bottom = value;
break;
+ case XINE_PARAM_VO_SHARPNESS:
+ case XINE_PARAM_VO_NOISE_REDUCTION:
case XINE_PARAM_VO_HUE:
case XINE_PARAM_VO_SATURATION:
case XINE_PARAM_VO_CONTRAST:
@@ -1629,6 +1672,9 @@ static void vo_exit (xine_video_port_t *this_gen) {
free (this->free_img_buf_queue);
free (this->display_img_buf_queue);
+ pthread_cond_destroy(&this->trigger_drawing_cond);
+ pthread_mutex_destroy(&this->trigger_drawing_mutex);
+
free (this);
}
@@ -1698,6 +1744,15 @@ static void vo_flush (xine_video_port_t *this_gen) {
}
}
+static void vo_trigger_drawing (xine_video_port_t *this_gen) {
+ vos_t *this = (vos_t *) this_gen;
+
+ pthread_mutex_lock (&this->trigger_drawing_mutex);
+ this->trigger_drawing = 1;
+ pthread_cond_signal (&this->trigger_drawing_cond);
+ pthread_mutex_unlock (&this->trigger_drawing_mutex);
+}
+
/* crop_frame() will allocate a new frame to copy in the given image
* while cropping. maybe someday this will be an automatic post plugin.
*/
@@ -1793,6 +1848,7 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon
this->vo.enable_ovl = vo_enable_overlay;
this->vo.get_overlay_manager = vo_get_overlay_manager;
this->vo.flush = vo_flush;
+ this->vo.trigger_drawing = vo_trigger_drawing;
this->vo.get_property = vo_get_property;
this->vo.set_property = vo_set_property;
this->vo.status = vo_status;
@@ -1886,6 +1942,9 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon
"were not scheduled for display in time, xine sends a notification."),
20, NULL, NULL);
+ pthread_mutex_init(&this->trigger_drawing_mutex, NULL);
+ pthread_cond_init(&this->trigger_drawing_cond, NULL);
+ this->trigger_drawing = 0;
if (grabonly) {