[Openchrome-users] cle266: time spent in XvMCPutSurface() is longer than frame duration

Mark Zimmerman markzimm
Mon Jan 15 07:28:07 PST 2007


On Sat, Jan 13, 2007 at 10:11:07AM +0100, Reinhard Nissl wrote:
> Hi,
> 
> I'm trying to optimize xine-lib's xxmc driver which uses
> XvMCPutSurface() to display a video frame.
> 
> Typically, the time spent in this function is less then 1 ms. But
> occationally, it happens that it needs 50 ms to process and then 20 ms.
> 
> Please have a look at the attached code fragment. This function is
> called every 40 ms to display a frame. When bob-deinterlacing is
> enabled, it first displays for example the top field. Then it sleeps ~20
> ms and displays the bottom field.
> 
> I've instrumented the code with gettimeofday() calls to see how long it
> takes to execute specific parts of the code. At the end of the function
> the deltas are output on screen. In the attached output, dt4 lists the
> time spent in the first call of XvMCPutSurface() and dt9 for the second.
> The last column dt shows the total time spent for executing the code.
> 
> As you can see, dt4 and dt9 are typically less than 1 ms and dt6 shows
> the time spent with sleeping (~20 ms) between the two calls to
> XvMCPutSurface().
> 
> But at a certain point in time, dt9 rises immediately to more than 50 ms
> and the total time spent to ~70 ms. As a result, xine tries to hurry up
> and calls the output function immediately with the next frame. As a
> result, dt4 and dt9 show values of about 20 ms. The total time spent
> raises to over 40 ms, so xine continues to hurry up but the situation
> doesn't improve. Finally, xine drops some frames and the time spent in
> XvMCPutSurface() goes back to normal values.
> 
> The 20 ms seem to be the result of the video driver's waiting for the
> next vblank interrupt. But I have no idea, why the issue starts
> repeatedly at the second call to XvMCPutSurface() with a duration of
> more than 50 ms.
> 

I have been looking at the same code in an attempt to cure excessive
frame drops on system with an nvidia card. The first thing I
questioned was the unconditional sleep between frames, but I made no
attempt to measure and report the elapsed times for fear of perturbing
the system I was trying to measure. Are you sure that the time spent
doing I/O is not affecting performance?

I made a small change that subtracts the elapsed time to render the
first field from the sleep time and it largely cured my frame drops.
The following patch applies to xine-lib-1.1.3 (your code seems to be a
different version).

----------------------------------------------------------------------
--- video_out_xxmc.c.orig       2006-12-26 15:38:54.000000000 -0700
+++ video_out_xxmc.c    2007-01-05 21:37:32.000000000 -0700
@@ -40,6 +40,8 @@
 
 #include "xxmc.h"
 #include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
 
 
 static int gX11Fail;
@@ -1615,6 +1617,9 @@
 
   xxmc_redraw_needed (this_gen);
   if (frame->format == XINE_IMGFMT_XXMC) {
+    struct timeval tv0 = {0,0};
+    struct timezone tz = {0,0};
+    int tstat0 = gettimeofday (&tv0, &tz);
     XVMCLOCKDISPLAY( this->display );
     XvMCSyncSurface( this->display, frame->xvmc_surf );
     XvMCPutSurface( this->display, frame->xvmc_surf , this->drawable,
@@ -1625,10 +1630,18 @@
                    this->cur_field);
     XVMCUNLOCKDISPLAY( this->display );
     if (this->deinterlace_enabled && this->bob) {
+      struct timeval tv1 = {0,0};
+      int tstat1 = gettimeofday (&tv1, &tz);
+      unsigned long already = 0;
+      if ( (tstat0==0) && (tstat1==0) )
+        already = (tv1.tv_usec - tv0.tv_usec)
+                + (1000000*(tv1.tv_sec-tv0.tv_sec));
       unsigned 
        ms_per_field = 500 * frame->vo_frame.duration / 90000 - 2;
       
-      usleep(ms_per_field*1000);
+      if ((ms_per_field*1000) > already)
+        usleep((ms_per_field*1000) - already);
+
       this->cur_field = (frame->vo_frame.top_field_first) ? XVMC_BOTTOM_FIELD : XVMC_TOP_FIELD;
 
       XVMCLOCKDISPLAY( this->display );

----------------------------------------------------------------------

Also, I did something else that seemed to improve smoothness (although
I have no measurements to prove it). I spent some time tweaking my
modeline until I had a refresh rate that was an exact multiple of the
1080i frame rate. (90000/1001 = 89.91 works best for ATSC material).
You might try something similar based on the frame rate of your source
material.

-- Mark





More information about the Openchrome-users mailing list