View Full Version : Infinite loop in dgdecode?
mimungr
10th November 2005, 20:54
I'm using VirtualDubMod 1.5.10.2, AVISynth 2.5.6, and DGMPGDec 1.4.5. When seeking about in VDM, the app hangs with the CPU pegged. There's also a lot of disk activity. I've let it sit for several minutes, and it doesn't recover. I attached a debugger and broke in randomly several times, and it was always in dgdecode.dll.
I've used DGMPGDec extensively without issue, so it must be something peculiar about this movie. It's a mainstream Hollywood release: Reefer Madness: The Movie Musical (R1).
I was able to repro with version 1.4.3 as well.
I'm able to play the movie straight through. I've only hit the hang when seeking about in VDM.
I uploaded a sample to neuron2's FTP server: infinite_loop.vob. Sorry about the size, but the nature of the repro makes it difficult to isolate the specific frames causing the problem.
Repro steps:
1) It's a hard telecine, so I ran DGIndex with honor pulldown flags. I'm pretty sure all my other settings are defaults.
2) I used a two line AVS script:
LoadPlugin("C:\Program Files\GordianKnot\AviSynthPlugins\dgdecode.dll")
mpeg2source("C:\Video\Scratch\test\test.d2v")
3) Open the AVS script in VDM and drag the slider back and forth. It should lock up within seconds.
If you can point me at symbols, I can get you a stack trace and verify that it's not returning control to AVS. If I find time, I may take a crack at compiling dgdecode to generate my own symbols.
Thanks.
mimungr
11th November 2005, 01:53
I built dgdecode.dll to get the symbols. It's stuck in this loop at vfapidec.cpp(688):
// Start decoding. Stop when the requested frame is decoded.
// First get the starting I frame of the GOP.
HadI = 0;
while (true)
{
if (!Get_Hdr())
{
// Something is really messed up.
return;
}
Decode_Picture(dst);
if (picture_coding_type == I_TYPE) HadI = 1;
if (picture_structure != FRAME_PICTURE)
{
Get_Hdr();
Decode_Picture(dst);
}
if (HadI) break;
}
To repro, you can just jump to frame number 6307.
Guest
11th November 2005, 06:15
I have duplicated the issue and will investigate.
A workaround for now is to demux the video and then make the project from the M2V file. Note that this affects only random navigation; a straight-through encode will be OK.
Thank you for your concise and accurate trouble report, and for your VOB that allows me to duplicate this issue.
Guest
11th November 2005, 14:44
Try this:
HadI = 0;
while (true)
{
if (!Get_Hdr())
{
// Something is really messed up.
return;
}
Decode_Picture(dst);
if (picture_coding_type == I_TYPE) HadI = 1;
if (picture_structure != FRAME_PICTURE)
{
Get_Hdr();
Decode_Picture(dst);
if (picture_coding_type == I_TYPE) HadI = 1;
}
if (HadI) break;
} If you confirm that as a fix, I will release a new beta.
Guest
12th November 2005, 03:13
That's a very interesting problem. It's quite technical but I'll explain it for those MPEG2 junkies that might be interested.
This is a field structure clip so we have:
top field picture
bottom field picture
top field picture <---
bottom field picture
top field picture
bottom field picture
...
Now, suppose I want to index the arrowed picture above. For program streams (of which VOB is one), I index the previous pack start code. But we have this in this clip:
pack start
bottom field picture (P)
top field picture (I) <---
bottom field picture (P)
...
So the code loop cited above in the thread sees a bottom field P picture first and thus fails the test to set HadI. Then it decodes another picture because it is field structure and encounters the top field I picture, but that decode has no test to set HadI. That causes the hang.
Normally this would never happen because pictures are usually bigger than one pack. But in this case it was at a static scene. And of course field pictures are smaller than frame pictures. And the bottom field was a P and not an I. A really bad congruence of factors!
We can't just add the HadI test for the second picture decode in the loop because we would exit the loop out of sync by one field, i.e., we should exit with a top and bottom field decoded and expecting a top next, but we'd have done a bottom and then a top, so instead of having a top coming next as we should, we'd have a bottom.
Unfortunately MPEG2 syntax doesn't give you a direct way to determine if a field is the first one of a frame pair for field structure. They should have used the top_field_first flag, IMHO.
I made a fix by using the Second_Field variable. I reset it to 0 whenever a sequence header or gop header is encountered. Then I test it and decide whether an extra field picture needs to be decoded. So, in this case, after the spurious bottom field picture is decoded, the Second_Field variable gets reset to 0, allowing me to know that I am out of sync by a field. (We could get really unlucky and not have an intervening SH or GH. In that case I don't know what to do, other than just ensure that it doesn't hang, even though we'd still be out by a field.)
The fix works fine for the linked VOB. I want to do a lot of regression testing before releasing this, however.
By indexing the demuxed M2V you finesse the problem because you index the headers directly and not the pack start codes.
If anyone can think of a better solution, please let me know.
EDIT: Another idea is to record the field order as seen at the most recent SH and assume that is still valid. That would handle the cases where there is no intervening SH or GH. I'll try that as it sounds like a better fix.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.