[MPlayer-dev-eng] [PATCH]VDPAU: Recover from display pre-emption
Carl Eugen Hoyos
cehoyos at rainbow.studorg.tuwien.ac.at
Mon Oct 5 09:55:45 CEST 2009
Hi!
I tested Uoti's display preemption patch successfully on a system where
preemptions are (unfortunately) nothing unusual (even for vo vdpau with
software decoding) when receiving DVB streams at the same time (KNC One
DVB-S2 with multiproto and v4l-dvb trunk).
Attached is a version for current svn, it certainly works not as nice for
preemptions caused by virtual display change, but it does work and I
consider such (user) issues less important.
At least the change in control() is probably unnecessary, but I cannot
test for ten days, so please comment.
Carl Eugen
PS: Has anybody ever tried to port gnutv to DVB-S2?
It seems the superior tuning application to me.
-------------- next part --------------
Index: libvo/vo_vdpau.c
===================================================================
--- libvo/vo_vdpau.c (revision 29748)
+++ libvo/vo_vdpau.c (working copy)
@@ -142,6 +142,7 @@
static VdpDecoderRender *vdp_decoder_render;
static VdpGenerateCSCMatrix *vdp_generate_csc_matrix;
+static VdpPreemptionCallbackRegister *vdp_preemption_callback_register;
static void *vdpau_lib_handle;
/* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */
@@ -177,6 +178,8 @@
static VdpChromaType vdp_chroma_type;
static VdpYCbCrFormat vdp_pixel_format;
+static volatile int is_preempted;
+
/* draw_osd */
static unsigned char *index_data;
static int index_data_size;
@@ -310,6 +313,12 @@
flip_page();
}
+static void preemption_callback(VdpDevice device, void *context)
+{
+ mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Display preemption detected\n");
+ is_preempted = 1;
+}
+
/* Initialize vdp_get_proc_address, called from preinit() */
static int win_x11_init_vdpau_procs(void)
{
@@ -365,6 +374,8 @@
{VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE,
&vdp_output_surface_render_bitmap_surface},
{VDP_FUNC_ID_GENERATE_CSC_MATRIX, &vdp_generate_csc_matrix},
+ {VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER,
+ &vdp_preemption_callback_register},
{0, NULL}
};
@@ -383,6 +394,10 @@
return -1;
}
}
+ vdp_st = vdp_preemption_callback_register(vdp_device,
+ preemption_callback, NULL);
+ CHECK_ST_ERROR("Error when calling vdp_preemption_callback_register")
+
return 0;
}
@@ -528,6 +543,51 @@
return 1;
}
+static void mark_vdpau_objects_uninitialized(void)
+{
+ int i;
+
+ decoder = VDP_INVALID_HANDLE;
+ for (i = 0; i < MAX_VIDEO_SURFACES; i++)
+ surface_render[i].surface = VDP_INVALID_HANDLE;
+ for (i = 0; i < 3; i++) {
+ deint_surfaces[i] = VDP_INVALID_HANDLE;
+ if (i < 2 && deint_mpi[i])
+ deint_mpi[i]->usage_count--;
+ deint_mpi[i] = NULL;
+ }
+ video_mixer = VDP_INVALID_HANDLE;
+ vdp_flip_queue = VDP_INVALID_HANDLE;
+ vdp_flip_target = VDP_INVALID_HANDLE;
+ for (i = 0; i <= NUM_OUTPUT_SURFACES; i++)
+ output_surfaces[i] = VDP_INVALID_HANDLE;
+ vdp_device = VDP_INVALID_HANDLE;
+ for (i = 0; i < eosd_surface_count; i++)
+ eosd_surfaces[i].surface = VDP_INVALID_HANDLE;
+ output_surface_width = output_surface_height = -1;
+ eosd_render_count = 0;
+ visible_buf = 0;
+}
+
+static int handle_preemption(void)
+{
+ if (!is_preempted)
+ return 0;
+ is_preempted = 0;
+ mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Attempting to recover from preemption.\n");
+ mark_vdpau_objects_uninitialized();
+ if (win_x11_init_vdpau_procs() < 0 ||
+ win_x11_init_vdpau_flip_queue() < 0 ||
+ create_vdp_mixer(vdp_chroma_type) < 0) {
+ mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Recovering from preemption failed\n");
+ is_preempted = 1;
+ return -1;
+ }
+ resize();
+ mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Recovered from display preemption.\n");
+ return 1;
+}
+
/*
* connect to X server, create and map window, initialize all
* VDPAU objects, create different surfaces etc.
@@ -634,6 +694,9 @@
{
int e = vo_x11_check_events(mDisplay);
+ if (handle_preemption() < 0)
+ return;
+
if (e & VO_EVENT_RESIZE)
resize();
@@ -831,6 +894,9 @@
{
mp_msg(MSGT_VO, MSGL_DBG2, "DRAW_OSD\n");
+ if (handle_preemption() < 0)
+ return;
+
vo_draw_text_ext(vo_dwidth, vo_dheight, border_x, border_y, border_x, border_y,
vid_width, vid_height, draw_osd_I8A8);
}
@@ -841,6 +907,9 @@
mp_msg(MSGT_VO, MSGL_DBG2, "\nFLIP_PAGE VID:%u -> OUT:%u\n",
surface_render[vid_surface_num].surface, output_surfaces[surface_num]);
+ if (handle_preemption() < 0)
+ return;
+
vdp_st = vdp_presentation_queue_display(vdp_flip_queue, output_surfaces[surface_num],
vo_dwidth, vo_dheight,
0);
@@ -856,6 +925,10 @@
VdpStatus vdp_st;
struct vdpau_render_state *rndr = (struct vdpau_render_state *)image[0];
int max_refs = image_format == IMGFMT_VDPAU_H264 ? rndr->info.h264.num_ref_frames : 2;
+
+ if (handle_preemption() < 0)
+ return VO_TRUE;
+
if (!IMGFMT_IS_VDPAU(image_format))
return VO_FALSE;
if ((decoder == VDP_INVALID_HANDLE || decoder_max_refs < max_refs)
@@ -1165,6 +1238,8 @@
static int control(uint32_t request, void *data, ...)
{
+ handle_preemption();
+
switch (request) {
case VOCTRL_GET_DEINTERLACE:
*(int*)data = deint;
More information about the MPlayer-dev-eng
mailing list