Solved

Quicktime in MFC:  Getting AccessViolation/first-chance exception

Posted on 2001-08-20
19
418 Views
Last Modified: 2013-11-20
I gave up trying to search this site for related questions -- decided to just ask my own Q and see if I get a response.  I am pretty desperate for help.

I am working on a form-view based application that loads Quicktime movies and rtf files.  I am able to load and display the text files in a RichEditCtrl with no problems.  I can load a single-frame movie repeatedly with no problems, using both a hand-rolled QT-wrapper class and a commercial ActiveX QT player.  

The problem is, when I load the 'real' videos, I get a fairly consistent access violation.  The way the program works is it switches between 3 modes -- text, sign-language video, and animation video (both in QT format).  After loading a few videos and/or switching between text and video mode, it almost always crashes (running in Debug mode).

I had been optimistic that using a commercial QT player would solve the problem, but it did not help.  When the crash occurs, the call stack always shows the following:

KERNEL32! bff7a606()
WINMM! bfdf67f1()
KERNEL32! bff958f8()
00737472()

And VC++ always breaks into disassembly garbage that I can't decipher.

I have set breakpoints up the wazoo trying to isolate what sets it off, but it seems to happen after any of my code is run.  Obviously memory is being overwritten somewhere and it doesn't crash until a bit later, and it seems to be related to opening movie files, but how can I isolate it further? (And ultimately fix it?)

Thanks in advance for any help or suggestions..
--aejones
0
Comment
Question by:aejones
  • 9
  • 5
  • 3
  • +2
19 Comments
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
Do you have example code? - it would take the experts some time to recreate your scenario and it ould be quicker if you could do that and post it to anyone who asks
0
 
LVL 2

Author Comment

by:aejones
Comment Utility
Good idea.  I will post the relevant functions in separate comments.

The functions I think are related to the bug are:

LoadVideo(CString):  loads a QT file given its filename

LoadText(CString):  loads an RTF file given its filename

OnBtnASL():  sets up controls on screen for sign-lang vid, calls LoadVideo()

OnBtnAnim():  sets up controls on screen for animation vid, calls LoadVideo()

OnBtnText():  sets up controls on screen for RTF file, calls LoadText()

(function bodies to follow)
0
 
LVL 2

Author Comment

by:aejones
Comment Utility
void CDMCReview::LoadVideo(CString strFilename)
{
     CString strFullFilename, strPath, strTemp, strDefaultVidFile;
     char buff[3];

     // check to see if the target file exists
     HANDLE hFileHandle;    
     WIN32_FIND_DATA FindFileData;

     strFullFilename = m_strMediaPath;
     strFullFilename += "\Lesson_";  
     strFullFilename += (CString)itoa(m_nCurrLesson + 1, buff, 10);
     strFullFilename += (CString)"\\";
     strFullFilename += strFilename;

     strDefaultVidFile = m_strMediaPath;
     strDefaultVidFile +="\\noVid.mov";

     m_txtCurrFile.SetWindowText(strFilename);

     hFileHandle = ::FindFirstFile((LPCTSTR)strFullFilename, &FindFileData);
     bool fileFound = (hFileHandle != INVALID_HANDLE_VALUE);
     ::FindClose(hFileHandle);
     
     m_btnRepeat.EnableWindow(TRUE);

     if(fileFound)
     {
          m_ctrlSkyVid.SetFileName(strFullFilename);
     }
     else
     {
          CString err = "Video file ";
          err + strFullFilename;
          err += " not found!";
          AfxMessageBox(err, 0, 0);
          m_ctrlSkyVid.SetFileName(strDefaultVidFile);
     }
     
     m_ctrlSkyVid.Play();

}
0
 
LVL 2

Author Comment

by:aejones
Comment Utility
void CDMCReview::LoadText(CString strFilename)
{
     char buff[3];
     CString strMsg, strErr, strDefaultTxt;
      CString strCurrFile, strFullPath;
     CString strCurrIndex, strCurrPart;

     m_ctrlSkyVid.ShowWindow(SW_HIDE);

     m_txtSystem.ShowWindow(SW_HIDE);
     m_imgReviewBanner.ShowWindow(SW_SHOW);
     m_ctrlPresentText.ShowWindow(SW_SHOW);

     strFullPath = m_strMediaPath;  
 
     // set up default text file for missing resource...
     strDefaultTxt = strFullPath;
     strDefaultTxt += "noTxt.rtf";    

     strFullPath += "Lesson_";

     if (m_bRevMode)
          strFullPath += itoa(m_nCurrLesson, buff, 10);
     else
          strFullPath += itoa((m_nCurrLesson + 1), buff, 10);
     strFullPath += "\\";
     strFullPath += strFilename;

      // determine if file is present
      HANDLE hFileHandle;
      WIN32_FIND_DATA fd;
      hFileHandle = ::FindFirstFile((LPCTSTR)strFullPath, &fd);
      bool FileExists = (hFileHandle != INVALID_HANDLE_VALUE);
      ::FindClose(hFileHandle);
 
      CFile cFile;
 
      if(FileExists)
     {
           cFile.Open((LPCTSTR)strFullPath, CFile::modeRead);
     }
      else          
     {
          CString strErr = "Error:  Missing file: ";
          strErr += strFilename;
          AfxMessageBox(strErr, 0, 0);
          cFile.Open((LPCTSTR)strDefaultTxt, CFile::modeRead);
     }

     m_txtCurrFile.SetWindowText(strFilename);
     

     EDITSTREAM es;
      es.dwCookie = (DWORD) &cFile;
      es.pfnCallback = PullTextFromFileRev;

     // Turn word wrap on - based on window width
     m_ctrlPresentText.SetTargetDevice(NULL, 1);
     
      m_ctrlPresentText.StreamIn(SF_RTF, es);
}
0
 
LVL 2

Author Comment

by:aejones
Comment Utility
void CDMCReview::OnBtnAnim()
{
     CString strFilename;

     m_ctrlSkyVid.Stop();

     m_imgReviewBanner.ShowWindow(SW_HIDE);
     m_txtSystem.ShowWindow(SW_HIDE);
     m_ctrlPresentText.ShowWindow(SW_HIDE);
     m_ctrlSkyVid.ShowWindow(SW_SHOW);  

     m_btnRepeat.EnableWindow(TRUE);
     m_btnText.EnableWindow(TRUE);
     m_btnAnim.EnableWindow(FALSE);   // they should not be able to push this again...
     m_btnASL.EnableWindow(TRUE);
     m_bSeenAnim = true;
     m_btnText.SetCheck(0);
     m_btnASL.SetCheck(0);

     m_btnContinue.EnableWindow(TRUE);

     // load current Anim item
     strFilename = LookupTriplet(m_nCurrLesson, m_nCurrCluster, m_nCurrTriplet, m_bRevMode, 'N');
     LoadVideo(strFilename);
}

Note:  This function is nearly identical to OnBtnASL() and OnBtnText()...if you need the specifics on those other 2, let me know and I will post them as well.
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
what is m_ctrlSkyVid ?
0
 
LVL 2

Author Comment

by:aejones
Comment Utility
It's an ActiveX control that loads the videos.  (Skylight control downloaded from a 3rd party site -- www.skylight.ie).  

Previously, I was using a 'hand-rolled' QT wrapper class written by a former colleague -- but I replaced it recently with the Skylight control thinking the homemade control may have been the culprit, perhaps not allocating or releasing memory properly.  Since replacing it had no visible impact on the bug, it either means the problem is related to the underlying QT library classes (since they both rely on these), or that the problem is not directly related to the movie loading mechanism...


0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
are you using the demo? It says that the demo control is limited on the number of files you can open - wild guess here
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 2

Author Comment

by:aejones
Comment Utility
I am currently using the demo, but it happens before the 10-file maximum is reached.  It was also occurring before, using the homemade QT wrapper class to load the videos.

Besides, it would be pretty bad PR if, after exceeding the number of files allowed, it simply crashed the entire program...(and occasionally brought down my entire machine), don't you think?  ;-)

Thanks for the updated link, btw...
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
> , it would be pretty bad PR

yup :) as I said wild guess
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
One way to attack:  
Isolate it so that only the video is at issue -- that is, stub out all of the text-screen related fns and see if the problem continues.

Next tack:
Spinkle a bunch of TRACE statements around to see how far things go before the crash
TRACE("calling LoadVideo\r\n");
TRACE("Starting playback\r\n");
TRACE("Stopping playback\r\n");
TRACE("unloading the video\r\n");
etc.

I also see that you are not checking return (error?) codes from calls such as m_ctrlSkyVid.Stop(); and Play() and LookupTriplet (whatever that is).

It might be that the video activeX has not completely shutdown playback when you start to play again.  Are there some events you can trap to ensure that playback is stopped before calling Play()?

-- Dan
0
 
LVL 2

Author Comment

by:aejones
Comment Utility
Thanks for the comments...I will try adding TRACE statements, and checking the return codes from the video control functions.  

I am sure playback is shutdown before calling Play again because I manually call m_ctrlSkyVid.Stop().  I have looked at the documentation for the control itself and for the Quicktime libraries and this should be fine.  
0
 
LVL 2

Author Comment

by:aejones
Comment Utility
Thanks again for the suggestions.  I tried using TRACE statements, but that isolated it down to something that made no sense -- the call to SkyVid.SetFileName().  Since the bug was happening before I introduced the SkyVid control, this seemed to confirm my earlier suspicion that something was getting corrupted earlier on.

I decided to use HeapAgent (an interactive mem error debug tool) to try to figure out where the corruption might be occurring...but strangely enough, it did not pick up the bug -- in fact, it did not occur at all when running through HA!

I removed HeapAgent from my system to see if the bug returned, and so far it has not...even in Release mode.

I'm cautiously optimistic (but still somewhat paranoid about the problem's pretty random appearance and disappearance).  For now I think I will keep this question open for a while in case the bug comes back...at least in that case there will be a record of the problem here.

In the meantime, DanRollins, I will post points for you in the CS area because your suggestions were helpful (good general debugging strategies that I'm sure I will use in the future).

--aej
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Thanks aejones.

CS deleted your "Points for DanROllins" question.  I'd prefer them in MFC section anyway.

Incidently, if the error is related to the filename, it might help to use code like:

void CDMCReview::LoadVideo( LPCSTR szFilename)
{
    CString strFilename= szFilename;
...

This is the normal way for a function to "recieve" a CString --- they are only rarely passed as a CString (perhaps a CString& or a CString* ...);

Also, I don't know the SkyVid interface, but there is a chance that it is not making a copy of the filename and that it relies on you passing a persistant buffer.  That would cause unpredictable results like you have seen.

Since the problem is no longer reproducible, these theories are hard to test.  However, code such as

    static char szFile[255];
    strcpy(szFile, strFuleFilename);
    m_ctrlSkyVid.SetFileName( szFile );

...would be one avenue of approach.

-- Dan
0
 
LVL 2

Author Comment

by:aejones
Comment Utility
OK, there is now a points-question for you in the MFC area.  (Sorry, it had been a while since I participated in EE and I had forgotten the standard protocol...) :-)

Regarding your comments about passing CStrings by value, I think you may be mistaken there...

This is the 3rd program in a suite of similar products, each of which contains at least a hundred functions accepting CString arguments.  Never had a problem as a result.

There is an interesting discussion of CStrings on CodeGuru:

http://www.codeguru.com/string/CStringInANutshell.shtml

Thanks again for your comments!
--aej
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
after downloading from
  http://www.skylark.ie/skylight/index.htm
I see that in the MFC demo, they use code such as:

TCHAR szFile[256];
...
m_ctlSkyLight1.SetFileName(szFile);

strcpy( szFile, m_ctlSkyLight1.GetFileName() );
e = m_ctlSkyLight1.GetErrorCode();

When QuickTime is not installed, (or perhaps when the file is not found), the return code is 0 (no error) and szFile ends up as "".  

The fact that they placed this code (the call to GetFileName) into the demo is an implied suggestion that checking the filename after SetFileName is good idea:

if( !fileFound ) {
   CString sErr;
   sErr.Format( "Video file %s not found", (LPCSTR)strFullFilename );
   AfxMessageBox( sErr );
   strFullFilename= strDefaultVidFile;
}
m_ctrlSkyVid.SetFileName(strFullFilename);
CString sTmp= m_ctrlSkyVid.GetFileName();
ASSERT( sTmp != "" );

=-=-=-=-=-=-=-=-=-
>>passing CStrings by value, I think you may be mistaken there...

That is a good, informative article.  But when passing a CString by value, the CString copy ctor needs to be called, which is possibly somewhat less efficient than using the LPCSTR cast (which boils down to passing a pointer directly to the data)

Why doesn't MFC itself use this technique (passing CString by value to any of its class members)?  Perhaps it is legacy code from when CString was a less robust class.  Or perhaps they want to avoid that call to InterlockedDecrement and thereby avoid some thread-safety issues.

However, having seen the SkyLight wrapper code, I agree that it is unlikely that your problem is related to persistance of the filename.

-- Dan
0
 
LVL 23

Expert Comment

by:Roshan Davis
Comment Utility
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

PAQ'd and pts refunded

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Roshan Davis
EE Cleanup Volunteer
0
 
LVL 1

Accepted Solution

by:
Computer101 earned 0 total points
Comment Utility
PAQed, with points refunded (300)

Computer101
E-E Admin
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now