diff options
author | Torsten Jager <t.jager@gmx.de> | 2014-04-09 16:49:55 +0200 |
---|---|---|
committer | Torsten Jager <t.jager@gmx.de> | 2014-04-09 16:49:55 +0200 |
commit | 7938fb8aa66d9ffe7efc3a0a822d25d340a248d0 (patch) | |
tree | 3d03daf220a529117d68bd35526836d4b83a8bcf | |
parent | 3247f4d05093d20ccb94a1da100e65d11e4d379d (diff) | |
download | xine-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.c | 100 |
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 { |