From 944fc07d1bfd33010a1a61e923d53b884f5a6359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Thu, 26 Jul 2007 23:35:19 +0200 Subject: propagate frame changes in xxmc_do_update_frame() to intercepted frames XXMC doesn't work well with the way how intercepting frames is implemented for postprocessing as xxmc_do_update_frame() may change the native frame's format after the frame has been intercepted. As intercepting XXMC frames didn't work in the past, we can imply that postplugins which will support XXMC do know about this special behaviour. So the idea is to detect any changes on the native frame and propagate these changes to all intercepted frames. At the same time, we check that all intercepted frames still share the same data (which we are about to change) with the native frame and abort otherwise. --HG-- extra : transplant_source : c%D5%13%21jF%1E%D4%AB%D7%DB%22%27%0A%CB%0E%7F%CF%84v --- src/video_out/video_out_xxmc.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c index 748d207ab..1f093070d 100644 --- a/src/video_out/video_out_xxmc.c +++ b/src/video_out/video_out_xxmc.c @@ -1230,6 +1230,13 @@ static void xxmc_do_update_frame(vo_driver_t *this_gen, if ( XINE_IMGFMT_XXMC == format ) { xine_xxmc_t *xxmc = &frame->xxmc_data; + vo_frame_t orig_frame_content; + + if (frame_gen != &frame->vo_frame) { + /* this is an intercepted frame, so we need to detect and propagate any + * changes on the original vo_frame to all the intercepted frames */ + xine_fast_memcpy(&orig_frame_content, &frame->vo_frame, sizeof (vo_frame_t)); + } xvmc_context_writer_lock( &this->xvmc_lock); if (xxmc_accel_update(this, this->last_accel_request, xxmc->acceleration) || @@ -1259,6 +1266,33 @@ static void xxmc_do_update_frame(vo_driver_t *this_gen, xvmc_context_writer_unlock( &this->xvmc_lock); + if (frame_gen != &frame->vo_frame) { + /* this is an intercepted frame, so we need to detect and propagate any + * changes on the original vo_frame to all the intercepted frames */ + unsigned char *p0 = (unsigned char *)&orig_frame_content; + unsigned char *p1 = (unsigned char *)&frame->vo_frame; + int i; + for (i = 0; i < sizeof (vo_frame_t); i++) { + if (*p0 != *p1) { + /* propagate the change */ + vo_frame_t *f = frame_gen; + while (f->next) { + /* serveral restrictions apply when intercepting XXMC frames. So let's check + * the intercepted frames before modifing them and fail otherwise. */ + unsigned char *p = (unsigned char *)f + i; + if (*p != *p0) { + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "xxmc_do_update_frame: a post plugin violates the restrictions on intercepting XXMC frames\n"); + _x_abort(); + } + + *p = *p1; + f = f->next; + } + } + p0++; + p1++; + } + } } else { /* switch back to an unaccelerated context */ if (this->last_accel_request != 0xFFFFFFFF) { -- cgit v1.2.3