summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Scheel <julian@jusst.de>2008-12-27 17:20:17 +0000
committerJulian Scheel <julian@jusst.de>2008-12-27 17:20:17 +0000
commit92d89235ad1e8a413422947b92b957a5453950ea (patch)
tree729b0bb2519e662e78514fd39fb207a97c961962
parentf57b7d6e2bfe2d2b759e5389cdd6c9f10acd1f16 (diff)
downloadxine-lib-92d89235ad1e8a413422947b92b957a5453950ea.tar.gz
xine-lib-92d89235ad1e8a413422947b92b957a5453950ea.tar.bz2
Initial support for ARGB overlay.
-rw-r--r--include/xine.h.in7
-rw-r--r--src/video_out/video_out_vdpau.c65
-rw-r--r--src/xine-engine/osd.c15
-rw-r--r--src/xine-engine/osd.h13
-rw-r--r--src/xine-engine/video_out.h2
-rw-r--r--src/xine-engine/xine_interface.c5
6 files changed, 100 insertions, 7 deletions
diff --git a/include/xine.h.in b/include/xine.h.in
index ced7a8757..79db9024e 100644
--- a/include/xine.h.in
+++ b/include/xine.h.in
@@ -2200,6 +2200,13 @@ void xine_osd_get_palette (xine_osd_t *self, uint32_t *color,
void xine_osd_set_palette (xine_osd_t *self,
const uint32_t *const color,
const uint8_t *const trans ) XINE_PROTECTED;
+
+/*
+ * set an argb buffer to be blended into video
+ * this is currently only supported with vdpau
+ */
+void xine_osd_set_argb_buffer(xine_osd_t *self, uint32_t *argb_buffer) XINE_PROTECTED;
+
/*
* close osd rendering engine
* loaded fonts are unloaded
diff --git a/src/video_out/video_out_vdpau.c b/src/video_out/video_out_vdpau.c
index ed68b5c5f..190e671b3 100644
--- a/src/video_out/video_out_vdpau.c
+++ b/src/video_out/video_out_vdpau.c
@@ -154,6 +154,11 @@ typedef struct {
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;
+
VdpVideoSurface soft_surface;
uint32_t soft_surface_width;
uint32_t soft_surface_height;
@@ -212,7 +217,35 @@ static void vdpau_overlay_clut_yuv2rgb(vdpau_driver_t *this, vo_overlay_t *over
}
}
+static int vdpau_process_argb_ovl( vdpau_driver_t *this_gen, vo_overlay_t *overlay )
+{
+ vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
+
+ if(overlay->argb_buffer == NULL)
+ return 0;
+
+ if ( (this->argb_overlay_width != overlay->width ) || (this->argb_overlay_height != overlay->height) || (this->argb_overlay == VDP_INVALID_HANDLE) ) {
+ if (this->argb_overlay != VDP_INVALID_HANDLE) {
+ vdp_output_surface_destroy( this->argb_overlay );
+ }
+ VdpStatus st = vdp_output_surface_create( vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, overlay->width, overlay->height, &this->argb_overlay );
+ if ( st != VDP_STATUS_OK ) {
+ printf( "vdpau_process_argb_ovl: vdp_output_surface_create failed : %s\n", vdp_get_error_string(st) );
+ }
+ this->argb_overlay_width = overlay->width;
+ this->argb_overlay_height = overlay->height;
+ }
+
+ uint32_t pitch = this->argb_overlay_width*4;
+ VdpRect dest = { 0, 0, this->argb_overlay_width, this->argb_overlay_height };
+ VdpStatus st = vdp_output_surface_put_bits( this->argb_overlay, (void*)&(overlay->argb_buffer), &pitch, &dest );
+ if ( st != VDP_STATUS_OK ) {
+ printf( "vdpau_process_argb_ovl: vdp_output_surface_put_bits_native failed : %s\n", vdp_get_error_string(st) );
+ } else
+ this->has_argb_overlay = 1;
+ return 1;
+}
static int vdpau_process_ovl( vdpau_driver_t *this_gen, vo_overlay_t *overlay )
{
@@ -316,6 +349,9 @@ static void vdpau_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, v
if ( vdpau_process_ovl( this, overlay ) )
++this->ovl_changed;
}
+
+ if(overlay->argb_buffer)
+ vdpau_process_argb_ovl( this, overlay );
}
@@ -667,9 +703,10 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
printf("vo_vdpau: recreate mixer to match frames: width=%d, height=%d, chroma=%d\n", mix_w, mix_h, chroma);
vdp_video_mixer_destroy( this->video_mixer );
VdpVideoMixerFeature features[] = { VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL, VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL, VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE, VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION };
- 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 = 2;
- void const *param_values[] = { &mix_w, &mix_h, &chroma, &num_layers };
+ 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, VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL };
+ int num_layers = 3;
+ float noise_reduction_level = 1.0;
+ void const *param_values[] = { &mix_w, &mix_h, &chroma, &num_layers, &noise_reduction_level };
vdp_video_mixer_create( vdp_device, 2, features, 4, params, param_values, &this->video_mixer );
this->video_mixer_chroma = chroma;
this->video_mixer_width = mix_w;
@@ -700,7 +737,7 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
vdp_queue_block( vdp_queue, this->output_surface[this->current_output_surface], &last_time );
uint32_t layer_count;
- VdpLayer layer[2];
+ VdpLayer layer[3];
VdpRect layersrc, unscaledsrc;
if ( this->has_overlay ) {
//printf("vdpau_display_frame: overlay should be visible !\n");
@@ -715,6 +752,15 @@ static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
layer_count = 0;
}
+ VdpRect argb_rect = {0, 0, this->argb_overlay_width, this->argb_overlay_height };
+ if( this->has_argb_overlay ) {
+ layer_count++;
+ layer[layer_count-1].destination_rect = &vid_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;
+ }
+
if ( frame->vo_frame.duration>2500 && !frame->vo_frame.progressive_frame && frame->format==XINE_IMGFMT_VDPAU ) {
VdpTime current_time = 0;
VdpVideoSurface past[2];
@@ -1069,6 +1115,10 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
this->ovl_changed = 0;
this->has_overlay = 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 );
@@ -1241,9 +1291,10 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
this->video_mixer_width = this->soft_surface_width;
this->video_mixer_height = this->soft_surface_height;
VdpVideoMixerFeature features[] = { VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL, VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL, VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE, VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION };
- 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 = 2;
- void const *param_values[] = { &this->video_mixer_width, &this->video_mixer_height, &chroma, &num_layers };
+ 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, VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL };
+ int num_layers = 3;
+ float noise_reduction_level = 1.0;
+ void const *param_values[] = { &this->video_mixer_width, &this->video_mixer_height, &chroma, &num_layers, &noise_reduction_level };
st = vdp_video_mixer_create( vdp_device, 2, features, 4, params, param_values, &this->video_mixer );
if ( vdpau_init_error( st, "Can't create video mixer !!", &this->vo_driver, 1 ) ) {
vdp_video_surface_destroy( this->soft_surface );
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index 05acd4779..0bc1574ca 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -152,6 +152,8 @@ static osd_object_t *XINE_MALLOC osd_new_object (osd_renderer_t *this, int width
osd->x2 = 0;
osd->y2 = 0;
+ osd->argb_buffer = NULL;
+
memcpy(osd->color, textpalettes_color[0], sizeof(textpalettes_color[0]));
memcpy(osd->trans, textpalettes_trans[0], sizeof(textpalettes_trans[0]));
@@ -228,6 +230,9 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) {
this->event.object.handle = osd->handle;
memset( this->event.object.overlay, 0, sizeof(*this->event.object.overlay) );
+
+ this->event.object.overlay->argb_buffer = osd->argb_buffer;
+
this->event.object.overlay->unscaled = unscaled;
this->event.object.overlay->x = osd->display_x + osd->x1;
this->event.object.overlay->y = osd->display_y + osd->y1;
@@ -1537,6 +1542,15 @@ static void osd_draw_bitmap(osd_object_t *osd, uint8_t *bitmap,
}
}
+static void osd_set_argb_buffer(osd_object_t *osd, uint32_t *argb_buffer)
+{
+ osd->argb_buffer = argb_buffer;
+ osd->x2 = osd->width;
+ osd->x1 = 0;
+ osd->y2 = osd->height;
+ osd->y1 = 0;
+}
+
static uint32_t osd_get_capabilities (osd_object_t *osd) {
osd_renderer_t *this = osd->renderer;
@@ -1612,6 +1626,7 @@ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) {
this->get_text_size = osd_get_text_size;
this->close = osd_renderer_close;
this->draw_bitmap = osd_draw_bitmap;
+ this->set_argb_buffer = osd_set_argb_buffer;
this->show_unscaled = osd_show_unscaled;
this->get_capabilities = osd_get_capabilities;
diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h
index 70193a2ea..ed3118a05 100644
--- a/src/xine-engine/osd.h
+++ b/src/xine-engine/osd.h
@@ -65,6 +65,13 @@ struct osd_object_s {
osd_font_t *font;
osd_ft2context_t *ft2;
+
+
+ /* this holds an optional ARGB overlay, which
+ * is only be used by supported video_out modules.
+ * right now this is only vdpau */
+ uint32_t *argb_buffer;
+
};
/* this one is public */
@@ -211,6 +218,12 @@ struct osd_renderer_s {
*/
uint32_t (*get_capabilities) (osd_object_t *osd);
+ /*
+ * set a buffer to an argb buffer
+ */
+ void (*set_argb_buffer) (osd_object_t *osd, uint32_t *argb_buffer);
+
+
/* private stuff */
pthread_mutex_t osd_mutex;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 17ddd660b..7fa34ac8b 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -419,6 +419,8 @@ struct vo_overlay_s {
int hili_rgb_clut; /* true if clut was converted to rgb */
int unscaled; /* true if it should be blended unscaled */
+
+ uint32_t *argb_buffer;
};
diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c
index d1d5a18d9..1f6175a06 100644
--- a/src/xine-engine/xine_interface.c
+++ b/src/xine-engine/xine_interface.c
@@ -855,6 +855,11 @@ void xine_osd_draw_bitmap(xine_osd_t *this, uint8_t *bitmap,
this->osd.renderer->draw_bitmap(&this->osd, bitmap, x1, y1, width, height, palette_map);
}
+void xine_osd_set_argb_buffer(xine_osd_t *this, uint32_t *argb_buffer) {
+ this->osd.renderer->set_argb_buffer(&this->osd, argb_buffer);
+}
+
+
const char *const *xine_post_list_inputs(xine_post_t *this_gen) {
post_plugin_t *this = (post_plugin_t *)this_gen;
return this->input_ids;