summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/spu_dec/spudvb_decoder.c1
-rw-r--r--src/video_out/video_out_vdpau.c567
2 files changed, 292 insertions, 276 deletions
diff --git a/src/spu_dec/spudvb_decoder.c b/src/spu_dec/spudvb_decoder.c
index eb14fc540..518903e01 100644
--- a/src/spu_dec/spudvb_decoder.c
+++ b/src/spu_dec/spudvb_decoder.c
@@ -901,7 +901,6 @@ static void draw_subtitles (dvb_spu_decoder_t * this)
for ( r=0; r<MAX_REGIONS; r++ ) {
lprintf("region=%d, visible=%d, osd=%d, empty=%d\n", r, this->dvbsub->page.regions[r].is_visible, this->dvbsub->regions[r].osd?1:0, this->dvbsub->regions[r].empty );
if ( this->dvbsub->page.regions[r].is_visible && this->dvbsub->regions[r].osd && !this->dvbsub->regions[r].empty ) {
- this->stream->osd_renderer->set_extent(this->dvbsub->regions[r].osd, SPU_MAX_WIDTH, SPU_MAX_HEIGHT);
this->stream->osd_renderer->set_position( this->dvbsub->regions[r].osd, this->dvbsub->page.regions[r].x, this->dvbsub->page.regions[r].y );
this->stream->osd_renderer->show( this->dvbsub->regions[r].osd, this->vpts );
lprintf("show region = %d\n",r);
diff --git a/src/video_out/video_out_vdpau.c b/src/video_out/video_out_vdpau.c
index 7d92302c2..57ee478b0 100644
--- a/src/video_out/video_out_vdpau.c
+++ b/src/video_out/video_out_vdpau.c
@@ -187,31 +187,30 @@ static VdpDecoderCreate *orig_vdp_decoder_create;
static VdpDecoderDestroy *orig_vdp_decoder_destroy;
static VdpDecoderRender *orig_vdp_decoder_render;
+#ifdef LOCKDISPLAY
+#define DO_LOCKDISPLAY XLockDisplay(guarded_display);
+#define DO_UNLOCKDISPLAY XUnlockDisplay(guarded_display);
static Display *guarded_display;
+#else
+#define DO_LOCKDISPLAY
+#define DO_UNLOCKDISPLAY
+#endif
static VdpStatus guarded_vdp_video_surface_putbits_ycbcr(VdpVideoSurface surface, VdpYCbCrFormat source_ycbcr_format, void const *const *source_data, uint32_t const *source_pitches)
{
VdpStatus r;
-#ifdef LOCKDISPLAY
- XLockDisplay(guarded_display);
-#endif
+ DO_LOCKDISPLAY
r = orig_vdp_video_surface_putbits_ycbcr(surface, source_ycbcr_format, source_data, source_pitches);
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return r;
}
static VdpStatus guarded_vdp_video_surface_create(VdpDevice device, VdpChromaType chroma_type, uint32_t width, uint32_t height,VdpVideoSurface *surface)
{
VdpStatus r;
-#ifdef LOCKDISPLAY
- XLockDisplay(guarded_display);
-#endif
+ DO_LOCKDISPLAY
r = orig_vdp_video_surface_create(device, chroma_type, width, height, surface);
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return r;
}
@@ -227,76 +226,63 @@ static VdpStatus guarded_vdp_video_surface_destroy(VdpVideoSurface surface)
static VdpStatus guarded_vdp_output_surface_create(VdpDevice device, VdpChromaType chroma_type, uint32_t width, uint32_t height,VdpVideoSurface *surface)
{
VdpStatus r;
-#ifdef LOCKDISPLAY
- XLockDisplay(guarded_display);
-#endif
+ DO_LOCKDISPLAY
r = orig_vdp_output_surface_create(device, chroma_type, width, height, surface);
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return r;
}
static VdpStatus guarded_vdp_output_surface_destroy(VdpVideoSurface surface)
{
VdpStatus r;
-#ifdef LOCKDISPLAY
- XLockDisplay(guarded_display);
-#endif
+ DO_LOCKDISPLAY
r = orig_vdp_output_surface_destroy(surface);
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return r;
}
static VdpStatus guarded_vdp_decoder_create(VdpDevice device, VdpDecoderProfile profile, uint32_t width, uint32_t height, uint32_t max_references, VdpDecoder *decoder)
{
VdpStatus r;
-#ifdef LOCKDISPLAY
- XLockDisplay(guarded_display);
-#endif
+ DO_LOCKDISPLAY
r = orig_vdp_decoder_create(device, profile, width, height, max_references, decoder);
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return r;
}
static VdpStatus guarded_vdp_decoder_destroy(VdpDecoder decoder)
{
VdpStatus r;
-#ifdef LOCKDISPLAY
- XLockDisplay(guarded_display);
-#endif
+ DO_LOCKDISPLAY
r = orig_vdp_decoder_destroy(decoder);
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return r;
}
static VdpStatus guarded_vdp_decoder_render(VdpDecoder decoder, VdpVideoSurface target, VdpPictureInfo const *picture_info, uint32_t bitstream_buffer_count, VdpBitstreamBuffer const *bitstream_buffers)
{
VdpStatus r;
-#ifdef LOCKDISPLAY
- XLockDisplay(guarded_display);
-#endif
+ DO_LOCKDISPLAY
r = orig_vdp_decoder_render(decoder, target, picture_info, bitstream_buffer_count, bitstream_buffers);
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return r;
}
typedef struct {
+ VdpOutputSurface surface;
+ uint32_t width;
+ uint32_t height;
+ uint32_t size;
+} vdpau_output_surface_t;
+
+
+typedef struct {
xine_grab_video_frame_t grab_frame;
vo_driver_t *vo_driver;
- VdpOutputSurface render_surface;
- int vdp_runtime_nr;
+ vdpau_output_surface_t render_surface;
int width, height;
uint32_t *rgba;
} vdpau_grab_video_frame_t;
@@ -331,13 +317,12 @@ typedef struct {
int extent_width;
int extent_height;
- int unscaled; /* true if it should be blended unscaled */
+ int unscaled; /* true if it should be blended unscaled */
+ int use_dirty_rect; /* true if update of dirty rect only is possible */
vo_overlay_t *ovl;
- VdpOutputSurface render_surface;
- uint32_t render_width;
- uint32_t render_height;
+ vdpau_output_surface_t render_surface;
} vdpau_overlay_t;
@@ -350,12 +335,14 @@ typedef struct {
int screen;
Drawable drawable;
pthread_mutex_t drawable_lock;
+ uint32_t display_width;
+ uint32_t display_height;
config_values_t *config;
int ovl_changed;
int num_ovls;
- int created_ovls;
+ int old_num_ovls;
vdpau_overlay_t overlays[XINE_VORAW_MAX_OVL];
uint32_t *ovl_pixmap;
int ovl_pixmap_size;
@@ -363,20 +350,18 @@ typedef struct {
VdpRect ovl_src_rect;
VdpRect ovl_dest_rect;
VdpRect ovl_video_dest_rect;
- VdpOutputSurface ovl_output_surface;
- uint32_t ovl_output_width;
- uint32_t ovl_output_height;
- int ovl_use_dirty_rect;
- int ovl_last_argb_x;
- int ovl_last_argb_y;
- int ovl_last_argb_width;
- int ovl_last_argb_height;
+ vdpau_output_surface_t ovl_main_render_surface;
VdpVideoSurface soft_surface;
uint32_t soft_surface_width;
uint32_t soft_surface_height;
int soft_surface_format;
+#define NOUTPUTSURFACEBUFFER 25
+ vdpau_output_surface_t output_surface_buffer[NOUTPUTSURFACEBUFFER];
+ int output_surface_buffer_size;
+ int num_big_output_surfaces_created;
+
#define NOUTPUTSURFACE 8
VdpOutputSurface output_surface[NOUTPUTSURFACE];
uint8_t current_output_surface;
@@ -449,19 +434,116 @@ typedef struct {
+static VdpStatus vdpau_get_output_surface (vdpau_driver_t *this, uint32_t width, uint32_t height, vdpau_output_surface_t *r)
+{
+ int i, full = 1;
+ vdpau_output_surface_t *smallest = NULL, *best = NULL;
+ vdpau_output_surface_t *l = &this->output_surface_buffer[0];
+ VdpStatus st = VDP_STATUS_OK;
+
+ for (i = this->output_surface_buffer_size; i; --i, ++l) {
+ if (l->surface == VDP_INVALID_HANDLE)
+ full = 0;
+ else if ((l->width >= width && l->height >= height) && (best == NULL || l->size < best->size))
+ best = l;
+ else if (smallest == NULL || l->size < smallest->size)
+ smallest = l;
+ }
+
+ if (best != NULL) {
+ *r = *best;
+ best->surface = VDP_INVALID_HANDLE;
+ } else if (full) {
+ *r = *smallest;
+ smallest->surface = VDP_INVALID_HANDLE;
+ } else
+ r->surface = VDP_INVALID_HANDLE;
+
+ if (r->surface != VDP_INVALID_HANDLE && (r->width < width || r->height < height)) {
+ lprintf("destroy output surface %d\n", (int)r->surface);
+ st = vdp_output_surface_destroy(r->surface);
+ if (st != VDP_STATUS_OK)
+ fprintf(stderr, "vdpau_get_output_surface: vdp_output_surface_destroy failed : %s\n", vdp_get_error_string(st));
+ r->surface = VDP_INVALID_HANDLE;
+ }
+
+ if (r->surface == VDP_INVALID_HANDLE) {
+ if (this->num_big_output_surfaces_created < this->output_surface_buffer_size) {
+ /* We create big output surfaces which should fit for many output buffer requests as long
+ * as the reuse buffer can hold them */
+ if (width < this->video_mixer_width)
+ width = this->video_mixer_width;
+ if (height < this->video_mixer_height)
+ height = this->video_mixer_height;
+
+ if (width < this->display_width)
+ width = this->display_width;
+ if (height < this->display_height)
+ height = this->display_height;
+
+ ++this->num_big_output_surfaces_created;
+ }
+
+ st = vdp_output_surface_create(vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, width, height, &r->surface);
+ if (st != VDP_STATUS_OK)
+ fprintf(stderr, "vdpau_get_output_surface: vdp_output_surface_create failed : %s\n", vdp_get_error_string(st));
+ r->width = width;
+ r->height = height;
+ r->size = width * height;
+ lprintf("create output surface %dx%d -> %d\n", (int)r->width, (int)r->height, (int)r->surface);
+ }
+
+ return st;
+}
+
+
+
+static void vdpau_free_output_surface (vdpau_driver_t *this, vdpau_output_surface_t *os)
+{
+ if (os->surface == VDP_INVALID_HANDLE)
+ return;
+
+ vdpau_output_surface_t *smallest = NULL;
+ vdpau_output_surface_t *l = &this->output_surface_buffer[0];
+ int i;
+ for (i = this->output_surface_buffer_size; i; --i, ++l) {
+ if (l->surface == VDP_INVALID_HANDLE) {
+ *l = *os;
+ os->surface = VDP_INVALID_HANDLE;
+ return;
+ } else if (smallest == NULL || l->size < smallest->size)
+ smallest = l;
+ }
+
+ VdpOutputSurface surface;
+ if (smallest && smallest->size < os->size) {
+ surface = smallest->surface;
+ *smallest = *os;
+ } else
+ surface = os->surface;
+
+ lprintf("destroy output surface %d\n", (int)surface);
+ VdpStatus st = vdp_output_surface_destroy (surface);
+ if (st != VDP_STATUS_OK)
+ fprintf(stderr, "vdpau_free_output_surface: vdp_output_surface_destroy failed : %s\n", vdp_get_error_string(st));
+
+ os->surface = VDP_INVALID_HANDLE;
+}
+
+
static void vdpau_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed)
{
vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
this->ovl_changed = changed;
if ( changed ) {
+ this->old_num_ovls = this->num_ovls;
this->num_ovls = 0;
lprintf("overlay begin\n");
}
}
-
static void vdpau_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *voovl)
{
vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
@@ -477,21 +559,34 @@ static void vdpau_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, v
return;
if (voovl->rle)
- lprintf("overlay[%d] rle %s%s %dx%d@%d,%d extend %dx%d hili rect %d,%d-%d,%d\n", i,
+ lprintf("overlay[%d] rle %s%s %dx%d@%d,%d extend %dx%d hili %d,%d-%d,%d video %dx%d@%d,%d\n", i,
voovl->unscaled ? " unscaled ": " scaled ",
(voovl->rgb_clut > 0 || voovl->hili_rgb_clut > 0) ? " rgb ": " ycbcr ",
voovl->width, voovl->height, voovl->x, voovl->y,
voovl->extent_width, voovl->extent_height,
voovl->hili_left, voovl->hili_top,
- voovl->hili_right, voovl->hili_bottom);
+ voovl->hili_right, voovl->hili_bottom,
+ voovl->video_window_width,voovl->video_window_height,
+ voovl->video_window_x,voovl->video_window_y);
if (voovl->argb_layer && voovl->argb_layer->buffer)
- lprintf("overlay[%d] argb %s %dx%d@%d,%d dirty rect %d,%d-%d,%d\n", i,
+ lprintf("overlay[%d] argb %s %dx%d@%d,%d dirty %d,%d-%d,%d video %dx%d@%d,%d\n", i,
voovl->unscaled ? " unscaled ": " scaled ",
voovl->width, voovl->height, voovl->x, voovl->y,
voovl->argb_layer->x1, voovl->argb_layer->y1,
- voovl->argb_layer->x2, voovl->argb_layer->y2);
+ voovl->argb_layer->x2, voovl->argb_layer->y2,
+ voovl->video_window_width,voovl->video_window_height,
+ voovl->video_window_x,voovl->video_window_y);
vdpau_overlay_t *ovl = &this->overlays[i];
+
+ if (i >= this->old_num_ovls ||
+ !ovl->use_dirty_rect ||
+ ovl->render_surface.surface == VDP_INVALID_HANDLE ||
+ voovl->rle ||
+ ovl->x != voovl->x || ovl->y != voovl->y ||
+ ovl->width != voovl->width || ovl->height != voovl->height)
+ ovl->use_dirty_rect = 0;
+
ovl->ovl = voovl;
ovl->x = voovl->x;
ovl->y = voovl->y;
@@ -516,46 +611,31 @@ static void vdpau_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen)
if (!this->ovl_changed)
return;
- int novls = this->num_ovls;
- if (!novls)
- this->ovl_use_dirty_rect = 0;
-
- VdpStatus st;
int i;
- for (i = 0; i < novls; ++i) {
+ for (i = 0; i < this->old_num_ovls; ++i) {
vdpau_overlay_t *ovl = &this->overlays[i];
- vo_overlay_t *voovl = ovl->ovl;
-
- if (ovl->render_surface != VDP_INVALID_HANDLE && (ovl->render_width < ovl->width || ovl->render_height < ovl->height) ) {
- lprintf("overlay[%d] destroy render surface\n", i);
- st = vdp_output_surface_destroy( ovl->render_surface );
- if ( st != VDP_STATUS_OK )
- fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_destroy failed : %s\n", vdp_get_error_string(st) );
- ovl->render_surface = VDP_INVALID_HANDLE;
+ if (!ovl->use_dirty_rect) {
+ lprintf("overlay[%d] free render surface %d\n", i, (int)ovl->render_surface.surface);
+ vdpau_free_output_surface(this, &ovl->render_surface);
}
+ }
+ if (this->ovl_main_render_surface.surface != VDP_INVALID_HANDLE) {
+ lprintf("overlay free main render surface %d\n", (int)this->ovl_main_render_surface.surface);
+ vdpau_free_output_surface(this, &this->ovl_main_render_surface);
+ }
- if (ovl->render_surface == VDP_INVALID_HANDLE ) {
- this->ovl_use_dirty_rect = 0;
+ for (i = 0; i < this->num_ovls; ++i) {
+ vdpau_overlay_t *ovl = &this->overlays[i];
+ vo_overlay_t *voovl = ovl->ovl;
- ovl->render_width = ovl->width;
- ovl->render_height = ovl->height;
- if (i == 0) {
- if (ovl->render_width < this->video_mixer_width)
- ovl->render_width = this->video_mixer_width;
- if (ovl->render_height < this->video_mixer_height)
- ovl->render_height = this->video_mixer_height;
- }
- lprintf("overlay[%d] create render surface %dx%d\n", i, ovl->render_width, ovl->render_height);
- st = vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, ovl->render_width, ovl->render_height, &ovl->render_surface );
- if ( st != VDP_STATUS_OK )
- fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_create failed : %s\n", vdp_get_error_string(st) );
+ if (!ovl->use_dirty_rect) {
+ vdpau_get_output_surface(this, ovl->width, ovl->height, &ovl->render_surface);
+ lprintf("overlay[%d] get render surface %dx%d -> %d\n", i, ovl->width, ovl->height, (int)ovl->render_surface.surface);
}
uint32_t *pixmap;
int is_argb = 1;
if (voovl->rle) {
- this->ovl_use_dirty_rect = 0;
-
if ((ovl->width * ovl->height) > this->ovl_pixmap_size) {
this->ovl_pixmap_size = ovl->width * ovl->height;
free(this->ovl_pixmap);
@@ -611,7 +691,7 @@ static void vdpau_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen)
}
VdpRect put_rect;
- if (this->ovl_use_dirty_rect && ovl->x == this->ovl_last_argb_x && ovl->y == this->ovl_last_argb_y && ovl->width == this->ovl_last_argb_width && ovl->height == this->ovl_last_argb_height) {
+ if (ovl->use_dirty_rect) {
put_rect.x0 = voovl->argb_layer->x1;
put_rect.y0 = voovl->argb_layer->y1;
put_rect.x1 = voovl->argb_layer->x2;
@@ -623,47 +703,27 @@ static void vdpau_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen)
put_rect.y1 = ovl->height;
}
+ VdpStatus st;
uint32_t pitch = ovl->width * sizeof(uint32_t);
if (is_argb) {
- lprintf("overlay[%d] put argb %d,%d:%d,%d\n", i, put_rect.x0, put_rect.y0, put_rect.x1, put_rect.y1);
- st = vdp_output_surface_put_bits(ovl->render_surface, &pixmap, &pitch, &put_rect);
+ lprintf("overlay[%d] put %s %d,%d:%d,%d\n", i, ovl->use_dirty_rect ? "dirty argb": "argb", put_rect.x0, put_rect.y0, put_rect.x1, put_rect.y1);
+ st = vdp_output_surface_put_bits(ovl->render_surface.surface, &pixmap, &pitch, &put_rect);
if ( st != VDP_STATUS_OK )
fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_put_bits_native failed : %s\n", vdp_get_error_string(st));
} else {
lprintf("overlay[%d] put ycbcr %d,%d:%d,%d\n", i, put_rect.x0, put_rect.y0, put_rect.x1, put_rect.y1);
- st = vdp_output_surface_put_bits_ycbcr(ovl->render_surface, VDP_YCBCR_FORMAT_V8U8Y8A8, &pixmap, &pitch, &put_rect, NULL);
+ st = vdp_output_surface_put_bits_ycbcr(ovl->render_surface.surface, VDP_YCBCR_FORMAT_V8U8Y8A8, &pixmap, &pitch, &put_rect, NULL);
if ( st != VDP_STATUS_OK )
fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_put_bits_ycbcr failed : %s\n", vdp_get_error_string(st));
}
- if (!voovl->rle) {
+ if (voovl->rle)
+ ovl->use_dirty_rect = 0;
+ else {
pthread_mutex_unlock(&voovl->argb_layer->mutex);
- if (novls == 1) {
- this->ovl_last_argb_x = ovl->x;
- this->ovl_last_argb_y = ovl->y;
- this->ovl_last_argb_width = ovl->width;
- this->ovl_last_argb_height = ovl->height;
- this->ovl_use_dirty_rect = 1;
- }
- }
- }
-
- if (novls > this->created_ovls)
- this->created_ovls = novls;
-
- i = this->created_ovls;
- while (i > 1 && i > novls) {
- vdpau_overlay_t *ovl = &this->overlays[--i];
-
- if (ovl->render_surface != VDP_INVALID_HANDLE) {
- lprintf("overlay[%d] destroy render surface\n", i);
- st = vdp_output_surface_destroy( ovl->render_surface );
- if ( st != VDP_STATUS_OK )
- fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_destroy failed : %s\n", vdp_get_error_string(st) );
- ovl->render_surface = VDP_INVALID_HANDLE;
+ ovl->use_dirty_rect = 1;
}
}
- this->created_ovls = i;
}
@@ -754,11 +814,11 @@ static void vdpau_process_overlays (vdpau_driver_t *this, vo_frame_t *frame)
if (novls == 1) {
this->ovl_src_rect.x1 = this->overlays[0].width;
this->ovl_src_rect.y1 = this->overlays[0].height;
- this->ovl_layer_surface = this->overlays[0].render_surface;
+ this->ovl_layer_surface = this->overlays[0].render_surface.surface;
} else {
this->ovl_src_rect.x1 = this->ovl_dest_rect.x1 - this->ovl_dest_rect.x0;
this->ovl_src_rect.y1 = this->ovl_dest_rect.y1 - this->ovl_dest_rect.y0;
- this->ovl_layer_surface = this->ovl_output_surface;
+ this->ovl_layer_surface = this->ovl_main_render_surface.surface;
}
lprintf("overlay output %dx%d -> %d,%d:%d,%d video window %d,%d:%d,%d\n",
@@ -773,37 +833,21 @@ static void vdpau_process_overlays (vdpau_driver_t *this, vo_frame_t *frame)
return;
}
- VdpStatus st;
-
- uint32_t output_width = this->ovl_src_rect.x1;
- uint32_t output_height = this->ovl_src_rect.y1;
- if (this->ovl_output_surface != VDP_INVALID_HANDLE && (this->ovl_output_width < output_width || this->ovl_output_height < output_height) ) {
- lprintf("overlay destroy output surface\n");
- st = vdp_output_surface_destroy( this->ovl_output_surface );
- if ( st != VDP_STATUS_OK )
- fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_destroy failed : %s\n", vdp_get_error_string(st) );
- this->ovl_output_surface = VDP_INVALID_HANDLE;
+ if (this->ovl_main_render_surface.surface != VDP_INVALID_HANDLE) {
+ lprintf("overlay free main render surface %d\n", (int)this->ovl_main_render_surface.surface);
+ vdpau_free_output_surface(this, &this->ovl_main_render_surface);
}
- if (this->ovl_output_surface == VDP_INVALID_HANDLE ) {
- if (output_width < this->video_mixer_width)
- output_width = this->video_mixer_width;
- if (output_height < this->video_mixer_height)
- output_height = this->video_mixer_height;
- lprintf("overlay create output surface %dx%d\n", output_width, output_height);
- st = vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, output_width, output_height, &this->ovl_output_surface );
- if ( st != VDP_STATUS_OK )
- fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_create failed : %s\n", vdp_get_error_string(st) );
+ vdpau_get_output_surface(this, this->ovl_src_rect.x1, this->ovl_src_rect.y1, &this->ovl_main_render_surface);
+ lprintf("overlay get main render surface %dx%d -> %d\n", this->ovl_src_rect.x1, this->ovl_src_rect.y1, (int)this->ovl_main_render_surface.surface);
- this->ovl_output_width = output_width;
- this->ovl_output_height = output_height;
- }
+ this->ovl_layer_surface = this->ovl_main_render_surface.surface;
- this->ovl_layer_surface = this->ovl_output_surface;
+ VdpStatus st;
if (novls > 1 && (this->ovl_dest_rect.x0 != ovl_rects[0].x0 || this->ovl_dest_rect.x1 != ovl_rects[0].x1 || this->ovl_dest_rect.y0 != ovl_rects[0].y0 || this->ovl_dest_rect.y1 != ovl_rects[0].y1)) {
- if (output_width > this->ovl_pixmap_size) {
- this->ovl_pixmap_size = output_width;
+ if (this->ovl_src_rect.x1 > this->ovl_pixmap_size) {
+ this->ovl_pixmap_size = this->ovl_src_rect.x1;
free(this->ovl_pixmap);
this->ovl_pixmap = calloc(this->ovl_pixmap_size, sizeof(uint32_t));
} else {
@@ -833,7 +877,7 @@ static void vdpau_process_overlays (vdpau_driver_t *this, vo_frame_t *frame)
lprintf("overlay[%d] render %dx%d -> %d,%d:%d,%d\n", i, src_rect.x1, src_rect.y1, render_rect.x0, render_rect.y0, render_rect.x1, render_rect.y1);
VdpOutputSurfaceRenderBlendState *bs = (i > 0) ? &blend: NULL;
- st = vdp_output_surface_render_output_surface(this->ovl_layer_surface, &render_rect, ovl->render_surface, &src_rect, 0, bs, 0 );
+ st = vdp_output_surface_render_output_surface(this->ovl_layer_surface, &render_rect, ovl->render_surface.surface, &src_rect, 0, bs, 0 );
if ( st != VDP_STATUS_OK )
fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_render_output_surface failed : %s\n", vdp_get_error_string(st));
}
@@ -1583,8 +1627,13 @@ static void vdpau_check_output_size( vo_driver_t *this_gen )
this->output_surface_width[this->current_output_surface] = this->sc.gui_width;
this->output_surface_height[this->current_output_surface] = this->sc.gui_height;
- vdp_output_surface_destroy( this->output_surface[this->current_output_surface] );
- vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, this->output_surface_width[this->current_output_surface], this->output_surface_height[this->current_output_surface], &this->output_surface[this->current_output_surface] );
+ VdpStatus st = vdp_output_surface_destroy( this->output_surface[this->current_output_surface] );
+ if (st != VDP_STATUS_OK)
+ fprintf(stderr, "vo_vdpau: Can't destroy output surface: %s\n", vdp_get_error_string (st));
+
+ st = vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, this->output_surface_width[this->current_output_surface], this->output_surface_height[this->current_output_surface], &this->output_surface[this->current_output_surface] );
+ if (st != VDP_STATUS_OK)
+ fprintf(stderr, "vo_vdpau: Can't create output surface: %s\n", vdp_get_error_string (st));
}
}
@@ -1601,8 +1650,8 @@ static void vdpau_grab_current_output_surface (vdpau_driver_t *this, int64_t vpt
frame->grab_frame.vpts = -1;
VdpOutputSurface grab_surface = this->output_surface[this->current_output_surface];
- int width = this->output_surface_width[this->current_output_surface];
- int height = this->output_surface_height[this->current_output_surface];
+ int width = this->sc.gui_width;
+ int height = this->sc.gui_height;
/* take cropping parameters into account */
width = width - frame->grab_frame.crop_left - frame->grab_frame.crop_right;
@@ -1618,26 +1667,12 @@ static void vdpau_grab_current_output_surface (vdpau_driver_t *this, int64_t vpt
if (frame->grab_frame.height <= 0)
frame->grab_frame.height = height;
- if (frame->vdp_runtime_nr != this->vdp_runtime_nr)
- frame->render_surface = VDP_INVALID_HANDLE;
-
if (frame->grab_frame.width != frame->width || frame->grab_frame.height != frame->height) {
free(frame->rgba);
free(frame->grab_frame.img);
frame->rgba = NULL;
frame->grab_frame.img = NULL;
- if (frame->render_surface != VDP_INVALID_HANDLE) {
- st = vdp_output_surface_destroy(frame->render_surface);
- frame->render_surface = VDP_INVALID_HANDLE;
- if (st != VDP_STATUS_OK) {
- fprintf(stderr, "vo_vdpau: Can't destroy grab render output surface: %s\n", vdp_get_error_string (st));
- pthread_cond_broadcast(&this->grab_cond);
- pthread_mutex_unlock(&this->grab_lock);
- return;
- }
- }
-
frame->width = frame->grab_frame.width;
frame->height = frame->grab_frame.height;
}
@@ -1650,6 +1685,7 @@ static void vdpau_grab_current_output_surface (vdpau_driver_t *this, int64_t vpt
return;
}
}
+
if (frame->grab_frame.img == NULL) {
frame->grab_frame.img = (uint8_t *) calloc(frame->width * frame->height, 3);
if (frame->grab_frame.img == NULL) {
@@ -1661,30 +1697,22 @@ static void vdpau_grab_current_output_surface (vdpau_driver_t *this, int64_t vpt
uint32_t pitches = frame->width * sizeof(uint32_t);
VdpRect src_rect = { frame->grab_frame.crop_left, frame->grab_frame.crop_top, width+frame->grab_frame.crop_left, height+frame->grab_frame.crop_top };
-
if (frame->width != width || frame->height != height) {
- st = VDP_STATUS_OK;
- if (frame->render_surface == VDP_INVALID_HANDLE) {
- frame->vdp_runtime_nr = this->vdp_runtime_nr;
- st = vdp_output_surface_create(vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, frame->width, frame->height, &frame->render_surface);
- }
+ st = vdpau_get_output_surface(this, frame->width, frame->height, &frame->render_surface);
if (st == VDP_STATUS_OK) {
- st = vdp_output_surface_render_output_surface(frame->render_surface, NULL, grab_surface, &src_rect, NULL, NULL, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0);
+ lprintf("grab got render output surface %dx%d -> %d\n", frame->width, frame->height, (int)frame->render_surface.surface);
+
+ VdpRect dst_rect = { 0, 0, frame->width, frame->height };
+ st = vdp_output_surface_render_output_surface(frame->render_surface.surface, &dst_rect, grab_surface, &src_rect, NULL, NULL, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0);
if (st == VDP_STATUS_OK) {
- st = vdp_output_surface_get_bits(frame->render_surface, NULL, &frame->rgba, &pitches);
- if (st == VDP_STATUS_OK) {
- if (!(frame->grab_frame.flags & XINE_GRAB_VIDEO_FRAME_FLAGS_CONTINUOUS)) {
- st = vdp_output_surface_destroy(frame->render_surface);
- if (st != VDP_STATUS_OK)
- fprintf(stderr, "vo_vdpau: Can't destroy grab render output surface: %s\n", vdp_get_error_string (st));
- frame->render_surface = VDP_INVALID_HANDLE;
- }
- } else
+ st = vdp_output_surface_get_bits(frame->render_surface.surface, &dst_rect, &frame->rgba, &pitches);
+ if (st != VDP_STATUS_OK)
fprintf(stderr, "vo_vdpau: Can't get output surface bits for raw frame grabbing: %s\n", vdp_get_error_string (st));
} else
fprintf(stderr, "vo_vdpau: Can't render output surface for raw frame grabbing: %s\n", vdp_get_error_string (st));
- } else
- fprintf(stderr, "vo_vdpau: Can't create render output surface for raw frame grabbing: %s\n", vdp_get_error_string (st));
+
+ vdpau_free_output_surface(this, &frame->render_surface);
+ }
} else {
st = vdp_output_surface_get_bits(grab_surface, &src_rect, &frame->rgba, &pitches);
if (st != VDP_STATUS_OK)
@@ -1891,9 +1919,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
if ( this->init_queue>1 )
vdp_queue_block( vdp_queue, this->output_surface[this->current_output_surface], &last_time );
-#ifdef LOCKDISPLAY
- XLockDisplay( this->display );
-#endif
+ DO_LOCKDISPLAY
vdpau_check_output_size( this_gen );
@@ -1914,7 +1940,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
vdpau_grab_current_output_surface( this, frame->vo_frame.vpts );
vdp_queue_get_time( vdp_queue, &current_time );
- vdp_queue_display( vdp_queue, this->output_surface[this->current_output_surface], 0, 0, 0 ); /* display _now_ */
+ vdp_queue_display( vdp_queue, this->output_surface[this->current_output_surface], this->sc.gui_width, this->sc.gui_height, 0 ); /* display _now_ */
vdpau_shift_queue( this_gen );
int dm;
@@ -1925,13 +1951,9 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
if ( (dm != DEINT_HALF_TEMPORAL) && (dm != DEINT_HALF_TEMPORAL_SPATIAL) && frame->vo_frame.future_frame ) { /* process second field */
if ( this->init_queue >= this->queue_length ) {
-#ifdef LOCKDISPLAY
- XUnlockDisplay(this->display);
-#endif
+ DO_UNLOCKDISPLAY
vdp_queue_block( vdp_queue, this->output_surface[this->current_output_surface], &last_time );
-#ifdef LOCKDISPLAY
- XLockDisplay(this->display);
-#endif
+ DO_LOCKDISPLAY
}
vdpau_check_output_size( this_gen );
@@ -1951,7 +1973,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
if ( stream_speed > 0 )
current_time += frame->vo_frame.duration * 1000000ull * XINE_FINE_SPEED_NORMAL / (180 * stream_speed);
- vdp_queue_display( vdp_queue, this->output_surface[this->current_output_surface], 0, 0, current_time );
+ vdp_queue_display( vdp_queue, this->output_surface[this->current_output_surface], this->sc.gui_width, this->sc.gui_height, current_time );
vdpau_shift_queue( this_gen );
}
}
@@ -1964,13 +1986,11 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
fprintf(stderr, "vo_vdpau: vdp_video_mixer_render error : %s\n", vdp_get_error_string( st ) );
vdpau_grab_current_output_surface( this, frame->vo_frame.vpts );
- vdp_queue_display( vdp_queue, this->output_surface[this->current_output_surface], 0, 0, 0 );
+ vdp_queue_display( vdp_queue, this->output_surface[this->current_output_surface], this->sc.gui_width, this->sc.gui_height, 0 );
vdpau_shift_queue( this_gen );
}
-#ifdef LOCKDISPLAY
- XUnlockDisplay( this->display );
-#endif
+ DO_UNLOCKDISPLAY
if ( stream_speed )
vdpau_backup_frame( this_gen, frame_gen );
@@ -2099,19 +2119,13 @@ static void vdpau_get_property_min_max (vo_driver_t *this_gen, int property, int
static void vdpau_dispose_grab_video_frame(xine_grab_video_frame_t *frame_gen)
{
vdpau_grab_video_frame_t *frame = (vdpau_grab_video_frame_t *) frame_gen;
- vdpau_driver_t *this = (vdpau_driver_t *) frame->vo_driver;
free(frame->grab_frame.img);
free(frame->rgba);
- if (frame->render_surface != VDP_INVALID_HANDLE && frame->vdp_runtime_nr == this->vdp_runtime_nr) {
- VdpStatus st;
- st = vdp_output_surface_destroy(frame->render_surface);
- if (st != VDP_STATUS_OK)
- fprintf(stderr, "vo_vdpau: Can't destroy grab render output surface: %s\n", vdp_get_error_string (st) );
- }
free(frame);
}
+
/*
* grab next displayed output surface.
* Note: This feature only supports grabbing of next displayed frame (implicit VO_GRAB_FRAME_FLAGS_WAIT_NEXT)
@@ -2182,7 +2196,7 @@ static xine_grab_video_frame_t * vdpau_new_grab_video_frame(vo_driver_t *this)
frame->grab_frame.vpts = -1;
frame->grab_frame.timeout = XINE_GRAB_VIDEO_FRAME_DEFAULT_TIMEOUT;
frame->vo_driver = this;
- frame->render_surface = VDP_INVALID_HANDLE;
+ frame->render_surface.surface = VDP_INVALID_HANDLE;
}
return (xine_grab_video_frame_t *) frame;
@@ -2202,18 +2216,14 @@ static int vdpau_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *
case XINE_GUI_SEND_EXPOSE_EVENT: {
if ( this->init_queue ) {
pthread_mutex_lock(&this->drawable_lock); /* wait for other thread which is currently displaying */
-#ifdef LOCKDISPLAY
- XLockDisplay( this->display );
-#endif
+ DO_LOCKDISPLAY
int previous;
if ( this->current_output_surface )
previous = this->current_output_surface - 1;
else
previous = this->queue_length - 1;
vdp_queue_display( vdp_queue, this->output_surface[previous], 0, 0, 0 );
-#ifdef LOCKDISPLAY
- XUnlockDisplay( this->display );
-#endif
+ DO_UNLOCKDISPLAY
pthread_mutex_unlock(&this->drawable_lock);
}
break;
@@ -2222,34 +2232,26 @@ static int vdpau_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *
case XINE_GUI_SEND_DRAWABLE_CHANGED: {
VdpStatus st;
pthread_mutex_lock(&this->drawable_lock); /* wait for other thread which is currently displaying */
-#ifdef LOCKDISPLAY
- XLockDisplay( this->display );
-#endif
+ DO_LOCKDISPLAY
this->drawable = (Drawable) data;
vdp_queue_destroy( vdp_queue );
vdp_queue_target_destroy( vdp_queue_target );
st = vdp_queue_target_create_x11( vdp_device, this->drawable, &vdp_queue_target );
if ( st != VDP_STATUS_OK ) {
fprintf(stderr, "vo_vdpau: FATAL !! Can't recreate presentation queue target after drawable change !!\n" );
-#ifdef LOCKDISPLAY
- XUnlockDisplay( this->display );
-#endif
+ DO_UNLOCKDISPLAY
pthread_mutex_unlock(&this->drawable_lock);
break;
}
st = vdp_queue_create( vdp_device, vdp_queue_target, &vdp_queue );
if ( st != VDP_STATUS_OK ) {
fprintf(stderr, "vo_vdpau: FATAL !! Can't recreate presentation queue after drawable change !!\n" );
-#ifdef LOCKDISPLAY
- XUnlockDisplay( this->display );
-#endif
+ DO_UNLOCKDISPLAY
pthread_mutex_unlock(&this->drawable_lock);
break;
}
vdp_queue_set_background_color( vdp_queue, &this->back_color );
-#ifdef LOCKDISPLAY
- XUnlockDisplay( this->display );
-#endif
+ DO_UNLOCKDISPLAY
pthread_mutex_unlock(&this->drawable_lock);
this->sc.force_redraw = 1;
break;
@@ -2304,17 +2306,21 @@ static void vdpau_dispose (vo_driver_t *this_gen)
vdp_video_surface_destroy( this->soft_surface );
if ( vdp_output_surface_destroy ) {
- if (this->ovl_output_surface != VDP_INVALID_HANDLE)
- vdp_output_surface_destroy( this->ovl_output_surface );
- for (i = 0; i < this->created_ovls; ++i) {
+ if (this->ovl_main_render_surface.surface != VDP_INVALID_HANDLE)
+ vdp_output_surface_destroy( this->ovl_main_render_surface.surface );
+ for (i = 0; i < this->num_ovls; ++i) {
vdpau_overlay_t *ovl = &this->overlays[i];
- if (ovl->render_surface != VDP_INVALID_HANDLE)
- vdp_output_surface_destroy( ovl->render_surface );
+ if (ovl->render_surface.surface != VDP_INVALID_HANDLE)
+ vdp_output_surface_destroy( ovl->render_surface.surface );
}
for ( i=0; i<this->queue_length; ++i ) {
- if ( this->output_surface[i]!=VDP_INVALID_HANDLE )
+ if ( this->output_surface[i] != VDP_INVALID_HANDLE )
vdp_output_surface_destroy( this->output_surface[i] );
}
+ for ( i=0; i<this->output_surface_buffer_size; ++i ) {
+ if ( this->output_surface_buffer[i].surface != VDP_INVALID_HANDLE )
+ vdp_output_surface_destroy( this->output_surface_buffer[i].surface );
+ }
}
for ( i=0; i<NUM_FRAMES_BACK; i++ )
@@ -2333,6 +2339,18 @@ static void vdpau_dispose (vo_driver_t *this_gen)
+static void vdpau_update_display_dimension (vdpau_driver_t *this)
+{
+ XLockDisplay (this->display);
+
+ this->display_width = DisplayWidth(this->display, this->screen);
+ this->display_height = DisplayHeight(this->display, this->screen);
+
+ XUnlockDisplay(this->display);
+}
+
+
+
static int vdpau_reinit_error( VdpStatus st, const char *msg )
{
if ( st != VDP_STATUS_OK ) {
@@ -2349,9 +2367,7 @@ static void vdpau_reinit( vo_driver_t *this_gen )
fprintf(stderr,"vo_vdpau: VDPAU was pre-empted. Reinit.\n");
vdpau_driver_t *this = (vdpau_driver_t *)this_gen;
-#ifdef LOCKDISPLAY
- XLockDisplay(guarded_display);
-#endif
+ DO_LOCKDISPLAY
vdpau_release_back_frames(this_gen);
VdpStatus st = vdp_device_create_x11( this->display, this->screen, &vdp_device, &vdp_get_proc_address );
@@ -2362,25 +2378,18 @@ static void vdpau_reinit( vo_driver_t *this_gen )
fprintf(stderr, "No vdpau implementation.\n" );
else
fprintf(stderr, "unsupported GPU?\n" );
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return;
}
st = vdp_queue_target_create_x11( vdp_device, this->drawable, &vdp_queue_target );
if ( vdpau_reinit_error( st, "Can't create presentation queue target !!" ) ) {
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
-
+ DO_UNLOCKDISPLAY
return;
}
st = vdp_queue_create( vdp_device, vdp_queue_target, &vdp_queue );
if ( vdpau_reinit_error( st, "Can't create presentation queue !!" ) ) {
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return;
}
vdp_queue_set_background_color( vdp_queue, &this->back_color );
@@ -2389,35 +2398,37 @@ static void vdpau_reinit( vo_driver_t *this_gen )
VdpChromaType chroma = VDP_CHROMA_TYPE_420;
st = orig_vdp_video_surface_create( vdp_device, chroma, this->soft_surface_width, this->soft_surface_height, &this->soft_surface );
if ( vdpau_reinit_error( st, "Can't create video surface !!" ) ) {
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return;
}
+ vdpau_update_display_dimension(this);
this->current_output_surface = 0;
this->init_queue = 0;
int i;
for ( i=0; i<this->queue_length; ++i ) {
+ this->output_surface_width[i] = this->display_width;
+ this->output_surface_height[i] = this->display_height;
st = vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, this->output_surface_width[i], this->output_surface_height[i], &this->output_surface[i] );
if ( vdpau_reinit_error( st, "Can't create output surface !!" ) ) {
int j;
for ( j=0; j<i; ++j )
vdp_output_surface_destroy( this->output_surface[j] );
vdp_video_surface_destroy( this->soft_surface );
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return;
}
}
+ this->num_big_output_surfaces_created = 0;
+ for (i = 0; i < this->output_surface_buffer_size; ++i)
+ this->output_surface_buffer[i].surface = VDP_INVALID_HANDLE;
+
this->ovl_layer_surface = VDP_INVALID_HANDLE;
- this->ovl_output_surface = VDP_INVALID_HANDLE;
- for (i = 0; i < this->created_ovls; ++i)
- this->overlays[i].render_surface = VDP_INVALID_HANDLE;
+ this->ovl_main_render_surface.surface = VDP_INVALID_HANDLE;
+ for (i = 0; i < this->num_ovls; ++i)
+ this->overlays[i].render_surface.surface = VDP_INVALID_HANDLE;
this->num_ovls = 0;
- this->created_ovls = 0;
this->ovl_changed = 1;
VdpVideoMixerFeature features[15];
@@ -2456,9 +2467,7 @@ static void vdpau_reinit( vo_driver_t *this_gen )
orig_vdp_video_surface_destroy( this->soft_surface );
for ( i=0; i<this->queue_length; ++i )
vdp_output_surface_destroy( this->output_surface[i] );
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
return;
}
this->video_mixer_chroma = chroma;
@@ -2475,9 +2484,7 @@ static void vdpau_reinit( vo_driver_t *this_gen )
this->vdp_runtime_nr++;
this->reinit_needed = 0;
-#ifdef LOCKDISPLAY
- XUnlockDisplay(guarded_display);
-#endif
+ DO_UNLOCKDISPLAY
fprintf(stderr,"vo_vdpau: Reinit done.\n");
}
@@ -2520,7 +2527,10 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
if (!this)
return NULL;
+#ifdef LOCKDISPLAY
guarded_display = visual->display;
+#endif
+
this->display = visual->display;
this->screen = visual->screen;
this->drawable = visual->d;
@@ -2576,20 +2586,14 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
this->ovl_changed = 0;
this->num_ovls = 0;
- this->created_ovls = 0;
+ this->old_num_ovls = 0;
this->ovl_layer_surface = VDP_INVALID_HANDLE;
- this->ovl_output_width = 0;
- this->ovl_output_height = 0;
- this->ovl_output_surface = VDP_INVALID_HANDLE;
+ this->ovl_main_render_surface.surface = VDP_INVALID_HANDLE;
this->ovl_pixmap = NULL;
this->ovl_pixmap_size = 0;
- this->ovl_use_dirty_rect = 0;
this->ovl_src_rect.x0 = 0;
this->ovl_src_rect.y0 = 0;
- for (i = 0; i < XINE_VORAW_MAX_OVL; ++i)
- this->overlays[i].render_surface = VDP_INVALID_HANDLE;
-
VdpStatus st = vdp_device_create_x11( visual->display, visual->screen, &vdp_device, &vdp_get_proc_address );
if ( st != VDP_STATUS_OK ) {
fprintf(stderr, "vo_vdpau: Can't create vdp device : " );
@@ -2832,6 +2836,22 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
if ( vdpau_init_error( st, "Can't create video surface !!", &this->vo_driver, 1 ) )
return NULL;
+ this->output_surface_buffer_size = config->register_num (config, "video.output.vdpau_output_surface_buffer_size", 10, /* default */
+ _("maximum number of output surfaces buffered for reuse"),
+ _("The maximum number of video output surfaces buffered for reuse"),
+ 20, NULL, this);
+ if (this->output_surface_buffer_size < 2)
+ this->output_surface_buffer_size = 2;
+ if (this->output_surface_buffer_size > NOUTPUTSURFACEBUFFER)
+ this->output_surface_buffer_size = NOUTPUTSURFACEBUFFER;
+ fprintf(stderr, "vo_vdpau: hold a maximum of %d video output surfaces for reuse\n", this->output_surface_buffer_size);
+
+ this->num_big_output_surfaces_created = 0;
+ for (i = 0; i < this->output_surface_buffer_size; ++i)
+ this->output_surface_buffer[i].surface = VDP_INVALID_HANDLE;
+
+ vdpau_update_display_dimension(this);
+
this->queue_length = config->register_num (config, "video.output.vdpau_display_queue_length", 3, /* default */
_("default length of display queue"),
_("The default number of video output surfaces to create for the display queue"),
@@ -2840,16 +2860,13 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
this->queue_length = 2;
if (this->queue_length > NOUTPUTSURFACE)
this->queue_length = NOUTPUTSURFACE;
- fprintf(stderr, "vo_vdpau: using %d output surfaces for display queue\n", this->queue_length);
+ fprintf(stderr, "vo_vdpau: using %d output surfaces of size %dx%d for display queue\n", this->queue_length, this->display_width, this->display_height);
- for ( i=0; i<this->queue_length; ++i ) {
- this->output_surface_width[i] = 320;
- this->output_surface_height[i] = 240;
- }
this->current_output_surface = 0;
this->init_queue = 0;
-
for ( i=0; i<this->queue_length; ++i ) {
+ this->output_surface_width[i] = this->display_width;
+ this->output_surface_height[i] = this->display_height;
st = vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, this->output_surface_width[i], this->output_surface_height[i], &this->output_surface[i] );
if ( vdpau_init_error( st, "Can't create output surface !!", &this->vo_driver, 1 ) ) {
int j;