summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/xine.h15
-rw-r--r--src/video_out/Makefile.am2
-rw-r--r--src/video_out/video_out_vdpau.c1010
3 files changed, 513 insertions, 514 deletions
diff --git a/include/xine.h b/include/xine.h
index c04e270c2..0fa01dd4e 100644
--- a/include/xine.h
+++ b/include/xine.h
@@ -2196,7 +2196,7 @@ void xine_event_send (xine_stream_t *stream, const xine_event_t *event) XINE_PRO
#define XINE_OSD_CAP_FREETYPE2 0x0001 /* freetype2 support compiled in */
#define XINE_OSD_CAP_UNSCALED 0x0002 /* unscaled overlays supp. by vo drv */
#define XINE_OSD_CAP_CUSTOM_EXTENT 0x0004 /* hardware scaled to match video output window */
-#define XINE_OSD_CAP_ARGB_LAYER 0x0008 /* supports separate true color layer */
+#define XINE_OSD_CAP_ARGB_LAYER 0x0008 /* supports ARGB true color pixmaps */
#define XINE_OSD_CAP_VIDEO_WINDOW 0x0010 /* can scale video to an area within osd extent */
typedef struct xine_osd_s xine_osd_t;
@@ -2264,13 +2264,12 @@ void xine_osd_set_palette (xine_osd_t *self,
const uint8_t *const trans ) XINE_PROTECTED;
/*
- * set an argb buffer to be blended into video
- * the buffer must exactly match the osd dimensions
- * and stay valid while the osd is on screen. pass
- * a NULL pointer to safely remove the buffer from
- * the osd layer. only the dirty area will be
- * updated on screen. for convinience the whole
- * osd object will be considered dirty when setting
+ * Set an ARGB buffer to be blended into video.
+ * The buffer must stay valid while the OSD is on screen.
+ * Pass a NULL pointer to safely remove the buffer from
+ * the OSD layer. Only the dirty area will be
+ * updated on screen. For convenience the whole
+ * OSD object will be considered dirty when setting
* a different buffer pointer.
* see also XINE_OSD_CAP_ARGB_LAYER
*/
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index e93d97bca..9ae05d6f7 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -121,7 +121,7 @@ xineplug_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \
xineplug_vo_out_none.la
xineplug_vo_out_vdpau_la_SOURCES = video_out_vdpau.c
-xineplug_vo_out_vdpau_la_LIBADD = $(YUV_LIBS) $(PTHREAD_LIBS) $(X_LIBS) $(LTLIBINTL) $(VDPAU_LIBS) -lm
+xineplug_vo_out_vdpau_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(AVUTIL_LIBS) $(PTHREAD_LIBS) $(X_LIBS) $(LTLIBINTL) $(VDPAU_LIBS) -lm
xineplug_vo_out_vdpau_la_CFLAGS = $(VISIBILITY_FLAG) $(MLIB_CFLAGS) $(X_CFLAGS) $(VDPAU_CFLAGS) $(AVUTIL_CFLAGS) -fno-strict-aliasing
xineplug_vo_out_xcbshm_la_SOURCES = video_out_xcbshm.c $(XCBOSD)
diff --git a/src/video_out/video_out_vdpau.c b/src/video_out/video_out_vdpau.c
index 69dcbae9e..7d92302c2 100644
--- a/src/video_out/video_out_vdpau.c
+++ b/src/video_out/video_out_vdpau.c
@@ -47,7 +47,6 @@
#include <xine/vo_scale.h>
#include <xine/xine_internal.h>
#include <xine/xineutils.h>
-#include "yuv2rgb.h"
#include <vdpau/vdpau_x11.h>
#include "accel_vdpau.h"
@@ -124,6 +123,7 @@ VdpGetApiVersion *vdp_get_api_version;
VdpGetInformationString *vdp_get_information_string;
VdpGetErrorString *vdp_get_error_string;
+VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities;
VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_get_put_bits_ycbcr_capabilities;
VdpVideoSurfaceCreate *vdp_video_surface_create;
VdpVideoSurfaceDestroy *vdp_video_surface_destroy;
@@ -131,12 +131,15 @@ VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_putbits_ycbcr;
VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_getbits_ycbcr;
VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters;
+VdpOutputSurfaceQueryCapabilities *vdp_output_surface_query_capabilities;
+VdpOutputSurfaceQueryGetPutBitsNativeCapabilities *vdp_output_surface_query_get_put_bits_native_capabilities;
+VdpOutputSurfaceQueryPutBitsYCbCrCapabilities *vdp_output_surface_query_put_bits_ycbcr_capabilities;
VdpOutputSurfaceCreate *vdp_output_surface_create;
VdpOutputSurfaceDestroy *vdp_output_surface_destroy;
-VdpOutputSurfaceRenderBitmapSurface *vdp_output_surface_render_bitmap_surface;
VdpOutputSurfaceRenderOutputSurface *vdp_output_surface_render_output_surface;
-VdpOutputSurfacePutBitsNative *vdp_output_surface_put_bits;
VdpOutputSurfaceGetBitsNative *vdp_output_surface_get_bits;
+VdpOutputSurfacePutBitsNative *vdp_output_surface_put_bits;
+VdpOutputSurfacePutBitsYCbCr *vdp_output_surface_put_bits_ycbcr;
VdpVideoMixerCreate *vdp_video_mixer_create;
VdpVideoMixerDestroy *vdp_video_mixer_destroy;
@@ -162,10 +165,6 @@ VdpPresentationQueueSetBackgroundColor *vdp_queue_set_background_color;
VdpPresentationQueueGetTime *vdp_queue_get_time;
VdpPresentationQueueQuerySurfaceStatus *vdp_queue_query_surface_status;
-VdpBitmapSurfacePutBitsNative *vdp_bitmap_put_bits;
-VdpBitmapSurfaceCreate *vdp_bitmap_create;
-VdpBitmapSurfaceDestroy *vdp_bitmap_destroy;
-
VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities;
VdpDecoderCreate *vdp_decoder_create;
VdpDecoderDestroy *vdp_decoder_destroy;
@@ -304,26 +303,6 @@ typedef struct {
typedef struct {
- VdpBitmapSurface ovl_bitmap;
- uint32_t bitmap_width, bitmap_height;
- int ovl_w, ovl_h; /* overlay's width and height */
- int ovl_x, ovl_y; /* overlay's top-left display position */
- int unscaled;
- int expected_overlay_width; /*if >0 scale to video width*/
- int expected_overlay_height; /* if >0 scale to video height */
-} vdpau_overlay_t;
-
-
-typedef struct {
- int x;
- int y;
- int w;
- int h;
-}
-argb_ovl_data_t;
-
-
-typedef struct {
vo_frame_t vo_frame;
int width, height, format, flags;
@@ -337,6 +316,33 @@ typedef struct {
typedef struct {
+ int x; /* x start of subpicture area */
+ int y; /* y start of subpicture area */
+ int width; /* width of subpicture area */
+ int height; /* height of subpicture area */
+
+ /* area within osd extent to scale video to */
+ int video_window_x;
+ int video_window_y;
+ int video_window_width;
+ int video_window_height;
+
+ /* extent of reference coordinate system */
+ int extent_width;
+ int extent_height;
+
+ int unscaled; /* true if it should be blended unscaled */
+
+ vo_overlay_t *ovl;
+
+ VdpOutputSurface render_surface;
+ uint32_t render_width;
+ uint32_t render_height;
+} vdpau_overlay_t;
+
+
+typedef struct {
+
vo_driver_t vo_driver;
vo_scale_t sc;
@@ -347,33 +353,24 @@ typedef struct {
config_values_t *config;
- int ovl_changed;
+ int ovl_changed;
+ int num_ovls;
+ int created_ovls;
vdpau_overlay_t overlays[XINE_VORAW_MAX_OVL];
- yuv2rgb_factory_t *yuv2rgb_factory;
- yuv2rgb_t *ovl_yuv2rgb;
- VdpOutputSurface overlay_output;
- uint32_t overlay_output_width;
- uint32_t overlay_output_height;
- int has_overlay;
-
- VdpOutputSurface overlay_unscaled;
- uint32_t overlay_unscaled_width;
- uint32_t overlay_unscaled_height;
- int has_unscaled;
-
- VdpOutputSurface argb_overlay;
- uint32_t argb_overlay_width;
- uint32_t argb_overlay_height;
- int has_argb_overlay;
- int argb_ovl_count;
- vo_overlay_t *argb_ovl[XINE_VORAW_MAX_OVL];
- int argb_ovl_data_count;
- argb_ovl_data_t argb_ovl_data[XINE_VORAW_MAX_OVL];
-
- int32_t video_window_x;
- int32_t video_window_y;
- int32_t video_window_width;
- int32_t video_window_height;
+ uint32_t *ovl_pixmap;
+ int ovl_pixmap_size;
+ VdpOutputSurface ovl_layer_surface;
+ 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;
VdpVideoSurface soft_surface;
uint32_t soft_surface_width;
@@ -452,408 +449,395 @@ typedef struct {
-static void vdpau_overlay_clut_yuv2rgb(vdpau_driver_t *this, vo_overlay_t *overlay, vdpau_frame_t *frame)
+static void vdpau_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed)
{
- int i;
- clut_t* clut = (clut_t*) overlay->color;
+ vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
- if (!overlay->rgb_clut) {
- for ( i=0; i<sizeof(overlay->color)/sizeof(overlay->color[0]); i++ ) {
- *((uint32_t *)&clut[i]) = this->ovl_yuv2rgb->yuv2rgb_single_pixel_fun(this->ovl_yuv2rgb, clut[i].y, clut[i].cb, clut[i].cr);
- }
- overlay->rgb_clut++;
- }
- if (!overlay->hili_rgb_clut) {
- clut = (clut_t*) overlay->hili_color;
- for ( i=0; i<sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
- *((uint32_t *)&clut[i]) = this->ovl_yuv2rgb->yuv2rgb_single_pixel_fun(this->ovl_yuv2rgb, clut[i].y, clut[i].cb, clut[i].cr);
- }
- overlay->hili_rgb_clut++;
+ this->ovl_changed = changed;
+ if ( changed ) {
+ this->num_ovls = 0;
+ lprintf("overlay begin\n");
}
}
-static void vdpau_process_argb_ovls(vdpau_driver_t *this_gen, vo_frame_t *frame_gen)
+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;
- int i, k;
-
- vo_overlay_t *ovl[XINE_VORAW_MAX_OVL];
- argb_ovl_data_t ovl_data[XINE_VORAW_MAX_OVL];
- int ovl_data_count = 0;
-
- int total_extent_width = 0, total_extent_height = 0;
- this->video_window_x = 0;
- this->video_window_y = 0;
- this->video_window_width = 0;
- this->video_window_height = 0;
-
- /* lock layers while processing and determine extent */
- for (i = 0; i < this->argb_ovl_count; i++) {
- pthread_mutex_lock(&this->argb_ovl[i]->argb_layer->mutex);
-
- if (this->argb_ovl[i]->argb_layer->buffer != NULL) {
- int extent_width = this->argb_ovl[i]->extent_width;
- int extent_height = this->argb_ovl[i]->extent_height;
- if (extent_width <= 0 || extent_height <= 0) {
- extent_width = frame_gen->width;
- extent_height = frame_gen->height;
- }
- if (extent_width > 0 && extent_height > 0) {
- if (total_extent_width < extent_width)
- total_extent_width = extent_width;
- if (total_extent_height < extent_height)
- total_extent_height = extent_height;
- ovl_data[ovl_data_count].x = this->argb_ovl[i]->x;
- ovl_data[ovl_data_count].y = this->argb_ovl[i]->y;
- ovl_data[ovl_data_count].w = this->argb_ovl[i]->width;
- ovl_data[ovl_data_count].h = this->argb_ovl[i]->height;
- ovl[ovl_data_count++] = this->argb_ovl[i];
- }
- if (this->argb_ovl[i]->video_window_width > 0
- && this->argb_ovl[i]->video_window_height > 0) {
- /* last one wins */
- this->video_window_x = this->argb_ovl[i]->video_window_x;
- this->video_window_y = this->argb_ovl[i]->video_window_y;
- this->video_window_width = this->argb_ovl[i]->video_window_width;
- this->video_window_height = this->argb_ovl[i]->video_window_height;
- }
- }
- }
- /* adjust surface */
- if (total_extent_width > 0 && total_extent_height > 0) {
- if (this->argb_overlay_width != total_extent_width || this->argb_overlay_height != total_extent_height || this->argb_overlay == VDP_INVALID_HANDLE) {
- if (this->argb_overlay != VDP_INVALID_HANDLE)
- vdp_output_surface_destroy(this->argb_overlay);
+ if (!this->ovl_changed)
+ return;
- VdpStatus st = vdp_output_surface_create(vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, total_extent_width, total_extent_height, &this->argb_overlay);
- if (st != VDP_STATUS_OK)
- fprintf(stderr, "vdpau_process_argb_ovl: vdp_output_surface_create failed : %s\n", vdp_get_error_string(st));
-
- this->argb_overlay_width = total_extent_width;
- this->argb_overlay_height = total_extent_height;
-
- /* change argb_ovl_data to wipe complete surface */
- this->argb_ovl_data_count = 1;
- this->argb_ovl_data[0].x = 0;
- this->argb_ovl_data[0].y = 0;
- this->argb_ovl_data[0].w = total_extent_width;
- this->argb_ovl_data[0].h = total_extent_height;
-
- /* extend dirty areas to maximum for filling wiped surface */
- for (i = 0; i < ovl_data_count; i++) {
- ovl[i]->argb_layer->x1 = 0;
- ovl[i]->argb_layer->y1 = 0;
- ovl[i]->argb_layer->x2 = ovl[i]->width;
- ovl[i]->argb_layer->y2 = ovl[i]->height;
- }
- }
- }
+ int i = this->num_ovls;
+ if (i >= XINE_VORAW_MAX_OVL)
+ return;
- /* wipe surface for gone overlays */
- if (this->argb_overlay != VDP_INVALID_HANDLE) {
- uint32_t *zeros = NULL;
- for (i = 0; i < this->argb_ovl_data_count; i++) {
- argb_ovl_data_t *curr_ovl_data = &this->argb_ovl_data[i];
- int ovl_gone = 1;
- for (k = 0; k < ovl_data_count; k++) {
- if (0 == memcmp(curr_ovl_data, &ovl_data[k], sizeof (*curr_ovl_data))) {
- ovl_gone = 0;
- break;
- }
- }
- if (!ovl_gone)
- continue;
- if (!zeros)
- zeros = calloc(4, this->argb_overlay_width * this->argb_overlay_height);
- if (zeros) {
- uint32_t pitch = curr_ovl_data->w * 4;
- VdpRect dest = { curr_ovl_data->x, curr_ovl_data->y, curr_ovl_data->x + curr_ovl_data->w, curr_ovl_data->y + curr_ovl_data->h };
- VdpStatus st = vdp_output_surface_put_bits(this->argb_overlay, (void *)&zeros, &pitch, &dest);
- if (st != VDP_STATUS_OK)
- fprintf(stderr, "vdpau_process_argb_ovl: vdp_output_surface_put_bits_native failed : %s\n", vdp_get_error_string(st));
- }
- }
- free(zeros);
- }
+ if (voovl->width <= 0 || voovl->height <= 0 || (!voovl->rle && (!voovl->argb_layer || !voovl->argb_layer->buffer)))
+ return;
- /* set destination area according to dirty area of argb layer and reset dirty area */
- for (i = 0; i < ovl_data_count; i++) {
- uint32_t pitch = ovl[i]->width * 4;
- uint32_t *buffer_start = ovl[i]->argb_layer->buffer + ovl[i]->argb_layer->y1 * ovl[i]->width + ovl[i]->argb_layer->x1;
- VdpRect dest = { ovl[i]->x + ovl[i]->argb_layer->x1, ovl[i]->y + ovl[i]->argb_layer->y1, ovl[i]->x + ovl[i]->argb_layer->x2, ovl[i]->y + ovl[i]->argb_layer->y2 };
- ovl[i]->argb_layer->x1 = ovl[i]->width;
- ovl[i]->argb_layer->y1 = ovl[i]->height;
- ovl[i]->argb_layer->x2 = 0;
- ovl[i]->argb_layer->y2 = 0;
+ if (voovl->rle)
+ lprintf("overlay[%d] rle %s%s %dx%d@%d,%d extend %dx%d hili rect %d,%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);
+ 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,
+ 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);
+
+ vdpau_overlay_t *ovl = &this->overlays[i];
+ ovl->ovl = voovl;
+ ovl->x = voovl->x;
+ ovl->y = voovl->y;
+ ovl->width = voovl->width;
+ ovl->height = voovl->height;
+ ovl->extent_width = voovl->extent_width;
+ ovl->extent_height = voovl->extent_height;
+ ovl->unscaled = voovl->unscaled;
+ ovl->video_window_x = voovl->video_window_x;
+ ovl->video_window_y = voovl->video_window_y;
+ ovl->video_window_width = voovl->video_window_width;
+ ovl->video_window_height = voovl->video_window_height;
+
+ this->num_ovls = i + 1;
+}
- VdpStatus st = vdp_output_surface_put_bits(this->argb_overlay, (void *)&buffer_start, &pitch, &dest);
- if (st != VDP_STATUS_OK)
- fprintf(stderr, "vdpau_process_argb_ovl: vdp_output_surface_put_bits_native failed : %s\n", vdp_get_error_string(st));
- else
- this->has_argb_overlay = 1;
- }
- /* store ovl_data */
- memcpy(this->argb_ovl_data, ovl_data, sizeof (ovl_data));
- this->argb_ovl_data_count = ovl_data_count;
+static void vdpau_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen)
+{
+ vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
- /* unlock layers */
- for (i = 0; i < this->argb_ovl_count; i++)
- pthread_mutex_unlock(&this->argb_ovl[i]->argb_layer->mutex);
-}
+ 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) {
+ vdpau_overlay_t *ovl = &this->overlays[i];
+ vo_overlay_t *voovl = ovl->ovl;
-static int vdpau_process_ovl( vdpau_driver_t *this_gen, vo_overlay_t *overlay )
-{
- vdpau_overlay_t *ovl = &this_gen->overlays[this_gen->ovl_changed-1];
+ 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 ( overlay->width<=0 || overlay->height<=0 )
- return 0;
+ if (ovl->render_surface == VDP_INVALID_HANDLE ) {
+ this->ovl_use_dirty_rect = 0;
- if ( (ovl->bitmap_width < overlay->width ) || (ovl->bitmap_height < overlay->height) || (ovl->ovl_bitmap == VDP_INVALID_HANDLE) ) {
- if (ovl->ovl_bitmap != VDP_INVALID_HANDLE) {
- vdp_bitmap_destroy( ovl->ovl_bitmap );
- ovl->ovl_bitmap = VDP_INVALID_HANDLE;
+ 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) );
}
- VdpStatus st = vdp_bitmap_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, overlay->width, overlay->height, 0, &ovl->ovl_bitmap );
- if ( st != VDP_STATUS_OK ) {
- fprintf(stderr, "vdpau_process_ovl: vdp_bitmap_create failed : %s\n", vdp_get_error_string(st) );
+
+ 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);
+ this->ovl_pixmap = calloc(this->ovl_pixmap_size, sizeof(uint32_t));
+ }
+
+ pixmap = this->ovl_pixmap;
+ rle_elem_t *rle = voovl->rle;
+ int num_rle = voovl->num_rle;
+ int pos = 0;
+ while (num_rle > 0) {
+ int x = pos % ovl->width;
+ int y = pos / ovl->width;
+ clut_t *colors;
+ uint8_t *trans;
+ if (x >= voovl->hili_left && x <= voovl->hili_right && y >= voovl->hili_top && y <= voovl->hili_bottom) {
+ colors = (clut_t*)voovl->hili_color;
+ trans = voovl->hili_trans;
+ is_argb = voovl->hili_rgb_clut;
+ } else {
+ colors = (clut_t*)voovl->color;
+ trans = voovl->trans;
+ is_argb = voovl->rgb_clut;
+ }
+
+ int clr = rle->color;
+ uint32_t pixel;
+ if ( trans[clr] == 0 )
+ pixel = 0;
+ else if (is_argb)
+ pixel = (((uint32_t)trans[clr] * 255 / 15) << 24) | (((uint32_t)colors[clr].y) << 16) | (((uint32_t)colors[clr].cr) << 8) | ((uint32_t)colors[clr].cb);
+ else
+ pixel = (((uint32_t)trans[clr] * 255 / 15) << 24) | (((uint32_t)colors[clr].y) << 16) | (((uint32_t)colors[clr].cb) << 8) | ((uint32_t)colors[clr].cr);
+
+ int rlelen = rle->len;
+ pos += rlelen;
+ while (rlelen > 0) {
+ *pixmap++ = pixel;
+ --rlelen;
+ }
+ ++rle;
+ --num_rle;
+ }
+
+ int n = ovl->width * ovl->height - pos;
+ if (n > 0)
+ memset(pixmap, 0, n * sizeof(uint32_t));
+
+ pixmap = this->ovl_pixmap;
+ } else {
+ pthread_mutex_lock(&voovl->argb_layer->mutex);
+ pixmap = voovl->argb_layer->buffer;
}
- ovl->bitmap_width = overlay->width;
- ovl->bitmap_height = overlay->height;
- }
- ovl->ovl_w = overlay->width;
- ovl->ovl_h = overlay->height;
- ovl->ovl_x = overlay->x;
- ovl->ovl_y = overlay->y;
- ovl->unscaled = overlay->unscaled;
- ovl->expected_overlay_width = overlay->extent_width;
- ovl->expected_overlay_height = overlay->extent_height;
- uint32_t *buf = (uint32_t*)malloc(ovl->ovl_w*ovl->ovl_h*4);
- if ( !buf )
- return 0;
-
- int num_rle = overlay->num_rle;
- rle_elem_t *rle = overlay->rle;
- uint32_t *rgba = buf;
- uint32_t red, green, blue, alpha;
- clut_t *low_colors = (clut_t*)overlay->color;
- clut_t *hili_colors = (clut_t*)overlay->hili_color;
- uint8_t *low_trans = overlay->trans;
- uint8_t *hili_trans = overlay->hili_trans;
- clut_t *colors;
- uint8_t *trans;
- int rlelen = 0;
- uint8_t clr = 0;
- int i, pos=0, x, y;
-
- while ( num_rle>0 ) {
- x = pos%ovl->ovl_w;
- y = pos/ovl->ovl_w;
- if ( (x>=overlay->hili_left && x<=overlay->hili_right) && (y>=overlay->hili_top && y<=overlay->hili_bottom) ) {
- colors = hili_colors;
- trans = hili_trans;
+
+ 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) {
+ put_rect.x0 = voovl->argb_layer->x1;
+ put_rect.y0 = voovl->argb_layer->y1;
+ put_rect.x1 = voovl->argb_layer->x2;
+ put_rect.y1 = voovl->argb_layer->y2;
+ } else {
+ put_rect.x0 = 0;
+ put_rect.y0 = 0;
+ put_rect.x1 = ovl->width;
+ put_rect.y1 = ovl->height;
}
- else {
- colors = low_colors;
- trans = low_trans;
+
+ 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);
+ 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);
+ if ( st != VDP_STATUS_OK )
+ fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_put_bits_ycbcr failed : %s\n", vdp_get_error_string(st));
}
- rlelen = rle->len;
- clr = rle->color;
- for ( i=0; i<rlelen; ++i ) {
- if ( trans[clr] == 0 ) {
- alpha = red = green = blue = 0;
- }
- else {
- red = colors[clr].y; /* red */
- green = colors[clr].cr; /* green */
- blue = colors[clr].cb; /* blue */
- alpha = trans[clr]*255/15;
+
+ if (!voovl->rle) {
+ 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;
}
- *rgba = (alpha<<24) | (red<<16) | (green<<8) | blue;
- rgba++;
- ++pos;
}
- ++rle;
- --num_rle;
}
- uint32_t pitch = ovl->ovl_w*4;
- VdpRect dest = { 0, 0, ovl->ovl_w, ovl->ovl_h };
- VdpStatus st = vdp_bitmap_put_bits( ovl->ovl_bitmap, &buf, &pitch, &dest);
- if ( st != VDP_STATUS_OK ) {
- fprintf(stderr, "vdpau_process_ovl: vdp_bitmap_put_bits failed : %s\n", vdp_get_error_string(st) );
+
+ 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;
+ }
}
- free(buf);
- return 1;
+ this->created_ovls = i;
}
-
-static void vdpau_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed)
+static void vdpau_process_overlays (vdpau_driver_t *this, vo_frame_t *frame)
{
- vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
-
- if ( !changed )
+ int novls = this->num_ovls;
+ if (!novls) {
+ this->ovl_changed = 0;
return;
+ }
- this->has_overlay = this->has_unscaled = 0;
- this->has_argb_overlay = 0;
- this->argb_ovl_count = 0;
- ++this->ovl_changed;
-}
+ this->ovl_video_dest_rect.x0 = this->sc.output_xoffset;
+ this->ovl_video_dest_rect.y0 = this->sc.output_yoffset;
+ this->ovl_video_dest_rect.x1 = this->sc.output_xoffset + this->sc.output_width;
+ this->ovl_video_dest_rect.y1 = this->sc.output_yoffset + this->sc.output_height;
+ VdpRect ovl_rects[XINE_VORAW_MAX_OVL];
+ int i;
+ for (i = 0; i < novls; ++i) {
+ vdpau_overlay_t *ovl = &this->overlays[i];
+
+ if (ovl->video_window_width > 0 && ovl->video_window_height > 0) {
+ this->ovl_video_dest_rect.x0 = ovl->video_window_x;
+ this->ovl_video_dest_rect.y0 = ovl->video_window_y;
+ this->ovl_video_dest_rect.x1 = ovl->video_window_x + ovl->video_window_width;
+ this->ovl_video_dest_rect.y1 = ovl->video_window_y + ovl->video_window_height;
+ }
+ VdpRect ovl_rect;
+ ovl_rect.x0 = ovl->x;
+ ovl_rect.y0 = ovl->y;
+ ovl_rect.x1 = ovl->x + ovl->width;
+ ovl_rect.y1 = ovl->y + ovl->height;
+
+ if (!ovl->unscaled) {
+ double rx, ry;
+ if (ovl->extent_width > 0 && ovl->extent_height > 0) {
+ rx = (double)ovl->extent_width;
+ ry = (double)ovl->extent_height;
+ } else {
+ rx = (double)frame->width;
+ ry = (double)frame->height;
+ }
+ rx = (double)this->sc.output_width / rx;
+ ry = (double)this->sc.output_height / ry;
+
+ if (ovl->video_window_width > 0 && ovl->video_window_height > 0) {
+ this->ovl_video_dest_rect.x0 *= rx;
+ this->ovl_video_dest_rect.y0 *= ry;
+ this->ovl_video_dest_rect.x1 *= rx;
+ this->ovl_video_dest_rect.y1 *= ry;
+
+ this->ovl_video_dest_rect.x0 += this->sc.output_xoffset;
+ this->ovl_video_dest_rect.y0 += this->sc.output_yoffset;
+ this->ovl_video_dest_rect.x1 += this->sc.output_xoffset;
+ this->ovl_video_dest_rect.y1 += this->sc.output_yoffset;
+ }
-static void vdpau_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay)
-{
- vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
- vdpau_frame_t *frame = (vdpau_frame_t *) frame_gen;
+ ovl_rect.x0 *= rx;
+ ovl_rect.y0 *= ry;
+ ovl_rect.x1 *= rx;
+ ovl_rect.y1 *= ry;
- if (!this->ovl_changed)
- return;
+ ovl_rect.x0 += this->sc.output_xoffset;
+ ovl_rect.y0 += this->sc.output_yoffset;
+ ovl_rect.x1 += this->sc.output_xoffset;
+ ovl_rect.y1 += this->sc.output_yoffset;
- if (overlay->rle) {
- if (this->ovl_changed >= XINE_VORAW_MAX_OVL)
- return;
- if (!overlay->rgb_clut || !overlay->hili_rgb_clut)
- vdpau_overlay_clut_yuv2rgb (this, overlay, frame);
- if ( vdpau_process_ovl( this, overlay ) )
- ++this->ovl_changed;
- }
+ this->ovl_changed = 1;
+ }
- if (overlay->argb_layer) {
- if (this->argb_ovl_count >= XINE_VORAW_MAX_OVL)
- return;
- this->argb_ovl[this->argb_ovl_count++] = overlay;
- }
-}
+ ovl_rects[i] = ovl_rect;
+ if (i == 0) {
+ this->ovl_dest_rect = ovl_rect;
+ } else {
+ if (ovl_rect.x0 < this->ovl_dest_rect.x0)
+ this->ovl_dest_rect.x0 = ovl_rect.x0;
+ if (ovl_rect.y0 < this->ovl_dest_rect.y0)
+ this->ovl_dest_rect.y0 = ovl_rect.y0;
+ if (ovl_rect.x1 > this->ovl_dest_rect.x1)
+ this->ovl_dest_rect.x1 = ovl_rect.x1;
+ if (ovl_rect.y1 > this->ovl_dest_rect.y1)
+ this->ovl_dest_rect.y1 = ovl_rect.y1;
+ }
+ }
+ 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;
+ } 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;
+ }
-static void vdpau_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame)
-{
- vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
- int i;
- VdpStatus st;
+ lprintf("overlay output %dx%d -> %d,%d:%d,%d video window %d,%d:%d,%d\n",
+ this->ovl_src_rect.x1, this->ovl_src_rect.y1,
+ this->ovl_dest_rect.x0, this->ovl_dest_rect.y0, this->ovl_dest_rect.x1, this->ovl_dest_rect.y1,
+ this->ovl_video_dest_rect.x0, this->ovl_video_dest_rect.y0, this->ovl_video_dest_rect.x1, this->ovl_video_dest_rect.y1);
- if ( !this->ovl_changed )
+ if (!this->ovl_changed)
return;
-
- if (this->argb_ovl_count || this->argb_ovl_data_count)
- vdpau_process_argb_ovls(this, frame);
-
- if ( !(this->ovl_changed-1) ) {
+ if (novls == 1) {
this->ovl_changed = 0;
- this->has_overlay = 0;
- this->has_unscaled = 0;
return;
}
- int w=0, h=0;
- int scaler = 0;
- for ( i=0; i<this->ovl_changed-1; ++i ) {
- if ( this->overlays[i].unscaled )
- continue;
- if ( w < (this->overlays[i].ovl_x+this->overlays[i].ovl_w) )
- w = this->overlays[i].ovl_x+this->overlays[i].ovl_w;
- if ( h < (this->overlays[i].ovl_y+this->overlays[i].ovl_h) )
- h = this->overlays[i].ovl_y+this->overlays[i].ovl_h;
- if ( this->overlays[i].expected_overlay_width )
- scaler = 1;
- if ( this->overlays[i].expected_overlay_height )
- scaler = 1;
- }
+ VdpStatus st;
- if ( scaler ) {
- w = this->video_mixer_width;
- h = this->video_mixer_height;
+ 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;
}
- int out_w = (w>frame->width) ? w : frame->width;
- int out_h = (h>frame->height) ? h : frame->height;
+ 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) );
- if ( (this->overlay_output_width!=out_w || this->overlay_output_height!=out_h) && this->overlay_output != VDP_INVALID_HANDLE ) {
- st = vdp_output_surface_destroy( this->overlay_output );
- if ( st != VDP_STATUS_OK ) {
- fprintf(stderr, "vdpau_overlay_end: vdp_output_surface_destroy failed : %s\n", vdp_get_error_string(st) );
- }
- this->overlay_output = VDP_INVALID_HANDLE;
+ this->ovl_output_width = output_width;
+ this->ovl_output_height = output_height;
}
- this->overlay_output_width = out_w;
- this->overlay_output_height = out_h;
+ this->ovl_layer_surface = this->ovl_output_surface;
- w = 64; h = 64;
- for ( i=0; i<this->ovl_changed-1; ++i ) {
- if ( !this->overlays[i].unscaled )
- continue;
- if ( w < (this->overlays[i].ovl_x+this->overlays[i].ovl_w) )
- w = this->overlays[i].ovl_x+this->overlays[i].ovl_w;
- if ( h < (this->overlays[i].ovl_y+this->overlays[i].ovl_h) )
- h = this->overlays[i].ovl_y+this->overlays[i].ovl_h;
- }
-
- if ( (this->overlay_unscaled_width!=w || this->overlay_unscaled_height!=h) && this->overlay_unscaled != VDP_INVALID_HANDLE ) {
- st = vdp_output_surface_destroy( this->overlay_unscaled );
- if ( st != VDP_STATUS_OK ) {
- fprintf(stderr, "vdpau_overlay_end: vdp_output_surface_destroy failed : %s\n", vdp_get_error_string(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;
+ free(this->ovl_pixmap);
+ this->ovl_pixmap = calloc(this->ovl_pixmap_size, sizeof(uint32_t));
+ } else {
+ memset(this->ovl_pixmap, 0, (this->ovl_src_rect.x1 * sizeof(uint32_t)));
}
- this->overlay_unscaled = VDP_INVALID_HANDLE;
+ lprintf("overlay init output surface %dx%d\n", this->ovl_src_rect.x1, this->ovl_src_rect.y1);
+ uint32_t pitch = 0;
+ st = vdp_output_surface_put_bits( this->ovl_layer_surface, &this->ovl_pixmap, &pitch, &this->ovl_src_rect );
+ if ( st != VDP_STATUS_OK )
+ fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_put_bits (clear) failed : %s\n", vdp_get_error_string(st) );
}
- this->overlay_unscaled_width = w;
- this->overlay_unscaled_height = h;
+ for (i = 0; i < novls; ++i) {
+ vdpau_overlay_t *ovl = &this->overlays[i];
- if ( this->overlay_unscaled == VDP_INVALID_HANDLE ) {
- st = vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, this->overlay_unscaled_width, this->overlay_unscaled_height, &this->overlay_unscaled );
- if ( st != VDP_STATUS_OK )
- fprintf(stderr, "vdpau_overlay_end: vdp_output_surface_create failed : %s\n", vdp_get_error_string(st) );
- }
+ VdpRect src_rect;
+ src_rect.x0 = 0;
+ src_rect.y0 = 0;
+ src_rect.x1 = ovl->width;
+ src_rect.y1 = ovl->height;
- if ( this->overlay_output == VDP_INVALID_HANDLE ) {
- st = vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, this->overlay_output_width, this->overlay_output_height, &this->overlay_output );
+ VdpRect render_rect;
+ render_rect.x0 = ovl_rects[i].x0 - this->ovl_dest_rect.x0;
+ render_rect.x1 = ovl_rects[i].x1 - this->ovl_dest_rect.x0;
+ render_rect.y0 = ovl_rects[i].y0 - this->ovl_dest_rect.y0;
+ render_rect.y1 = ovl_rects[i].y1 - this->ovl_dest_rect.y0;
+
+ 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 );
if ( st != VDP_STATUS_OK )
- fprintf(stderr, "vdpau_overlay_end: vdp_output_surface_create failed : %s\n", vdp_get_error_string(st) );
+ fprintf(stderr, "vdpau_process_overlays: vdp_output_surface_render_output_surface failed : %s\n", vdp_get_error_string(st));
}
- w = (this->overlay_unscaled_width>this->overlay_output_width) ? this->overlay_unscaled_width : this->overlay_output_width;
- h = (this->overlay_unscaled_height>this->overlay_output_height) ? this->overlay_unscaled_height : this->overlay_output_height;
-
- uint32_t *buf = (uint32_t*)calloc(w*4,h);
- uint32_t pitch = w*4;
- VdpRect clear = { 0, 0, this->overlay_output_width, this->overlay_output_height };
- st = vdp_output_surface_put_bits( this->overlay_output, &buf, &pitch, &clear );
- if ( st != VDP_STATUS_OK ) {
- fprintf(stderr, "vdpau_overlay_end: vdp_output_surface_put_bits (clear) failed : %s\n", vdp_get_error_string(st) );
- }
- clear.x1 = this->overlay_unscaled_width; clear.y1 = this->overlay_unscaled_height;
- st = vdp_output_surface_put_bits( this->overlay_unscaled, &buf, &pitch, &clear );
- if ( st != VDP_STATUS_OK ) {
- fprintf(stderr, "vdpau_overlay_end: vdp_output_surface_put_bits (clear) failed : %s\n", vdp_get_error_string(st) );
- }
- free(buf);
-
- VdpOutputSurface *surface;
- for ( i=0; i<this->ovl_changed-1; ++i ) {
- VdpRect dest = { this->overlays[i].ovl_x, this->overlays[i].ovl_y, this->overlays[i].ovl_x+this->overlays[i].ovl_w, this->overlays[i].ovl_y+this->overlays[i].ovl_h };
- if ( this->overlays[i].expected_overlay_width ) {
- double rx = (double)this->overlay_output_width/(double)this->overlays[i].expected_overlay_width;
- double ry = (double)this->overlay_output_height/(double)this->overlays[i].expected_overlay_height;
- dest.x0 *= rx; dest.y0 *= ry; dest.x1 *=rx; dest.y1 *= ry;
- lprintf( "vdpau_overlay_end: overlay_width=%d overlay_height=%d rx=%f ry=%f\n", this->overlay_output_width, this->overlay_output_height, rx, ry );
- }
- VdpRect src = { 0, 0, this->overlays[i].ovl_w, this->overlays[i].ovl_h };
- surface = (this->overlays[i].unscaled) ? &this->overlay_unscaled : &this->overlay_output;
- st = vdp_output_surface_render_bitmap_surface( *surface, &dest, this->overlays[i].ovl_bitmap, &src, 0, &blend, 0 );
- if ( st != VDP_STATUS_OK ) {
- fprintf(stderr, "vdpau_overlay_end: vdp_output_surface_render_bitmap_surface failed : %s\n", vdp_get_error_string(st) );
- }
- }
- this->has_overlay = 1;
this->ovl_changed = 0;
}
@@ -1747,7 +1731,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
this->sc.crop_top = frame->vo_frame.crop_top;
this->sc.crop_bottom = frame->vo_frame.crop_bottom;
- vdpau_redraw_needed( this_gen );
+ int redraw_needed = vdpau_redraw_needed( this_gen );
pthread_mutex_lock(&this->drawable_lock); /* protect drawble from being changed */
@@ -1834,7 +1818,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
#endif
VdpVideoMixerParameter params[] = { VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE, VDP_VIDEO_MIXER_PARAMETER_LAYERS };
- int num_layers = 3;
+ int num_layers = 1;
void const *param_values[] = { &mix_w, &mix_h, &chroma, &num_layers };
vdp_video_mixer_create( vdp_device, features_count, features, 4, params, param_values, &this->video_mixer );
this->video_mixer_chroma = chroma;
@@ -1857,56 +1841,38 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
vdpau_update_csc( this );
}
- VdpRect vid_source, out_dest, vid_dest;
+ if (this->ovl_changed || redraw_needed)
+ vdpau_process_overlays(this, frame_gen);
- vdpau_check_output_size( this_gen );
+ uint32_t layer_count;
+ VdpLayer *layer, ovl_layer;
+ VdpRect *vid_dest, vid_dest_rect;
+ if ( this->num_ovls ) {
+ ovl_layer.struct_version = VDP_LAYER_VERSION;
+ ovl_layer.source_surface = this->ovl_layer_surface;
+ ovl_layer.source_rect = &this->ovl_src_rect;
+ ovl_layer.destination_rect = &this->ovl_dest_rect;
+ layer = &ovl_layer;
+ layer_count = 1;
+ vid_dest = &this->ovl_video_dest_rect;
+ } else {
+ layer = NULL;
+ layer_count = 0;
+ vid_dest_rect.x0 = this->sc.output_xoffset;
+ vid_dest_rect.y0 = this->sc.output_yoffset;
+ vid_dest_rect.x1 = this->sc.output_xoffset + this->sc.output_width;
+ vid_dest_rect.y1 = this->sc.output_yoffset + this->sc.output_height;
+ vid_dest = &vid_dest_rect;
+ }
+ VdpRect vid_source, out_dest;
vid_source.x0 = this->sc.displayed_xoffset; vid_source.y0 = this->sc.displayed_yoffset;
vid_source.x1 = this->sc.displayed_width+this->sc.displayed_xoffset; vid_source.y1 = this->sc.displayed_height+this->sc.displayed_yoffset;
out_dest.x0 = out_dest.y0 = 0;
out_dest.x1 = this->sc.gui_width; out_dest.y1 = this->sc.gui_height;
- vid_dest.x0 = this->sc.output_xoffset; vid_dest.y0 = this->sc.output_yoffset;
- vid_dest.x1 = this->sc.output_xoffset+this->sc.output_width; vid_dest.y1 = this->sc.output_yoffset+this->sc.output_height;
stream_speed = frame->vo_frame.stream ? xine_get_param(frame->vo_frame.stream, XINE_PARAM_FINE_SPEED) : 0;
- VdpTime last_time;
-
- if ( this->init_queue >= this->queue_length )
- vdp_queue_block( vdp_queue, this->output_surface[this->current_output_surface], &last_time );
-
- uint32_t layer_count;
- VdpLayer layer[3];
- VdpRect unscaledsrc;
- if ( this->has_overlay ) {
- layer_count = 2;
- layer[0].struct_version = VDP_LAYER_VERSION; layer[0].source_surface = this->overlay_output; layer[0].source_rect = &vid_source; layer[0].destination_rect = &vid_dest;
- unscaledsrc.x0 = 0; unscaledsrc.y0 = 0; unscaledsrc.x1 = this->overlay_unscaled_width; unscaledsrc.y1 = this->overlay_unscaled_height;
- layer[1].struct_version = VDP_LAYER_VERSION; layer[1].source_surface = this->overlay_unscaled; layer[1].source_rect = &unscaledsrc; layer[1].destination_rect = &unscaledsrc;
- }
- else {
- layer_count = 0;
- }
-
- VdpRect argb_dest;
- VdpRect argb_rect = { 0, 0, this->argb_overlay_width, this->argb_overlay_height };
- if( this->has_argb_overlay ) {
- layer_count++;
- memcpy(&argb_dest, &vid_dest, sizeof (vid_dest));
- layer[layer_count-1].destination_rect = &argb_dest;
- layer[layer_count-1].source_rect = &argb_rect;
- layer[layer_count-1].source_surface = this->argb_overlay;
- layer[layer_count-1].struct_version = VDP_LAYER_VERSION;
- /* recalculate video destination window to match osd's specified video window */
- if (this->video_window_width > 0 && this->video_window_height > 0) {
- VdpRect win_rect = { this->video_window_x, this->video_window_y, this->video_window_x + this->video_window_width, this->video_window_y + this->video_window_height };
- vid_dest.x0 = ((win_rect.x0 - argb_rect.x0) * (argb_dest.x1 - argb_dest.x0) + argb_dest.x0 * (argb_rect.x1 - argb_rect.x0)) / (argb_rect.x1 - argb_rect.x0);
- vid_dest.y0 = ((win_rect.y0 - argb_rect.y0) * (argb_dest.y1 - argb_dest.y0) + argb_dest.y0 * (argb_rect.y1 - argb_rect.y0)) / (argb_rect.y1 - argb_rect.y0);
- vid_dest.x1 = ((win_rect.x1 - argb_rect.x0) * (argb_dest.x1 - argb_dest.x0) + argb_dest.x0 * (argb_rect.x1 - argb_rect.x0)) / (argb_rect.x1 - argb_rect.x0);
- vid_dest.y1 = ((win_rect.y1 - argb_rect.y0) * (argb_dest.y1 - argb_dest.y0) + argb_dest.y0 * (argb_rect.y1 - argb_rect.y0)) / (argb_rect.y1 - argb_rect.y0);
- }
- }
-
/* try to get frame duration from previous img->pts when frame->duration is 0 */
int frame_duration = frame->vo_frame.duration;
if ( !frame_duration && this->back_frame[0] ) {
@@ -1920,10 +1886,17 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
else
non_progressive = (this->honor_progressive && !frame->vo_frame.progressive_frame) || !this->honor_progressive;
+ VdpTime last_time;
+
+ 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
+ vdpau_check_output_size( this_gen );
+
if ( frame->format==XINE_IMGFMT_VDPAU && this->deinterlace && non_progressive && !(frame->vo_frame.flags & VO_STILL_IMAGE) && frame_duration>2500 ) {
VdpTime current_time = 0;
VdpVideoSurface past[2];
@@ -1935,7 +1908,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
picture_structure = ( frame->vo_frame.top_field_first ) ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD : VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
st = vdp_video_mixer_render( this->video_mixer, VDP_INVALID_HANDLE, 0, picture_structure,
- 2, past, surface, 1, future, &vid_source, this->output_surface[this->current_output_surface], &out_dest, &vid_dest, layer_count, layer_count?layer:NULL );
+ 2, past, surface, 1, future, &vid_source, this->output_surface[this->current_output_surface], &out_dest, vid_dest, layer_count, layer );
if ( st != VDP_STATUS_OK )
fprintf(stderr, "vo_vdpau: vdp_video_mixer_render error : %s\n", vdp_get_error_string( st ) );
@@ -1971,7 +1944,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
future[0] = VDP_INVALID_HANDLE;
st = vdp_video_mixer_render( this->video_mixer, VDP_INVALID_HANDLE, 0, picture_structure,
- 2, past, surface, 1, future, &vid_source, this->output_surface[this->current_output_surface], &out_dest, &vid_dest, layer_count, layer_count?layer:NULL );
+ 2, past, surface, 1, future, &vid_source, this->output_surface[this->current_output_surface], &out_dest, vid_dest, layer_count, layer );
if ( st != VDP_STATUS_OK )
fprintf(stderr, "vo_vdpau: vdp_video_mixer_render error : %s\n", vdp_get_error_string( st ) );
@@ -1986,7 +1959,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
if ( frame->vo_frame.flags & VO_STILL_IMAGE )
lprintf( "vo_vdpau: VO_STILL_IMAGE\n");
st = vdp_video_mixer_render( this->video_mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
- 0, 0, surface, 0, 0, &vid_source, this->output_surface[this->current_output_surface], &out_dest, &vid_dest, layer_count, layer_count?layer:NULL );
+ 0, 0, surface, 0, 0, &vid_source, this->output_surface[this->current_output_surface], &out_dest, vid_dest, layer_count, layer );
if ( st != VDP_STATUS_OK )
fprintf(stderr, "vo_vdpau: vdp_video_mixer_render error : %s\n", vdp_get_error_string( st ) );
@@ -2318,37 +2291,32 @@ static void vdpau_dispose (vo_driver_t *this_gen)
vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
int i;
- this->ovl_yuv2rgb->dispose(this->ovl_yuv2rgb);
- this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
+ if ( vdp_queue != VDP_INVALID_HANDLE )
+ vdp_queue_destroy( vdp_queue );
- for ( i=0; i<XINE_VORAW_MAX_OVL; ++i ) {
- if ( this->overlays[i].ovl_bitmap != VDP_INVALID_HANDLE )
- vdp_bitmap_destroy( this->overlays[i].ovl_bitmap );
- }
+ if ( vdp_queue_target != VDP_INVALID_HANDLE )
+ vdp_queue_target_destroy( vdp_queue_target );
if ( this->video_mixer!=VDP_INVALID_HANDLE )
vdp_video_mixer_destroy( this->video_mixer );
+
if ( this->soft_surface != VDP_INVALID_HANDLE )
vdp_video_surface_destroy( this->soft_surface );
if ( vdp_output_surface_destroy ) {
- if (this->argb_overlay != VDP_INVALID_HANDLE)
- vdp_output_surface_destroy(this->argb_overlay);
- if ( this->overlay_unscaled!=VDP_INVALID_HANDLE )
- vdp_output_surface_destroy( this->overlay_unscaled );
- if ( this->overlay_output!=VDP_INVALID_HANDLE )
- vdp_output_surface_destroy( this->overlay_output );
+ if (this->ovl_output_surface != VDP_INVALID_HANDLE)
+ vdp_output_surface_destroy( this->ovl_output_surface );
+ for (i = 0; i < this->created_ovls; ++i) {
+ vdpau_overlay_t *ovl = &this->overlays[i];
+ if (ovl->render_surface != VDP_INVALID_HANDLE)
+ vdp_output_surface_destroy( ovl->render_surface );
+ }
for ( i=0; i<this->queue_length; ++i ) {
if ( this->output_surface[i]!=VDP_INVALID_HANDLE )
vdp_output_surface_destroy( this->output_surface[i] );
}
}
- if ( vdp_queue != VDP_INVALID_HANDLE )
- vdp_queue_destroy( vdp_queue );
- if ( vdp_queue_target != VDP_INVALID_HANDLE )
- vdp_queue_target_destroy( vdp_queue_target );
-
for ( i=0; i<NUM_FRAMES_BACK; i++ )
if ( this->back_frame[i] )
this->back_frame[i]->vo_frame.dispose( &this->back_frame[i]->vo_frame );
@@ -2359,6 +2327,7 @@ static void vdpau_dispose (vo_driver_t *this_gen)
pthread_mutex_destroy(&this->grab_lock);
pthread_cond_destroy(&this->grab_cond);
pthread_mutex_destroy(&this->drawable_lock);
+ free(this->ovl_pixmap);
free (this);
}
@@ -2443,23 +2412,13 @@ static void vdpau_reinit( vo_driver_t *this_gen )
}
}
- /* osd overlays need to be recreated */
- for ( i=0; i<XINE_VORAW_MAX_OVL; ++i ) {
- this->overlays[i].ovl_bitmap = VDP_INVALID_HANDLE;
- this->overlays[i].bitmap_width = 0;
- this->overlays[i].bitmap_height = 0;
- }
- this->overlay_output = VDP_INVALID_HANDLE;
- this->overlay_output_width = this->overlay_output_height = 0;
- this->overlay_unscaled = VDP_INVALID_HANDLE;
- this->overlay_unscaled_width = this->overlay_unscaled_height = 0;
- this->ovl_changed = 0;
- this->has_overlay = 0;
- this->has_unscaled = 0;
-
- this->argb_overlay = VDP_INVALID_HANDLE;
- this->argb_overlay_width = this->argb_overlay_height = 0;
- this->has_argb_overlay = 0;
+ 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->num_ovls = 0;
+ this->created_ovls = 0;
+ this->ovl_changed = 1;
VdpVideoMixerFeature features[15];
int features_count = 0;
@@ -2490,7 +2449,7 @@ static void vdpau_reinit( vo_driver_t *this_gen )
}
#endif
VdpVideoMixerParameter params[] = { VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT, VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE, VDP_VIDEO_MIXER_PARAMETER_LAYERS };
- int num_layers = 3;
+ int num_layers = 1;
void const *param_values[] = { &this->video_mixer_width, &this->video_mixer_height, &chroma, &num_layers };
st = vdp_video_mixer_create( vdp_device, features_count, features, 4, params, param_values, &this->video_mixer );
if ( vdpau_reinit_error( st, "Can't create video mixer !!" ) ) {
@@ -2615,27 +2574,21 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
this->skip_chroma_is_supported = 0;
this->background_is_supported = 0;
- for ( i=0; i<XINE_VORAW_MAX_OVL; ++i ) {
- this->overlays[i].ovl_w = this->overlays[i].ovl_h = 0;
- this->overlays[i].bitmap_width = this->overlays[i].bitmap_height = 0;
- this->overlays[i].ovl_bitmap = VDP_INVALID_HANDLE;
- this->overlays[i].ovl_x = this->overlays[i].ovl_y = 0;
- }
- this->overlay_output = VDP_INVALID_HANDLE;
- this->overlay_output_width = this->overlay_output_height = 0;
- this->overlay_unscaled = VDP_INVALID_HANDLE;
- this->overlay_unscaled_width = this->overlay_unscaled_height = 0;
this->ovl_changed = 0;
- this->has_overlay = 0;
- this->has_unscaled = 0;
-
- this->argb_overlay = VDP_INVALID_HANDLE;
- this->argb_overlay_width = this->argb_overlay_height = 0;
- this->has_argb_overlay = 0;
-
- /* overlay converter */
- this->yuv2rgb_factory = yuv2rgb_factory_init (MODE_24_BGR, 0, NULL);
- this->ovl_yuv2rgb = this->yuv2rgb_factory->create_converter( this->yuv2rgb_factory );
+ this->num_ovls = 0;
+ this->created_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_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 ) {
@@ -2662,10 +2615,32 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
const char *s;
st = vdp_get_information_string( &s );
fprintf(stderr, "vo_vdpau: vdpau implementation description : %s\n", s );
+ VdpBool ok;
+ uint32_t max_surface_width, max_surface_height;
+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES , (void*)&vdp_video_surface_query_capabilities );
+ if ( vdpau_init_error( st, "Can't get VIDEO_SURFACE_QUERY_CAPABILITIES proc address !!", &this->vo_driver, 1 ) )
+ return NULL;
+ st = vdp_video_surface_query_capabilities( vdp_device, VDP_CHROMA_TYPE_422, &ok, &max_surface_width, &max_surface_height );
+ if ( vdpau_init_error( st, "Failed to check vdpau chroma type 4:2:2 capability", &this->vo_driver, 1 ) )
+ return NULL;
+ if ( !ok ) {
+ fprintf(stderr, "vo_vdpau: VideoSurface doesn't support chroma type 4:2:2, sorry.\n");
+ vdpau_dispose( &this->vo_driver );
+ return NULL;
+ }
+ fprintf(stderr, "vo_vdpau: maximum video surface size for chroma type 4:2:2 is %dx%d\n", (int)max_surface_width, (int)max_surface_height );
+ st = vdp_video_surface_query_capabilities( vdp_device, VDP_CHROMA_TYPE_420, &ok, &max_surface_width, &max_surface_height );
+ if ( vdpau_init_error( st, "Failed to check vdpau chroma type 4:2:0 capability", &this->vo_driver, 1 ) )
+ return NULL;
+ if ( !ok ) {
+ fprintf(stderr, "vo_vdpau: VideoSurface doesn't support chroma type 4:2:0, sorry.\n");
+ vdpau_dispose( &this->vo_driver );
+ return NULL;
+ }
+ fprintf(stderr, "vo_vdpau: maximum video surface size for chroma type 4:2:0 is %dx%d\n", (int)max_surface_width, (int)max_surface_height );
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES , (void*)&vdp_video_surface_query_get_put_bits_ycbcr_capabilities );
if ( vdpau_init_error( st, "Can't get VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES proc address !!", &this->vo_driver, 1 ) )
return NULL;
- VdpBool ok;
st = vdp_video_surface_query_get_put_bits_ycbcr_capabilities( vdp_device, VDP_CHROMA_TYPE_422, VDP_YCBCR_FORMAT_YUYV, &ok );
if ( vdpau_init_error( st, "Failed to check vdpau yuy2 capability", &this->vo_driver, 1 ) )
return NULL;
@@ -2682,6 +2657,40 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
vdpau_dispose( &this->vo_driver );
return NULL;
}
+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES , (void*)&vdp_output_surface_query_capabilities );
+ if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_QUERY_CAPABILITIES proc address !!", &this->vo_driver, 1 ) )
+ return NULL;
+ st = vdp_output_surface_query_capabilities( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, &ok, &max_surface_width, &max_surface_height );
+ if ( vdpau_init_error( st, "Failed to check vdpau rgba capability", &this->vo_driver, 1 ) )
+ return NULL;
+ if ( !ok ) {
+ fprintf(stderr, "vo_vdpau: OutputSurface doesn't support rgba, sorry.\n");
+ vdpau_dispose( &this->vo_driver );
+ return NULL;
+ }
+ fprintf(stderr, "vo_vdpau: maximum output surface size is %dx%d\n", (int)max_surface_width, (int)max_surface_height );
+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES , (void*)&vdp_output_surface_query_get_put_bits_native_capabilities );
+ if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES proc address !!", &this->vo_driver, 1 ) )
+ return NULL;
+ st = vdp_output_surface_query_get_put_bits_native_capabilities( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, &ok );
+ if ( vdpau_init_error( st, "Failed to check vdpau get/put bits native capability", &this->vo_driver, 1 ) )
+ return NULL;
+ if ( !ok ) {
+ fprintf(stderr, "vo_vdpau: OutputSurface doesn't support get/put bits native, sorry.\n");
+ vdpau_dispose( &this->vo_driver );
+ return NULL;
+ }
+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES , (void*)&vdp_output_surface_query_put_bits_ycbcr_capabilities );
+ if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES proc address !!", &this->vo_driver, 1 ) )
+ return NULL;
+ st = vdp_output_surface_query_put_bits_ycbcr_capabilities( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, VDP_YCBCR_FORMAT_V8U8Y8A8, &ok );
+ if ( vdpau_init_error( st, "Failed to check vdpau put bits ycbcr capability", &this->vo_driver, 1 ) )
+ return NULL;
+ if ( !ok ) {
+ fprintf(stderr, "vo_vdpau: OutputSurface doesn't support put bits ycbcr, sorry.\n");
+ vdpau_dispose( &this->vo_driver );
+ return NULL;
+ }
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_DEVICE_DESTROY , (void*)&vdp_device_destroy );
if ( vdpau_init_error( st, "Can't get DEVICE_DESTROY proc address !!", &this->vo_driver, 1 ) )
return NULL;
@@ -2706,15 +2715,15 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY , (void*)&orig_vdp_output_surface_destroy ); vdp_output_surface_destroy = guarded_vdp_output_surface_destroy;
if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_DESTROY proc address !!", &this->vo_driver, 1 ) )
return NULL;
- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE , (void*)&vdp_output_surface_render_bitmap_surface );
- if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_RENDER_BITMAP_SURFACE proc address !!", &this->vo_driver, 1 ) )
- return NULL;
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE , (void*)&vdp_output_surface_render_output_surface );
if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE proc address !!", &this->vo_driver, 1 ) )
return NULL;
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE , (void*)&vdp_output_surface_put_bits );
if ( vdpau_init_error( st, "Can't get VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE proc address !!", &this->vo_driver, 1 ) )
return NULL;
+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR , (void*)&vdp_output_surface_put_bits_ycbcr );
+ if ( vdpau_init_error( st, "Can't get VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR proc address !!", &this->vo_driver, 1 ) )
+ return NULL;
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE , (void*)&vdp_output_surface_get_bits );
if ( vdpau_init_error( st, "Can't get VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE proc address !!", &this->vo_driver, 1 ) )
return NULL;
@@ -2793,15 +2802,6 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_DECODER_RENDER , (void*)&orig_vdp_decoder_render ); vdp_decoder_render = guarded_vdp_decoder_render;
if ( vdpau_init_error( st, "Can't get DECODER_RENDER proc address !!", &this->vo_driver, 1 ) )
return NULL;
- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_BITMAP_SURFACE_CREATE , (void*)&vdp_bitmap_create );
- if ( vdpau_init_error( st, "Can't get BITMAP_SURFACE_CREATE proc address !!", &this->vo_driver, 1 ) )
- return NULL;
- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_BITMAP_SURFACE_DESTROY , (void*)&vdp_bitmap_destroy );
- if ( vdpau_init_error( st, "Can't get BITMAP_SURFACE_DESTROY proc address !!", &this->vo_driver, 1 ) )
- return NULL;
- st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE , (void*)&vdp_bitmap_put_bits );
- if ( vdpau_init_error( st, "Can't get BITMAP_SURFACE_PUT_BITS_NATIVE proc address !!", &this->vo_driver, 1 ) )
- return NULL;
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, (void*)&vdp_preemption_callback_register );
if ( vdpau_init_error( st, "Can't get PREEMPTION_CALLBACK_REGISTER proc address !!", &this->vo_driver, 1 ) )
return NULL;
@@ -2918,7 +2918,7 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
#endif
VdpVideoMixerParameter params[] = { VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE, VDP_VIDEO_MIXER_PARAMETER_LAYERS };
- int num_layers = 3;
+ int num_layers = 1;
void const *param_values[] = { &this->video_mixer_width, &this->video_mixer_height, &chroma, &num_layers };
st = vdp_video_mixer_create( vdp_device, features_count, features, 4, params, param_values, &this->video_mixer );
if ( vdpau_init_error( st, "Can't create video mixer !!", &this->vo_driver, 1 ) ) {