From: Torsten J. <t....@gm...> - 2014-04-09 14:50:22
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1397054995 -7200 # Node ID 65313def5e8e5167f2ec8709cdcddbc851cbca4a # Branch default # Parent 2e9406b7320ea9c0beea58c905a7fee66f9c5af8 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. diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.c @@ -714,45 +714,57 @@ 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; - - 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); + 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; + + 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); + + } lprintf ("get_frame (%d x %d) done\n", width, height); @@ -1066,6 +1078,20 @@ 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 { |