summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2014-04-09 16:49:55 +0200
committerTorsten Jager <t.jager@gmx.de>2014-04-09 16:49:55 +0200
commit7938fb8aa66d9ffe7efc3a0a822d25d340a248d0 (patch)
tree3d03daf220a529117d68bd35526836d4b83a8bcf
parent3247f4d05093d20ccb94a1da100e65d11e4d379d (diff)
downloadxine-lib-7938fb8aa66d9ffe7efc3a0a822d25d340a248d0.tar.gz
xine-lib-7938fb8aa66d9ffe7efc3a0a822d25d340a248d0.tar.bz2
Handle "no vo soft render space".
Video out plugins may now fail to allocate soft render space in update_frame_format (), free possible parts of it, and indicate that with vo_frame.with == 0. vo_get_frame () will then free some more, and try again. I know that is hypothetical but I somehow feel better not letting it all run into a NULL pointer segfault immediately.
-rw-r--r--src/xine-engine/video_out.c100
1 files changed, 63 insertions, 37 deletions
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 8f6791fa8..a8db5f3a9 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -714,45 +714,57 @@ static vo_frame_t *vo_get_frame (xine_video_port_t *this_gen,
lprintf ("get_frame (%d x %d)\n", width, height);
- while (!(img = vo_remove_from_img_buf_queue_nonblock (this->free_img_buf_queue,
- width, height, ratio, format, flags)))
- if (this->xine->port_ticket->ticket_revoked)
- this->xine->port_ticket->renew(this->xine->port_ticket, 1);
-
- lprintf ("got a frame -> pthread_mutex_lock (&img->mutex)\n");
-
- /* some decoders report strange ratios */
- if (ratio <= 0.0)
- ratio = (double)width / (double)height;
+ while (1) {
+
+ while (!(img = vo_remove_from_img_buf_queue_nonblock (this->free_img_buf_queue,
+ width, height, ratio, format, flags)))
+ if (this->xine->port_ticket->ticket_revoked)
+ this->xine->port_ticket->renew(this->xine->port_ticket, 1);
+
+ lprintf ("got a frame -> pthread_mutex_lock (&img->mutex)\n");
+
+ /* some decoders report strange ratios */
+ if (ratio <= 0.0)
+ ratio = (double)width / (double)height;
+
+ pthread_mutex_lock (&img->mutex);
+ img->lock_counter = 1;
+ img->width = width;
+ img->height = height;
+ img->ratio = ratio;
+ img->format = format;
+ img->flags = flags;
+ img->proc_called = 0;
+ img->bad_frame = 0;
+ img->progressive_frame = 0;
+ img->repeat_first_field = 0;
+ img->top_field_first = 1;
+ img->crop_left = 0;
+ img->crop_right = 0;
+ img->crop_top = 0;
+ img->crop_bottom = 0;
+ img->overlay_offset_x = 0;
+ img->overlay_offset_y = 0;
+ img->stream = NULL;
+
+ _x_extra_info_reset ( img->extra_info );
+
+ /* let driver ensure this image has the right format */
+
+ this->driver->update_frame_format (this->driver, img, width, height,
+ ratio, format, flags);
+
+ pthread_mutex_unlock (&img->mutex);
+
+ if (!width || img->width)
+ break;
- pthread_mutex_lock (&img->mutex);
- img->lock_counter = 1;
- img->width = width;
- img->height = height;
- img->ratio = ratio;
- img->format = format;
- img->flags = flags;
- img->proc_called = 0;
- img->bad_frame = 0;
- img->progressive_frame = 0;
- img->repeat_first_field = 0;
- img->top_field_first = 1;
- img->crop_left = 0;
- img->crop_right = 0;
- img->crop_top = 0;
- img->crop_bottom = 0;
- img->overlay_offset_x = 0;
- img->overlay_offset_y = 0;
- img->stream = NULL;
-
- _x_extra_info_reset ( img->extra_info );
-
- /* let driver ensure this image has the right format */
-
- this->driver->update_frame_format (this->driver, img, width, height,
- ratio, format, flags);
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ _("video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n"),
+ width, height, img->format);
+ vo_append_to_img_buf_queue (this->free_img_buf_queue, img);
- pthread_mutex_unlock (&img->mutex);
+ }
lprintf ("get_frame (%d x %d) done\n", width, height);
@@ -1066,6 +1078,20 @@ static vo_frame_t * duplicate_frame( vos_t *this, vo_frame_t *img ) {
pthread_mutex_unlock (&dupl->mutex);
+ if (img->width && !dupl->width) {
+ /* driver failed to set up render space */
+ if (this->free_img_buf_queue->last)
+ this->free_img_buf_queue->last->next = dupl;
+ this->free_img_buf_queue->last = dupl;
+ if (this->free_img_buf_queue->first)
+ this->free_img_buf_queue->num_buffers++;
+ else {
+ this->free_img_buf_queue->first = dupl;
+ this->free_img_buf_queue->num_buffers = 1;
+ }
+ return NULL;
+ }
+
if (dupl->proc_duplicate_frame_data) {
dupl->proc_duplicate_frame_data(dupl,img);
} else {