On Thu, 24 Mar 2005, I wrote:
we may arrive at WaitForFrame just at nexttrigger, or *just* after it. Believe me, when we're desperately trying to keep up with rendering 1080i, this is not an uncommon occurrance in my experience. :-)
To support this statement, I just quickly re-instrumented vsync.cpp where I had added the return, and this is a sample of what I was talking about when viewing 1080i video:
2005-03-24 21:45:47.628 WaitForFrame: we were 34 usecs late 2005-03-24 21:46:02.776 WaitForFrame: we were 316 usecs late 2005-03-24 21:46:02.826 WaitForFrame: we were 2067 usecs late 2005-03-24 21:46:03.414 WaitForFrame: we were 5598 usecs late 2005-03-24 21:47:00.479 WaitForFrame: we were 20 usecs late 2005-03-24 21:47:03.115 WaitForFrame: we were 20 usecs late 2005-03-24 21:47:04.783 WaitForFrame: we were 33 usecs late 2005-03-24 21:47:14.109 WaitForFrame: we were 26 usecs late 2005-03-24 21:47:23.201 WaitForFrame: we were 19 usecs late 2005-03-24 21:47:23.552 WaitForFrame: we were 17530 usecs late 2005-03-24 21:47:23.601 WaitForFrame: we were 16040 usecs late 2005-03-24 21:47:23.619 WaitForFrame: we were 477 usecs late 2005-03-24 21:47:23.634 WaitForFrame: we were 706 usecs late 2005-03-24 21:47:24.774 WaitForFrame: we were 5954 usecs late 2005-03-24 22:14:36.040 WaitForFrame: we were 17 usecs late 2005-03-24 22:14:36.624 WaitForFrame: we were 17 usecs late 2005-03-24 22:14:38.410 WaitForFrame: we were 356 usecs late 2005-03-24 22:14:42.261 WaitForFrame: we were 33721 usecs late 2005-03-24 22:14:42.279 WaitForFrame: we were 18324 usecs late 2005-03-24 22:14:42.381 WaitForFrame: we were 19036 usecs late 2005-03-24 22:14:43.680 WaitForFrame: we were 18 usecs late 2005-03-24 22:14:43.797 WaitForFrame: we were 18569 usecs late 2005-03-24 22:14:43.815 WaitForFrame: we were 3203 usecs late 2005-03-24 22:36:29.798 WaitForFrame: we were 56 usecs late 2005-03-24 22:36:40.491 WaitForFrame: we were 7521 usecs late 2005-03-24 22:36:41.075 WaitForFrame: we were 17 usecs late
I eliminated some large lateness entries in order to reduce clutter. I'll admit they were there though.
What do you mean? Doctoring the output does not help support anything. In looking at this output, this appears to be a 'straddle' event where this retrace and trigger times are so close together that they may fall on either side from one frame to the next. The fact that several times seem to center around ~20 leads me to believe that you've hacked out some even more important fixes in KeepPhase() that force the trigger time to be at least 500ms away from the refresh time so that this doesn't occur. Each time it is less than 500 it should shift by 2000 which should have occurred on the second line. If you've broken this then that is the cause of the problem you show here.
[upon further review of the timestamps, there is nothing even remotely like a sequence of frames and only a couple consecutive frames. Some of these are minutes, up to a half-hour apart. What the hell is this? What should anyone conclude about your credibility by posting this as an example of something?]
If I'm really just missing the point, please set me straight. :-)
Back to your earlier claim, lateness for the first time cannot be a result of waiting for the next available retrace. The only way the next available is retrace is after the target retrace is if we've already missed the target retrace but I'm getting ahead of myself. I hadn't replied to you previous message yet.
Andy Poling wrote:
On Thu, 24 Mar 2005, Bruce Markey wrote:
With retrace info, we target the next retrace after the trigger. We're not necessarily late just because delay passed 0. Returning ASAP can result in frame updating early. In fact, a few lines later we have a subtle but important fix to handle this situation. See: http://mythtv.org/pipermail/mythtv-commits/2004-September/004234.html http://cvs.mythtv.org/cgi-bin/viewcvs.cgi/mythtv/libs/libmythtv/vsync.cpp?sortby=file&r2=1.6&r1=1.5
Normally, prepareframe has finished it's business well before delay reaches 0 and none of this is an issue. However, if there were other processes running or disk O/I to wait for or whatever, we sometimes may not reach this point until after zero.
retrace A-v delay=0-v retrace B-v retrace C-v ------------------------------------------------------------------ prepareframe--^wait-------------------^ # This would be normal =). prepareframe-------------^ASAP^ # Opps! early prepareframe-------------^wait--------^ # Good prepareframe------------------------------------^ASAP^ # Bail!
// Always sync to the next retrace except when we are very late. if (m_delay > -(m_refresh_interval/2))
"Very late" is deliberate here. If we're less than half of a refresh interval after 0, it is more probable that we are still ahead of the target retrace and should wait for it. Even if the retrace was shortly after 0 and we did miss it, we've already missed our turn anyway.
If it has been more than half of a refresh interval after 0 (more than half could be 3X), it is most probable that we've already missed and need to bail ASAP. If it is more than half a refresh and the next refresh hasn't hit yet, it can't be that much later so we can't be very early and may not cause a glitch at all in this rare circumstance.
OK - this is good because it helps me better understand what you're trying to do.
No, I don't think you understand any more than you did before I had sent this. You took a cursory look at something you didn't understand and guessed that it was wrong. In fact, your hack is simply a regression to the incorrect behavior before an important fix that resolved a cause of jitter.
Here's my understanding of what's going on here. m_nexttrigger is designed to (once things have stabilized) indicate the time when we would have to begin to Show in order to complete rendering before the frame is to be retraced. Am I right on this so far?
Absolutely not. It's the hypothetical best time for the video image timing to align with the audio stream. However, the framebuffer needs to update when the signal to the TV set is ready to start a new field. If anything, nexttrigger represents the earliest time that the frame update should be allowed to occur. The target retrace is the first one after nexttrigger. By definition, there is always a gap in time between nexttrigger and the target retrace.
Here's what I (thought I) saw happening. When playing high-res video (think 1080i), we are ordinarily just barely able to complete PrepareFrame in time to beat nexttrigger.
It doesn't need to 'beat' nexttrigger, it needs to be ready in time for the next retrace after nexttrigger. If the frame is not prepared by the time that retrace is due, then nothing short of a time machine will fix the frame timing.
As the code stands now, WaitForFrame would then force us to wait an entire frame.
It never waits for an 'entire frame'. Only when it is less than half of a refresh cycle and after the trigger, it waits for the next refresh cycle which should be the one that it was supposed to have been waiting for if the code had reached this point before the trigger anyway. If we didn't reach this point before the retrace, the glitch already occurred anyway. If it is more than half a refresh after the trigger time it returns ASAP anyway.
The only time it would wait for the refresh (not frame) after the target would be if prepareframe finished late but by less than 1/2 refresh and the next refresh was unusually close to nexttringger and came before prepareframe finished. Well, in this case the glitch already occurred when prepareframe didn't finish in time. Pushing the following frame back one refresh would actually put it at the correct interval after the previous frame but in practice, the following frame(s) would be found to be late and return ASAP until it caught up again. The point is that in the rare case where it would wait one refresh after the target refresh, it would not cause a timing miss but, in fact, could only happen as a result of a timing miss that already happened.
This caused two apparent visible problems (to my eye):
1) the interlaced frames get inverted (are now out of order) if we wait one retrace interval
No. There is no deinterlacer currently in myth that combines the bottom field of one frame with the top for the next where the 'inverted' problem can occur. Bob line doubles top then bottom then top of the next frame so they are always sequentially forward in time. All other deinterlacers act on full frames and move sequentially forward.
If you are using bob, what you are seeing is that with bob, you will see horizontal bobbing when there are glitches in the frame timing.
2) a visible and audible pause in playback, accompanied by a complaint from the decoding code about a "prebuffering pause".
A prebuffer pause is the result of there not being enough frames decoded for the player to continue until there are more frames available. This pause is not a result of frame timing and having enough decoded frames ready is an entirely separate issue from frame timing when frames are available. Updating the video card framebuffer prematurely is in certain specific circumstances is not a solution to whatever caused it.
Maybe I'm mis-understanding something fundamental,
Obviously you have and I can't mask my disappointment that you disregarded (or at best didn't grasp) just about everything in my previous post.
but the logic behind my change was this: if we arrive just after m_nexttrigger, it's impossible that we're early.
Dead wrong. Nexttrigger is always before that target retrace. Delay = 0 is always early. Not only did I spell this out, I drew a diagram.
Bottom line is that nothing is changing here without hard quantifiable proof of a correct hypothesis.
-- bjm _______________________________________________ mythtv-dev mailing list [email protected] http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev
