Пример #1
0
QString VdpauWidget::benchH264720p()
{
   if ( !vc->isProfileSupported( VDPAUContext::ProfileH264High) )
      return "Profile unsupported.\n";

   QString directoryName(dataDirectory);
   directoryName.append("h264720p.dat");
   H264Decoder *d = new H264Decoder( vc, directoryName );
   if ( !d->init() ) {
      delete d;
      return "Can't initialize H264 decoder!\n";
   }

   if ( mixerWidth!=d->width || mixerHeight!=d->height )
      createMixer( d->width, d->height );

   int i;
   for ( i=0; i<FRAMESINSAMPLE; ++i ) {
      displayFrame( d->getNextFrame(), d->width, d->height, d->ratio );
      usleep( SHOWTIME );
   }

   QTime t;
   t.start();
   for ( i=0; i<FRAMESINLOOP; ++i ) {
      d->getNextFrame();
   }
   int e = t.elapsed();
   benchH264720pResult = QString("H264 DECODING (%1x%2): %3 frames/s\n").arg(d->width).arg(d->height).arg(FRAMESINLOOP*1000/e);

   delete d;
   return benchH264720pResult;
}
Пример #2
0
QString VdpauWidget::benchMPEG4()
{
   if ( !vc->isProfileSupported( VDPAUContext::ProfileMPEG4ASP) )
      return "Profile unsupported.\n";
#ifdef VDP_DECODER_PROFILE_MPEG4_PART2_ASP
   MPEG4Decoder *d = new MPEG4Decoder( vc, dataDirectory );
   if ( !d->init() ) {
      delete d;
      return "Can't initialize MPEG4 decoder!\n";
   }

   if ( mixerWidth!=d->width || mixerHeight!=d->height )
      createMixer( d->width, d->height );

   int i;
   for ( i=0; i<FRAMESINSAMPLE; ++i ) {
      displayFrame( d->getNextFrame(), d->width, d->height, d->ratio );
      usleep( SHOWTIME );
   }

   QTime t;
   t.start();
   for ( i=0; i<FRAMESINLOOP; ++i ) {
      d->getNextFrame();
   }
   int e = t.elapsed();
   benchMPEG4Result = QString("MPEG4 DECODING (%1x%2): %3 frames/s\n").arg(d->width).arg(d->height).arg(FRAMESINLOOP*1000/e);

   delete d;
#endif // VDP_DECODER_PROFILE_MPEG4_PART2_ASP
   return benchMPEG4Result;
}
Пример #3
0
 QWidget* createMixer(QWidget* parent) {
     parent->setObjectName("mixer");
     QGridLayout* grid = new QGridLayout(parent);
     // row 1
     grid->addWidget(createIndex("1"), 0, 0);
     grid->addWidget(createMixer(new QGroupBox(), 0), 0, 1);
     // row 2
     grid->addWidget(createIndex("2"), 1, 0);
     grid->addWidget(createMixer(new QGroupBox(), 1), 1, 1);
     // row 3
     grid->addWidget(createIndex("3"), 2, 0);
     grid->addWidget(createMixer(new QGroupBox(), 2), 2, 1);
     // row 4
     grid->addWidget(createIndex("4"), 3, 0);
     grid->addWidget(createMixer(new QGroupBox(), 3), 3, 1);
     grid->setHorizontalSpacing(2);
     return parent;
 }
Пример #4
0
QString VdpauWidget::initVdpau()
{
   QString res = vc->init();
   if ( !res.isEmpty() )
      return res;

   VdpStatus st = vc->vdp_output_surface_create( vc->vdpDevice, VDP_RGBA_FORMAT_B8G8R8A8, width(), height(), &displaySurface );
   if ( st != VDP_STATUS_OK ) {
      return "FATAL: Can't create display output surface !!\n";
   }

   if ( !createMixer( SURFACEWIDTH, SURFACEHEIGHT ) )
      return "FATAL: can't create mixer!\n";

   st = vc->vdp_presentation_queue_target_create_x11( vc->vdpDevice, winId(), &queueTarget );
   if ( st != VDP_STATUS_OK )
      return "FATAL: can't create queue target!";
   st = vc->vdp_presentation_queue_create( vc->vdpDevice, queueTarget, &queue );
   if ( st != VDP_STATUS_OK )
      return "FATAL: can't create display queue!";

   return "";
}
Пример #5
0
AppFrameWork::AppFrameWork():pGui(),pVarMan()
{
	/*-----default values-----------------*/
	exit = false;

	unsigned int width=800;//window's width
	unsigned int height=600;//window's height
	unsigned int fps=60;//frames per second 
	ready=false;
	mutexes=NULL;
	numMutex=0;
	this->elapsedTime=this->overSleepTime=this->sleepTime=this->excessTime=this->totalTime=0.0;
	fpsUpdatePeriod=0.13;
	frames=0;
	calFps=false;
	memset(&mouseState,0,sizeof(MouseState));
	/*-------------------------------------*/
	//read config.ini
	FILE* f;
	f=fopen("../Config/config.ini","r");
	if(f)
	{
		fscanf(f,"width=%u\n",&width);
		fscanf(f,"height=%u\n",&height);
		fscanf(f,"fps=%u\n",&fps);

		unsigned int ms;
		fscanf(f,"fpsUpdatePeriod=%u\n",&ms);//miliseconds
		fpsUpdatePeriod = ms/1000.0f;
		fclose(f);
	}
	//calculate period of an game loop's iteration
	this->period=1.0/fps;

	pRendererDll=LoadLibrary(L"Renderer.dll");//load dll
	if(!pRendererDll)
		return;
	pCreateRendererProc createRenderer=(pCreateRendererProc)GetProcAddress(pRendererDll,"CreateRenderer");
	if(!createRenderer)
	{
		FreeLibrary(pRendererDll);
		pRendererDll=NULL;
		return;
	}

	pMixerDll=LoadLibrary(L"Mixer.dll");//load dll
	if(!pMixerDll)
		return;
	pCreateDefaultMixerProc createMixer=(pCreateDefaultMixerProc)GetProcAddress(pMixerDll,"CreateDefaultMixer");
	if(!createMixer)
	{
		FreeLibrary(pMixerDll);
		pMixerDll=NULL;
		return;
	}
	//create mixer

	pMixer=createMixer();
	if(pMixer==NULL)
		return;

	InitWindow(width,height);

	//create renderer

	pRenderer=createRenderer(width,height);
	if(pRenderer==NULL)
		return;
	//init default matrices for renderer
	Matrix4x4 matrix;
	Matrix4PerspectiveProjRH(_PIOVER4,(float)width/height,1.0f,1000.0f,&matrix);

	pRenderer->SetProjectionMatrix(matrix);

	Matrix4LookAtRH(&Vector4(0,0,0,1),&Vector4(0,0,-1,1),&Vector4(0,1,0,0),&matrix);

	pRenderer->SetViewMatrix(matrix);

	//create GUI manager
	pGui = SharedPtr<GUImanager>(new GUImanager(pRenderer),false);
	//create variable manager
	pVarMan = SharedPtr<VariableManager>(new VariableManager(),false);

	//create mesh manager
	pMeshMan = SharedPtr<MeshManager>(new MeshManager(pRenderer),false);

	//default callback
	updateFunc=&DummyFunc;
	displayFunc=&DummyFunc;
	keyPressFunc=&DummyKeyFunc;

	ready=true;//now ready to use
}
Пример #6
0
// next 2 functions are the 2 threads.
// the first one (the main thread) runs the decoder
// the second one runs the mixer
QString VdpauWidget::benchMT()
{
   // init a mpeg decoder
   QString directoryName(dataDirectory);
   directoryName.append("mpghd.dat");
   MPEGDecoder *m = new MPEGDecoder( vc, directoryName );
   if ( !m->init() ) {
      delete m;
      return "Can't initialize MPEG decoder (1)!";
   }

   // create the rgba surface used by the mixer
   VdpStatus st = vc->vdp_output_surface_create( vc->vdpDevice, VDP_RGBA_FORMAT_B8G8R8A8, m->width, m->height, &mixerSurface );
   if ( st != VDP_STATUS_OK ) {
      delete m;
      return "FATAL: Can't create mixer output surface !!\n";
   }

   if ( mixerWidth!=m->width || mixerHeight!=m->height )
      createMixer( m->width, m->height );

   setDeinterlace( DEINT_TEMPORAL );

   // init the mixer thread
   // m->getOrderedFrames returns a list of 22 decoded surfaces in display order and destroys the decoder ...
   VdpauThread vt( vc, m->getOrderedFrames(), mixer, mixerSurface, m->width, m->height );

   // ... so we can create a new one here
   directoryName.clear();
   directoryName.append(dataDirectory);
   directoryName.append("mpghd.dat");
   MPEGDecoder *d = new MPEGDecoder( vc, directoryName );
   if ( !d->init( true ) ) {
      delete d;
      delete m;
      vc->vdp_output_surface_destroy( mixerSurface );
      return "Can't initialize MPEG decoder (2)!";
   }

   vt.running = true;
   // start the mixer thread
   vt.start();

   int loop=0;
   QTime t;
   t.start();
   // this is the decoder loop
   while ( t.elapsed() < MIXERLOOP ) {
      // decode next frame (25 frames in turn)
      d->getNextFrame();
      ++loop;
   }
   int e = t.elapsed();

   vt.running = false;
   // wait for the mixer thread to end
   vt.wait();

   benchMTResult = QString("MULTITHREADED MPEG DECODING (%1x%2): %3 frames/s\n").arg(d->width).arg(d->height).arg(loop*1000/e);
   benchMTResult += vt.result;

   delete d;
   delete m;
   vc->vdp_output_surface_destroy( mixerSurface );

   return benchMTResult;
}
Пример #7
0
QString VdpauWidget::benchMixer()
{
   QString directoryName(dataDirectory);
   directoryName.append("mpghd.dat");
   MPEGDecoder *d = new MPEGDecoder( vc, directoryName );
   if ( !d->init() ) {
      delete d;
      return "Can't initialize MPEG decoder!";
   }

   if ( mixerWidth!=d->width || mixerHeight!=d->height )
      createMixer( d->width, d->height );

   QList< VdpVideoSurface > list = d->getOrderedFrames();

   VdpStatus st = vc->vdp_output_surface_create( vc->vdpDevice, VDP_RGBA_FORMAT_B8G8R8A8, d->width, d->height, &mixerSurface );
   if ( st != VDP_STATUS_OK ) {
      delete d;
      return "FATAL: Can't create mixer output surface !!\n";
   }

   int i, loop=0;
   VdpRect vid_source = { 0, 0, d->width, d->height };

   setSkipChroma( 0 );
   // weave
   setDeinterlace( DEINT_BOB );
   QTime t;
   int e;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
               0, 0, list.at(i), 0, 0, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
      }
      ++loop;
   }
   e = t.elapsed();
   int n = (NUMSURFACES-2)*loop;
   benchMixerResult = QString("MIXER WEAVE (%1x%2): %3 frames/s\n").arg(d->width).arg(d->height).arg(n*1000/e);

   // bob
   loop = 0;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
               0, 0, list.at(i), 0, 0, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
               0, 0, list.at(i), 0, 0, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
      }
      loop += 2;
   }
   e = t.elapsed();
   n = (NUMSURFACES-2)*loop;
   benchMixerResult += QString("MIXER BOB (%1x%2): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);

   VdpVideoSurface past[2];
   VdpVideoSurface future[1];

   // temporal
   setDeinterlace( DEINT_TEMPORAL );
   loop = 0;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         past[1] = past[0] = list.at(i-1);
         future[0] = list.at(i);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         past[0] = list.at(i);
         future[0] = list.at(i+1);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
      }
      loop += 2;
   }
   e = t.elapsed();
   n = (NUMSURFACES-2)*loop;
   benchMixerResult += QString("MIXER TEMPORAL (%1x%2): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);

   // temporal + ivtc
   setIvtc( 1 );
   loop = 0;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         past[1] = past[0] = list.at(i-1);
         future[0] = list.at(i);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         past[0] = list.at(i);
         future[0] = list.at(i+1);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
      }
      loop += 2;
   }
   e = t.elapsed();
   n = (NUMSURFACES-2)*loop;
   benchMixerResult += QString("MIXER TEMPORAL + IVTC (%1x%2): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);
   setIvtc( 0 );

   // temporal + skip_chroma
   setSkipChroma( 1 );
   loop = 0;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         past[1] = past[0] = list.at(i-1);
         future[0] = list.at(i);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         past[0] = list.at(i);
         future[0] = list.at(i+1);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
      }
      loop += 2;
   }
   e = t.elapsed();
   n = (NUMSURFACES-2)*loop;
   benchMixerResult += QString("MIXER TEMPORAL + SKIP_CHROMA (%1x%2): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);
   setSkipChroma( 0 );

   // temporal_spatial
   setDeinterlace( DEINT_TEMPORAL_SPATIAL );
   loop = 0;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         past[1] = past[0] = list.at(i-1);
         future[0] = list.at(i);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         past[0] = list.at(i);
         future[0] = list.at(i+1);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
      }
      loop += 2;
   }
   e = t.elapsed();
   n = (NUMSURFACES-2)*loop;
   benchMixerResult += QString("MIXER TEMPORAL_SPATIAL (%1x%2): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);

   // temporal_spatial + ivtc
   setIvtc( 1 );
   loop = 0;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         past[1] = past[0] = list.at(i-1);
         future[0] = list.at(i);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         past[0] = list.at(i);
         future[0] = list.at(i+1);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
      }
      loop += 2;
   }
   e = t.elapsed();
   n = (NUMSURFACES-2)*loop;
   benchMixerResult += QString("MIXER TEMPORAL_SPATIAL + IVTC (%1x%2): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);
   setIvtc( 0 );

   // temporal_spatial + skip_chroma
   setSkipChroma( 1 );
   loop = 0;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         past[1] = past[0] = list.at(i-1);
         future[0] = list.at(i);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         past[0] = list.at(i);
         future[0] = list.at(i+1);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_source, &vid_source, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
      }
      loop += 2;
   }
   e = t.elapsed();
   n = (NUMSURFACES-2)*loop;
   benchMixerResult += QString("MIXER TEMPORAL_SPATIAL + SKIP_CHROMA (%1x%2): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);
   setSkipChroma( 0 );

   delete d;
   vc->vdp_output_surface_destroy( mixerSurface );

   // SD

   directoryName.clear();
   directoryName.append(dataDirectory);
   directoryName.append("mpgsd.dat");
   d = new MPEGDecoder( vc, directoryName );
   if ( !d->init() ) {
      delete d;
      return "Can't initialize MPEG decoder!";
   }

   if ( mixerWidth!=d->width || mixerHeight!=d->height )
      createMixer( d->width, d->height );

   list = d->getOrderedFrames();

   int sdwidth=1920, sdheight=1080;

   st = vc->vdp_output_surface_create( vc->vdpDevice, VDP_RGBA_FORMAT_B8G8R8A8, sdwidth, sdheight, &mixerSurface );
   if ( st != VDP_STATUS_OK ) {
      delete d;
      return "FATAL: Can't create mixer output surface !!\n";
   }

   vid_source.x1 = d->width;
   vid_source.y1 = d->height;

   VdpRect vid_dest = { 0, 0, sdwidth, sdheight };

   // temporal_spatial SD
   setDeinterlace( DEINT_TEMPORAL_SPATIAL );
   loop = 0;
   t.start();
   while ( t.elapsed() < MIXERLOOP ) {
      for ( i=1; i<NUMSURFACES-1; ++i ) {
         past[1] = past[0] = list.at(i-1);
         future[0] = list.at(i);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_dest, &vid_dest, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         past[0] = list.at(i);
         future[0] = list.at(i+1);
         st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
               2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_dest, &vid_dest, 0, NULL );
         if ( st != VDP_STATUS_OK )
            fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
      }
      loop+=2;
   }
   e = t.elapsed();
   n = (NUMSURFACES-2)*loop;
   benchMixerResult += QString("MIXER TEMPORAL_SPATIAL (%1x%2 video to 1920x1080 display): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);

   // temporal_spatial SD + hqScaling
   if ( vc->hqScalingSupported() ) {
      setHqScaling( 1 );
      loop = 0;
      t.start();
      while ( t.elapsed() < MIXERLOOP ) {
         for ( i=1; i<NUMSURFACES-1; ++i ) {
            past[1] = past[0] = list.at(i-1);
            future[0] = list.at(i);
            st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
                  2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_dest, &vid_dest, 0, NULL );
            if ( st != VDP_STATUS_OK )
               fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
            past[0] = list.at(i);
            future[0] = list.at(i+1);
            st = vc->vdp_video_mixer_render( mixer, VDP_INVALID_HANDLE, 0, VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
                  2, past, list.at(i), 1, future, &vid_source, mixerSurface, &vid_dest, &vid_dest, 0, NULL );
            if ( st != VDP_STATUS_OK )
               fprintf( stderr, "vdp_video_mixer_render failed: %s\n", vc->vdp_get_error_string( st ) );
         }
         loop+=2;
      }
      e = t.elapsed();
      n = (NUMSURFACES-2)*loop;
      benchMixerResult += QString("MIXER TEMPORAL_SPATIAL + HQSCALING (%1x%2 video to 1920x1080 display): %3 fields/s\n").arg(d->width).arg(d->height).arg(n*1000/e);
      setHqScaling( 0 );
   }

   delete d;
   return benchMixerResult;
}