0
votes

I am writing an application with a very simple purpose: Select a directory full of Bitmaps and create an AVI video. I am using René Nyffenegger's "Avi.cpp/Avi.h" source code to add the bmp frames to the AVI file. I am using the header "dirent.h" to "stream" the file names into my application.So far, and with a few minor bugs, the application works very well, except when working with a directory containing several thousand Bitmap files. The Bitmaps are identical except for name and pixel content, so I am a little bit confused. Here is the code snippet from inside the loop that writes the Bitmaps to the AVI file.

DIBSECTION dibs;
Bitmap bmp(bmpFileName.c_str());//Bitmap object created from filename
int sbm = ::GetObject(bmp,sizeof(dibs),&dibs);//size of bmp object

if(sbm != sizeof(DIBSECTION))
{
    //error reading Bitmap file
    //code to quit writing frames
    //there will be an error writing the frame to the avi file if this is the case
}
else
{
  //code to add frame to AVI file
}

I have a cout in the console that tells me when every 5th frame has been written to the AVI file, just so I can keep track. Right around the 2950th frame (different every time), it enters the error section of the "if" statement. I can verify by setting breakpoints that the Bitmap file name is correct. I have also tried the following "while" loop to see if re-initializing the Bitmap over and over again would eventually return a good value to sbm:

DIBSECTION dibs;
Bitmap bmp(bmpFileName.c_str());//Bitmap object created from filename
int sbm = ::GetObject(bmp,sizeof(dibs),&dibs);//size of bmp object

while(sbm != sizeof(DIBSECTION))
{
  Bitmap tryAgain(bmpFileName.c_str());
  sbm = ::GetObject(bmp,sizeof(dibs),&dibs);//size of bmp object
  if(sbm == sizeof(DIBSECTION))
  {
    bmp = tryAgain;
  }

}

//code to add frame to AVI file

Eventually this while loop will work, and the frame will be added to the AVI file, but the same thing will happen with the next file, and the next, and the next, adding loads of time to the otherwise rather quick process. I will summarize:

-Purpose is to create AVI file by using Bitmap files as frames, read from a directory -The program works perfectly until about the 2950th file in the directory -At this point, the Bitmap object is invalid even though it has been initialized with a string that points to a valid file on the hard drive (just like all the previous ones). -Using a while loop, I can eventually create a valid Bitmap object, but it adds way too much time for the application to be practical.

I am looking for some insight as to why this happens around the 2950th file in the directory. Is there some way around it, and/or a better library/header to use for this purpose? I have very little formal programming training, as is probably evident in my code/approach, but I appreciate the help.

1
Are you running out of memory / handles? Do you free resources are you go along? - Yetti99
Also possible: memory corruption due to writing past the end of an array, writing to dead pointers, ignoring errors... - Mooing Duck
Most likely you are not calling ::DeleteObject() when you should, that is you are leaking GDI objects. - rodrigo
Rodrigo, thank you. that fixed it. I usually rely on the fact that objects are destroyed out of scope, but I failed to recognize that this was happening in scope, being the frame-adding loop. I will definitely use this in the future, and I think I can use it to improve some of my other programs. - DensoEngineer

1 Answers

0
votes

Credit to rodrigo for the fix! Using:

::DeleteObject(bmp);

after adding every frame resulted in the memory usage staying under 10,000K (viewed in task manager). I'm sure I can clean it up elsewhere too and make it use even less memory.