[mythtv] Patch to fix motion jitter problems with VSYNC interrupt video synchronisation

Terry Barnaby terry1 at beam.ltd.uk
Mon Sep 20 04:25:27 EDT 2004


Hi Isaac,

I send you this patch for information, I'm not sure if this is a correct
fix not
being up with the inner workings of the MythTv video synchronisation.
However, it does work well for me, without this the picture has quite bad
motion jitter.

Terry


Terry Barnaby wrote:

> Hi All,
>
> A Bit more looking at this.
> I note in the DRMVideoSync::WaitForFrame() function the number of
> vsync interrupts to wait for is calculated as:
>    blank.request.sequence = (int)(ceil((double)m_delay / 
> m_refresh_interval));
>
> If you are running, as I am, with an incoming frame rate of 25Hz and
> a VSYNC rate of 50Hz then m_delay will be almost exactly 
> (m_refresh_interval * 2)
> and the number of VSYNC's to wait for will be 2.
> If m_delay ends up slighty more than (m_refresh_interval * 2) then the 
> ceil()
> function will make the number of VSYNC's to wait for 3. On the next frame
> m_delay will be set much smaller to compensate for the 3 * VSYNC delay
> and the number of VSYNC's to wait for will be 1. Thus we get a cycle of
> 3,1,3,1,3,1 VSYNC waits leading to display jitter.
>
> If a round() function is used in place of the ceil() this will settle 
> the VSYNC's
> correctly to the closest value, 2 in this case.
> So changing the above code line to:
>
>    blank.request.sequence = (int)(round((double)m_delay / 
> m_refresh_interval));
>
> Cures the motion jitter, at least in my case.
> This has all be done with the KeepPhase() code removed. Adding this 
> yields
> a large degree of motion jitter as the VSYNC periods choosen will move 
> and
> I get a VSYNC wait sequence of something like:
> 1,3,1,2,3,2,2,2,2,1,2.
> I still, having read a mail thread on this issue, do not understand why
> the KeepPhase() code has been included .....
>
> I enclose a patch that I am using to fix the VSYNC jitter, that works 
> well for me.
>
> Terry
>
>
> Terry Barnaby wrote:
>
>> Hi All,
>>
>> Further to my problems with MythTv 0.16 and large amounts of
>> picture motion jitter, I have added some instrumentation code
>> to look at the timings of Frame display. The following
>> lists the output and the insrumentation code used.
>> I believe it shows that there is quite a problem with the MythTv Video
>> sync when VSYNC interrupt is used.
>> I have not delved any further yet ....
>>
>> My System:
>> M10000 Via system running Fedora Core 2.
>> Kernel 2.6.7 with DRM from CVS date 2004-9-12.
>> Unichrome Via X driver from CVS 2004-9-16, AGP-DMA enabled
>> Unichrome Via libXvMC library from CVS 2004-9-16
>> MythTv from CVS + XvMC QMatrix mods.
>> Connected to PAL TV running with 50Hz VSYNC
>>
>>
>> Using RTC timeing
>> =======================================
>> Here the picture quality is fine.
>> FrameTime:  40.04ms Diff:   0.04ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.06ms Diff:   0.06ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  39.07ms Diff:  -0.93ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.09ms Diff:   0.09ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.04ms Diff:   0.04ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.11ms Diff:   0.11ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  39.96ms Diff:  -0.04ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.03ms Diff:   0.03ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.05ms Diff:   0.05ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.05ms Diff:   0.05ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.04ms Diff:   0.04ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>> FrameTime:  40.05ms Diff:   0.05ms PeakDiff:  40.13ms 
>> VsyncAdjust:      0
>>
>>
>> Using VSYNC interrupt with KeepPhase
>> =======================================
>> Here the picture motion is very jumpy.
>> VSyncWait: Refresh:  16650 MDelay:  19348 VBlank: 2
>> FrameTime:  40.01ms Diff:   0.01ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  17304 VBlank: 2
>> FrameTime:  40.03ms Diff:   0.03ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  14961 VBlank: 1
>> FrameTime:  19.99ms Diff: -20.01ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  33377 VBlank: 3
>> FrameTime:  60.01ms Diff:  20.01ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  11294 VBlank: 1
>> FrameTime:  20.01ms Diff: -19.99ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  29399 VBlank: 2
>> FrameTime:  40.00ms Diff:   0.00ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  27391 VBlank: 2
>> FrameTime:  40.02ms Diff:   0.02ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  25371 VBlank: 2
>> FrameTime:  40.00ms Diff:  -0.00ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  39794 VBlank: 3
>> FrameTime:  60.04ms Diff:  20.04ms PeakDiff:  60.04ms VsyncAdjust:  
>> 16650
>> VSyncWait: Refresh:  16650 MDelay:  17494 VBlank: 2
>> FrameTime:  39.98ms Diff:  -0.02ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  15767 VBlank: 1
>> FrameTime:  20.01ms Diff: -19.99ms PeakDiff:  60.04ms 
>> VsyncAdjust:      0
>>
>>
>>
>> Using VSYNC interrupt without KeepPhase
>> =======================================
>> Here the picture motion is fine
>> FrameTime:  40.00ms Diff:   0.00ms PeakDiff:  59.96ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  31159 VBlank: 2
>> FrameTime:  40.01ms Diff:   0.01ms PeakDiff:  59.96ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  30834 VBlank: 2
>> FrameTime:  40.03ms Diff:   0.03ms PeakDiff:  59.96ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  31129 VBlank: 2
>> FrameTime:  39.99ms Diff:  -0.01ms PeakDiff:  59.96ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  31099 VBlank: 2
>> FrameTime:  40.00ms Diff:   0.00ms PeakDiff:  59.96ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  31055 VBlank: 2
>> FrameTime:  40.01ms Diff:   0.01ms PeakDiff:  59.96ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  30740 VBlank: 2
>> FrameTime:  40.01ms Diff:   0.01ms PeakDiff:  59.96ms 
>> VsyncAdjust:      0
>>
>>
>> Perodically changes to
>> ======================
>> Here the picture motion is slightly jumpy
>> VSyncWait: Refresh:  16650 MDelay:  33428 VBlank: 3
>> FrameTime:  60.01ms Diff:  20.01ms PeakDiff:  20.09ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  13170 VBlank: 1
>> FrameTime:  20.00ms Diff: -19.99ms PeakDiff:  20.09ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  33393 VBlank: 3
>> FrameTime:  60.01ms Diff:  20.01ms PeakDiff:  20.09ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  13222 VBlank: 1
>> FrameTime:  20.01ms Diff: -19.99ms PeakDiff:  20.09ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  33389 VBlank: 3
>> FrameTime:  60.01ms Diff:  20.01ms PeakDiff:  20.09ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  13312 VBlank: 1
>> FrameTime:  20.01ms Diff: -19.99ms PeakDiff:  20.09ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  33382 VBlank: 3
>> FrameTime:  60.01ms Diff:  20.02ms PeakDiff:  20.09ms 
>> VsyncAdjust:      0
>> VSyncWait: Refresh:  16650 MDelay:  13284 VBlank: 1
>> FrameTime:  20.00ms Diff: -20.00ms PeakDiff:  20.09ms 
>> VsyncAdjust:      0
>>
>>
>> Instrumentation Code
>> ====================
>> --- 
>> /src/homeSys/devel/MythTv/mythtv_0.16/mythtv_cvs/libs/libmythtv/NuppelVideoPlayer.cpp    
>> 2004-09-13 07:09:23.000000000 +0100
>> +++ NuppelVideoPlayer.cpp    2004-09-19 09:29:47.000000000 +0100
>> @@ -1194,6 +1194,15 @@
>>     }
>> }
>>
>> +// Get current time in seconds
>> +double getTime()
>> +{
>> +    struct timeval    tp;
>> +   +    gettimeofday(&tp, NULL);
>> +    return ((double) tp.tv_sec + (double) tp.tv_usec * 1e-6);
>> +}
>> +
>> void NuppelVideoPlayer::AVSync(void)
>> {
>>     float           diverge;
>> @@ -1233,6 +1242,35 @@
>>         }
>>
>>         videosync->WaitForFrame(avsync_adjustment);
>> +
>> +#ifndef BEAM_ZAP
>> +{
>> +static double lastTime = 0.0;
>> +static double peak = 0.0;
>> +static int    c = 0;
>> +double    tnow = 0.0;
>> +double    d = 0.0;
>> +double    da = 0.0;
>> +
>> +    print_verbose_messages = VB_IMPORTANT | VB_PLAYBACK;
>> +
>> +    tnow = getTime();
>> +    if(lastTime > 0.0){
>> +        d = (tnow - lastTime) - (1.0 / 25.0);
>> +        da = fabs(d);
>> +        if(da > peak)
>> +            peak = da;
>> +    }
>> +//    printf("Raw: %4.4f Abs: %4.4f\n", (tnow - lastTime) - (1.0 / 
>> 25.0), fabs((tnow - lastTime) - (1.0 / 25.0)));
>> +    printf("FrameTime: %6.2fms Diff: %6.2fms PeakDiff: %6.2fms 
>> VsyncAdjust: %6d\n", (tnow - lastTime) * 1000, d * 1000, peak * 1000, 
>> avsync_adjustment);
>> +    lastTime = tnow;
>> +    c++;
>> +    if(c > 200){
>> +        peak = 0;
>> +        c = 0;
>> +    }
>> +}
>> +#endif
>>         avsync_adjustment = 0;
>>
>>         // Display the frame
>> --- 
>> /src/homeSys/devel/MythTv/mythtv_0.16/mythtv_cvs/libs/libmythtv/vsync.cpp    
>> 2004-08-28 19:45:34.000000000 +0100
>> +++ vsync.cpp    2004-09-19 09:43:11.342518473 +0100
>> @@ -276,10 +282,13 @@
>>         blank.request.type = DRM_VBLANK_RELATIVE;
>>         blank.request.sequence =
>>             (int)(ceil((double)m_delay / m_refresh_interval));
>> +printf("VSyncWait: Refresh: %6d MDelay: %6d VBlank: %d\n", 
>> m_refresh_interval, m_delay, blank.request.sequence);
>>         drmWaitVBlank(m_dri_fd, &blank);
>>     }
>>
>> +#ifdef BEAM_ZAP
>>     KeepPhase();
>> +#endif
>>        UpdateNexttrigger();
>> }
>>
>>
>> Terry Barnaby wrote:
>>
>>> Hi,
>>>
>>> I have got a bit further on this issue.
>>> In MythTv the frame sync system, has changed quite a bit and is
>>> now performed in the vsync.c file. This now chooses what
>>> it thinks is the best timing system to use.
>>> On the Via M10000 system the vsync algorithem chooses to
>>> use the DRM vsync interrupt system. This is fine by me (as I
>>> added the VSYNC Interrupt :) ), but it appears to cause
>>> frame output instability. If you disable the DRM vsync interrupt
>>> system (comment out in VideoSync::BestMethod()) so that MythTv uses
>>> the linux RTC, all looks much better.
>>>
>>> Delving into the DRM vsync interrupt system, there is a call
>>> to VideoSync::KeepPhase() in DRMVideoSync::WaitForFrame().
>>> This seems to be the root of the problem. Remove this and
>>> things appear fine (I am at work viewing on a VGA monitor rather
>>> than PAL TV). With KeepPhase() the peak discrepancy in
>>> the frame display time is around 26ms and without it it is
>>> around 10ms. I note that the Vsync interrupt at work is
>>> 60Hz when connected to a VGA screen with my X-Server mode lines.
>>>
>>> The code in VideoSync::KeepPhase() doesn't seem right to me ...
>>>
>>> void VideoSync::KeepPhase()
>>> {
>>>     // Keep our nexttrigger from drifting too close to the exact 
>>> retrace.
>>>     // If delay is near zero, some frames will be delay < 0 and others
>>>     // delay > 0 which would cause continous rapid fire stuttering.
>>>     // This method is only useful for those sync methods where 
>>> WaitForFrame
>>>     // targets hardware retrace rather than targeting nexttrigger.
>>>
>>>     // cerr << m_delay << endl;
>>>     if (m_delay < -(m_refresh_interval/2))
>>>         OffsetTimeval(m_nexttrigger, 200);
>>>     else if (m_delay > -500)
>>>         OffsetTimeval(m_nexttrigger, -2000);
>>> }
>>>
>>>
>>> Terry
>>>
>>> Terry Barnaby wrote:
>>>
>>>> Hi All,
>>>>
>>>> I have just had a chance to look at the motion "artifacts" problem
>>>> with using the latest Via XvMc MPEG Decoding with MythTv.
>>>>
>>>> There is a large amount of motion jitter on the display. I have
>>>> narrowed this down to some problem with MythTv 0.16 CVS.
>>>>
>>>> My System:
>>>> M10000 Via system running Fedora Core 2.
>>>> Kernel 2.6.7 with DRM from CVS date 2004-9-12.
>>>> Unichrome Via X driver from CVS 2004-9-16, AGP-DMA enabled
>>>> Unichrome Via libXvMC library from CVS 2004-9-16
>>>> MythTv from CVS + XvMC QMatrix mods.
>>>>
>>>> My Tests:
>>>> 1. Using MythTv 0.16 CVS there is a large amount of jitter both using
>>>>     the Via XvMc MPEG Decoding and the internal software decode
>>>>     with Xv display output.
>>>>     I am unable to turn on Vertical sync mode with 0.16, it seems
>>>>     to have been removed (experemental AV sync).
>>>>
>>>> 2. Using MythTv 0.15.1 the display looks good with both the Via XvMc
>>>>     MPEG Decoding and the internal software decode with Xv display
>>>>     output. Using Via XvMc MPEG decoding CPU usage is about 12%.
>>>>     If I enable Vertical sync mode the picture quality is still
>>>>     very good, but additionally when a jump forward in the video
>>>>     is performed (cursor right key) the display restarts quickly
>>>>     and cleanly. Without Vertical sync mode there is a period of
>>>>     about 3 seconds of display sluggishness.
>>>>
>>>> So the motion jitter problem seems to be an issue with a new
>>>> synchronisation scheme in MythTv. Note I am running MythTv as root
>>>> still so the Real-time mode is enabled.
>>>>
>>>> The Chroma QMatrix code does not seem to have made much difference
>>>> that I can see as yet, but I have been focassing on the motion 
>>>> problems ....
>>>>
>>>> I will investigate further today.
>>>>
>>>> Terry
>>>>
>>>>
>>>> ------------------------------------------------------------------------ 
>>>>
>>>>
>>>> _______________________________________________
>>>> mythtv-dev mailing list
>>>> mythtv-dev at mythtv.org
>>>> http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev
>>>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------ 
>>>
>>>
>>> _______________________________________________
>>> mythtv-dev mailing list
>>> mythtv-dev at mythtv.org
>>> http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev
>>>  
>>>
>>
>>
>> -------------------------------------------------------
>> This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
>> Project Admins to receive an Apple iPod Mini FREE for your judgement on
>> who ports your project to Linux PPC the best. Sponsored by IBM.
>> Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php
>> _______________________________________________
>> Unichrome-devel mailing list
>> Unichrome-devel at lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/unichrome-devel
>>
>------------------------------------------------------------------------
>
>--- /src/homeSys/devel/MythTv/mythtv_0.16/mythtv_cvs/libs/libmythtv/vsync.cpp	2004-08-28 19:45:34.000000000 +0100
>+++ mythtv-0.16.test_vsync/libs/libmythtv/vsync.cpp	2004-09-19 14:30:05.532400639 +0100
>@@ -274,12 +280,20 @@
>     {
>         drm_wait_vblank_t blank;
>         blank.request.type = DRM_VBLANK_RELATIVE;
>+#ifdef BEAM_ZAP
>         blank.request.sequence =
>             (int)(ceil((double)m_delay / m_refresh_interval));
>+#else
>+        blank.request.sequence =
>+            (int)(round((double)m_delay / m_refresh_interval));
>+
>+#endif
>         drmWaitVBlank(m_dri_fd, &blank);
>     }
> 
>+#ifdef BEAM_ZAP
>     KeepPhase();
>+#endif
>     
>     UpdateNexttrigger();
> }
>  
>
>------------------------------------------------------------------------
>
>_______________________________________________
>mythtv-dev mailing list
>mythtv-dev at mythtv.org
>http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev
>  
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mythtv-cvs-vsync-2.patch
Type: text/x-patch
Size: 579 bytes
Desc: not available
Url : http://mythtv.org/pipermail/mythtv-dev/attachments/20040920/5ceda14e/mythtv-cvs-vsync-2.bin


More information about the mythtv-dev mailing list