Jump to content
  • Advertisement
Sign in to follow this  

[sorted!] AVI exceptions & Win32 system memory overwrites

This topic is 4730 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is happening in old code that had been tested and running well. The application is a VFW app which loads .avi files and profiles decompressors for each .avi, profiling how fast each playback format will display for the source format. On to the problem. After profiling one particular .avi file, a Microsoft Video 1 file, the open file dialog begins to fail during creation. Basically, the OPENFILENAME struct is filled out with the necessary information, and GetOpenFileName is called. It only fails in that instance, which makes me believe some type of memory corruption is going on... but since I can't trace into system DLLs, I can't seem to find the problem. Calling CommDlgExtendedError() after GetOpenFileName() fails usually returns a 2 (CDERR_INITIALIZATION) or the general CDERR_DIALOGFAILURE. Occasionally, it WILL pop up an open file dialog... but it is corrupted; the file filter is messed up, and only a few folders and items show up in the listview. --- I'm using Paul Nettle's memory manager, and it doesn't seem to be able to root out the problem. The problem occurs in both Debug and Release mode. --- Q: How to find this memory corruption... and why might it occur with just the one video file type? I guess tracing the program's flow over the entire profiling procedure might turn up something... but what might be a good technique for discovering the corruption as it occurs-- or is that possible? -- Thanks for your time. Chad [Edited by - Verg on June 8, 2005 5:42:05 PM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Lord Maz
What exactly do you do with the OPENFILENAME object? Some code would be nice.


None of the data members of OPENFILENAME change; GetOpenFileName works up until the point as described. The error has nothing to do with the OPENFILENAME struct.

As stated, this is not a simple problem. The code for the open file dialog has worked for three years... there have been no direct modifications to the open file dialog code.

But... here's exactly what you want. You'll see there's nothing out of the ordinary:


ofn.lStructSize = 76
ofn.hwndOwner = 0x000103e4
ofn.hInstance = 0x00400000
ofn.lpstrFilter = "AVI files (*.avi)"
ofn.lpstrCustomFilter = 0x00000000
ofn.nMaxCustFilter = 0
ofn.nFilterIndex = 1
ofn.lpstrFile = ""
ofn.nMaxFile = 260
ofn.lpstrFileTitle = ""
ofn.nMaxFileTitle = 0
ofn.lpstrInitialDir = 0x00000000
ofn.lpstrTitle = ""
ofn.Flags = 524804
ofn.nFileOffset = 3
ofn.nFileExtension = 19
ofn.lpstrDefExt = ".avi"
ofn.lCustData = 0
ofn.lpfnHook = 0x00000000
ofn.lpTemplateName = 0x00000000



The data is absolutely no different than for when the open file dialog works. Again... it's nothing to do (apparently) with the OPENFILENAME struct.

Thanks.

Share this post


Link to post
Share on other sites
Still going with this thing...

The IGetFrame com interface (PGETFRAME) is throwing two exceptions (access violations), which are caught, right as the .avi begins profiling. I suspect the access violations have something to do with the problem...

Don't know exactly how to handle the exceptions; will have to play with this some... suggestions welcome.

Not resolved yet...

Share this post


Link to post
Share on other sites
A little more info...

AVIStreamGetFrameOpen() returns the COM object interface pointer (PGETFRAME) and
then the code (eventually) tries to get a frame.

When AVIStreamGetFrameOpen() is called initially, it does so with one bitmap format (16 bit RGB)... and the IGetFrame::GetFrame() method returns frame data without throwing.

The PGETFRAME pointer is then reset when the next bitmap format comes up; RGB 24.
IGetFrame->End() (same as AVIStreamGetFrameClose()) is called, the pointer is set to zero... everything is fine.

AVIStreamGetFrameOpen() gets a pointer to a (new?) PGETFRAME interface; one which can decompress the AVI to RGB 24.

Up to this point, everything works fine.

But when IGetFrame::GetFrame() is called, the code throws-- twice. Two access violations, attempting to write.

The write-location (for the access violation) is unfamiliar to the program, near as I can tell; no pointer or object appears to occupy that space. I can only assume that space is occupied by system data.

---------

Handling the throws is no problem; am just indicating that there is no frame data, and that this particular format (RGB 24) is unavailable. Seems kind of buggy that AVIStreamGetFrameOpen() would return a valid IGetFrame interface pointer, which then would refuse to actually get a frame!

The problem (as stated before) is that something happens to application resources, and the OpenFileDialog doesn't show -- after the described function takes place.

----------

I'm scratching my head here; what's do be done, if AVIStreamGetFrameOpen() successfully returns an interface pointer, but the pointer causes an access violation when used?

Don't want to test for the "special case", where the fccHandler 'msvc' attempts to decompress Microsoft Video 1 to RGB 24, and then disallow it.

...

Arg.... operating system bugs are a pain [frown]

Thanks again.


Chad

Share this post


Link to post
Share on other sites
Problem has been sorted. Here's what happened:

Each AVI is tested by attempting to decompress to standard formats (RGB 16/RGB 24/YUY 16/etc...)... and each decompressor on your machine is used to test each format. In the end, you have a list of formats, and decompression speeds for each decompressor/format combination.

When the next video format to be tested was being set, in the Win32-specific subclass of "VideoStreamFormatFinder", the BITMAPINFO struct member "biSizeImage" wasn't being calculated correctly. The image, in this case was 320 x 480 pixels, and 24 bit... meaning three bytes per pixel... or 506880 bytes total.

For some unknown reason, (stupidity? [grin] ) , the ORIGINAL format's bit depth (the format of the compressed AVI on disk) was being used to calculate the biSizeImage...

Naturally, if you decompress from a 16-bit image to a 24-bit image, you need more space!!

---

But the really interesting thing is that: most all other decompressors (apparently) ignore the biSizeImage field, because this process had worked when decompressing other types of .avi files... even ones where the biSizeImage exceeded the original.

Because of how Microsoft wrote their fccHandler "msvc", actually using the biSizeImage to (apparently) set up memory for IGetFrame::GetFrame(), the way the code was written made it fail.

---------

If everyone who wrote fccHandlers for video de/compressors would just do things the same way, I would have found this two years ago [grin] ... LMAO...

Sorry for the trouble; and thanks for reading. Mostly typed this out for future reference (and others who have the same trouble).

---

THE OFFENDING LINE:


// offensive!!

destbitmapinfo->bmiHeader.biSizeImage = (double(originalinfo->bmiHeader.biWidth * originalinfo->bmiHeader.biHeight) * (double(originalinfo->bmiHeader.biBitCount) / 8));

// defensive!!

destbitmapinfo->bmiHeader.biSizeImage = (double(originalinfo->bmiHeader.biWidth * originalinfo->bmiHeader.biHeight) * (double(destbitmapinfo->bmiHeader.biBitCount) / 8));




Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!