moviemaker.cpp

Go to the documentation of this file.
00001 
00032 //  ===============================================
00033 //  MovieMaker.cpp
00034 //  ===============================================
00035 
00036 #include "llviewerprecompiledheaders.h"
00037 
00038 #include "moviemaker.h"
00039 #include <memory>
00040 #include "llmemtype.h"
00041 
00042 #if LL_WINDOWS
00043 
00044 #include <windowsx.h>
00045 
00046 HANDLE  MakeDib( HBITMAP hbitmap, UINT bits );
00047 HBITMAP LoadBMPFromFB( int w, int h );
00048 
00049 /*
00050     ===============================================
00051         Constructors, Destructor
00052     ===============================================
00053 */
00054 
00055 
00056 MovieMaker::MovieMaker()
00057 {
00058     snprintf( fname, sizeof(fname), "movie.avi" );              /* Flawfinder: ignore */
00059     width  = -1;
00060     height = -1;
00061 
00062     bOK = true;
00063     nFrames = 0;
00064 
00065         pfile = NULL;
00066         ps = NULL;
00067         psCompressed = NULL;
00068         psText = NULL;
00069         aopts[0] = &opts;
00070 
00071     // Check VFW version.
00072         WORD wVer = HIWORD( VideoForWindowsVersion() );
00073         if ( wVer < 0x010A )
00074         {
00075         fprintf( stderr, "VFW version is too old.\n" );
00076         exit( -1 );
00077             }
00078         else
00079             {
00080                 AVIFileInit();
00081             }
00082 }
00083 
00084 
00085 MovieMaker::~MovieMaker()
00086 {
00087         if (ps)
00088                 AVIStreamClose(ps);
00089 
00090         if (psCompressed)
00091                 AVIStreamClose(psCompressed);
00092 
00093         if (psText)
00094                 AVIStreamClose(psText);
00095 
00096         if (pfile)
00097         {
00098                 AVIFileClose(pfile);
00099         }
00100 
00101         WORD wVer = HIWORD(VideoForWindowsVersion());
00102         if (wVer >= 0x010A)
00103             {
00104                 AVIFileExit();
00105             }
00106 }
00107 
00108 void MovieMaker::StartCapture( char *name , int x, int y)
00109 {
00110     strncpy( fname, name, sizeof(fname) -1 );           /* Flawfinder: ignore */
00111     fname[sizeof(fname) -1] = '\0';
00112 
00113     // Get the width and height.
00114     width = x;
00115     height = y;
00116 
00117     fprintf( stderr, "Starting %d x %d capture to file: %s\n", width, height, fname );
00118 
00119         bOK = TRUE;
00120 
00121         nFrames = 0;
00122 
00123 }
00124 
00125 void MovieMaker::EndCapture()
00126 {
00127     fprintf( stderr, "\n" );
00128         if (ps)
00129         {
00130                 AVIStreamClose(ps);
00131         ps = NULL;
00132         }
00133 
00134         if (psCompressed)
00135         {
00136                 AVIStreamClose(psCompressed);
00137         psCompressed = NULL;
00138         }
00139 
00140         if (psText)
00141         {
00142                 AVIStreamClose(psText);
00143         psText = NULL;
00144         }
00145 
00146         if (pfile)
00147         {
00148                 AVIFileClose(pfile);
00149         pfile = NULL;
00150         }
00151 
00152         WORD wVer = HIWORD(VideoForWindowsVersion());
00153         if (wVer >= 0x010A)
00154             {
00155                 AVIFileExit();
00156             }
00157 
00158 }
00159 
00160 bool MovieMaker::Snap()
00161 {
00162         HRESULT hr;
00163 
00164         if (!bOK)
00165                 return false;
00166 
00167     // Get an image and stuff it into a bitmap.
00168     HBITMAP bmp;
00169     bmp = LoadBMPFromFB( width, height );
00170 
00171         LPBITMAPINFOHEADER alpbi = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(bmp, 32));
00172     DeleteObject( bmp );
00173 
00174         if (alpbi == NULL)
00175         {
00176         bOK = false;
00177                 return false;
00178         }
00179         if (width>=0 && width != alpbi->biWidth)
00180         {
00181                 GlobalFreePtr(alpbi);
00182         bOK = false;
00183                 return false;
00184         }
00185         if (height>=0 && height != alpbi->biHeight)
00186         {
00187                 GlobalFreePtr(alpbi);
00188         bOK = false;
00189                 return false;
00190         }
00191         width = alpbi->biWidth;
00192         height = alpbi->biHeight;
00193         if (nFrames == 0)
00194         {
00195                 hr = AVIFileOpenA(&pfile,                   // returned file pointer
00196                                fname,                                                   // file name
00197                                    OF_WRITE | OF_CREATE,                    // mode to open file with
00198                                    NULL);                                                       // use handler determined
00199                                                                                                         // from file extension....
00200                 if (hr != AVIERR_OK)
00201                 {
00202                         GlobalFreePtr(alpbi);
00203                         bOK = false;
00204                         return false;
00205                 }
00206                 _fmemset(&strhdr, 0, sizeof(strhdr));
00207                 strhdr.fccType                = streamtypeVIDEO;// stream type
00208                 strhdr.fccHandler             = 0;
00209                 strhdr.dwScale                = 1;
00210                 strhdr.dwRate                 = 15;
00211                 strhdr.dwSuggestedBufferSize  = alpbi->biSizeImage;
00212                 SetRect(&strhdr.rcFrame, 0, 0,              // rectangle for stream
00213                         (int) alpbi->biWidth,
00214                         (int) alpbi->biHeight);
00215 
00216                 // And create the stream;
00217                 hr = AVIFileCreateStream(pfile,             // file pointer
00218                                                          &ps,               // returned stream pointer
00219                                                                  &strhdr);          // stream header
00220                 if (hr != AVIERR_OK)
00221                 {
00222                         GlobalFreePtr(alpbi);
00223                         bOK = false;
00224                         return false;
00225                 }
00226 
00227                 _fmemset(&opts, 0, sizeof(opts));
00228 
00229                 if (!AVISaveOptions(NULL, ICMF_CHOOSE_KEYFRAME, 1, &ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
00230                 {
00231             fprintf( stderr, "AVISaveOptions failed.\n" );
00232                         GlobalFreePtr(alpbi);
00233                         bOK = false;
00234                         return false;
00235                 }
00236 
00237                 hr = AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL);
00238                 if (hr != AVIERR_OK)
00239                 {
00240             fprintf( stderr, "AVIMakeCompressedStream failed.\n" );
00241                         GlobalFreePtr(alpbi);
00242                         bOK = false;
00243                         return false;
00244                 }
00245 
00246                 hr = AVIStreamSetFormat(psCompressed, 0,
00247                                            alpbi,           // stream format
00248                                        alpbi->biSize +   // format size
00249                                        alpbi->biClrUsed * sizeof(RGBQUAD));
00250                 if (hr != AVIERR_OK)
00251                 {
00252             fprintf( stderr, "AVIStreamSetFormat failed.\n" );
00253                         GlobalFreePtr(alpbi);
00254                         bOK = false;
00255                         return false;
00256                 }
00257 
00258                 // Fill in the stream header for the text stream....
00259 
00260                 // The text stream is in 60ths of a second....
00261 /*
00262                 _fmemset(&strhdr, 0, sizeof(strhdr));
00263                 strhdr.fccType                = streamtypeTEXT;
00264                 strhdr.fccHandler             = mmioFOURCC('D', 'R', 'A', 'W');
00265                 strhdr.dwScale                = 1;
00266                 strhdr.dwRate                 = 60;
00267                 strhdr.dwSuggestedBufferSize  = sizeof(szText);
00268                 SetRect(&strhdr.rcFrame, 0, (int) alpbi->biHeight,
00269                         (int) alpbi->biWidth, (int) alpbi->biHeight + TEXT_HEIGHT);
00270 
00271                 // ....and create the stream.
00272                 hr = AVIFileCreateStream(pfile, &psText, &strhdr);
00273                 if (hr != AVIERR_OK)
00274                 {
00275                         GlobalFreePtr(alpbi);
00276                         bOK = false;
00277                         return false;
00278                 }
00279 
00280                 dwTextFormat = sizeof(dwTextFormat);
00281                 hr = AVIStreamSetFormat(psText, 0, &dwTextFormat, sizeof(dwTextFormat));
00282                 if (hr != AVIERR_OK)
00283                 {
00284                         GlobalFreePtr(alpbi);
00285                         bOK = false;
00286                         return false;
00287                 }
00288 */
00289         }
00290 
00291         // Now actual writing
00292         hr = AVIStreamWrite(psCompressed,       // stream pointer
00293                 nFrames * 1, // 10,                             // time of this frame
00294                 1,                              // number to write
00295                 (LPBYTE) alpbi +                // pointer to data
00296                         alpbi->biSize +
00297                         alpbi->biClrUsed * sizeof(RGBQUAD),
00298                         alpbi->biSizeImage,     // size of this frame
00299                 AVIIF_KEYFRAME,                  // flags....
00300                 NULL,
00301                 NULL);
00302         if (hr != AVIERR_OK)
00303         {
00304         fprintf( stderr, "AVIStreamWrite failed.\n" );
00305                 GlobalFreePtr(alpbi);
00306                 bOK = false;
00307                 return false;
00308         }
00309 
00310         // Make some text to put in the file ...
00311         //LoadString(hInstance, IDS_TEXTFORMAT, szMessage, BUFSIZE );
00312         /*
00313         strcpy(szMessage, "This is frame #%d");
00314                 
00315         int iLen = wsprintf(szText, szMessage, (int)(nFrames + 1));
00316 
00317         // ... and write it as well.
00318         hr = AVIStreamWrite(psText,
00319                         nFrames * 40,
00320                         1,
00321                         szText,
00322                         iLen + 1,
00323                         AVIIF_KEYFRAME,
00324                         NULL,
00325                         NULL);
00326         if (hr != AVIERR_OK)
00327         {
00328                 GlobalFreePtr(alpbi);
00329                 bOK = false;
00330                 return false;
00331         }
00332         */
00333         GlobalFreePtr(alpbi);
00334 
00335         nFrames++;
00336 
00337     fprintf( stderr, "Wrote frame %d.\r", nFrames );
00338 
00339         return true;
00340 }
00341 
00342 static HANDLE  MakeDib( HBITMAP hbitmap, UINT bits )
00343 {
00344         HANDLE              hdib ;
00345         HDC                 hdc ;
00346         BITMAP              bitmap ;
00347         UINT                wLineLen ;
00348         DWORD               dwSize ;
00349         DWORD               wColSize ;
00350         LPBITMAPINFOHEADER  lpbi ;
00351         LPBYTE              lpBits ;
00352         
00353         GetObject(hbitmap,sizeof(BITMAP),&bitmap) ;
00354 
00355         //
00356         // DWORD align the width of the DIB
00357         // Figure out the size of the colour table
00358         // Calculate the size of the DIB
00359         //
00360         wLineLen = (bitmap.bmWidth*bits+31)/32 * 4;
00361         wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<<bits : 0);
00362         dwSize = sizeof(BITMAPINFOHEADER) + wColSize +
00363                 (DWORD)(UINT)wLineLen*(DWORD)(UINT)bitmap.bmHeight;
00364 
00365         //
00366         // Allocate room for a DIB and set the LPBI fields
00367         //
00368         hdib = GlobalAlloc(GHND,dwSize);
00369         if (!hdib)
00370                 return hdib ;
00371 
00372         lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib) ;
00373 
00374         lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
00375         lpbi->biWidth = bitmap.bmWidth ;
00376         lpbi->biHeight = bitmap.bmHeight ;
00377         lpbi->biPlanes = 1 ;
00378         lpbi->biBitCount = (WORD) bits ;
00379         lpbi->biCompression = BI_RGB ;
00380         lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize ;
00381         lpbi->biXPelsPerMeter = 0 ;
00382         lpbi->biYPelsPerMeter = 0 ;
00383         lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
00384         lpbi->biClrImportant = 0 ;
00385 
00386         //
00387         // Get the bits from the bitmap and stuff them after the LPBI
00388         //
00389         lpBits = (LPBYTE)(lpbi+1)+wColSize ;
00390 
00391         hdc = CreateCompatibleDC(NULL) ;
00392 
00393         GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
00394 
00395         // Fix this if GetDIBits messed it up....
00396         lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
00397 
00398         DeleteDC(hdc) ;
00399         GlobalUnlock(hdib);
00400 
00401         return hdib ;
00402 }
00403 
00404 
00405 static HBITMAP LoadBMPFromFB( int w, int h )
00406 {
00407     // Create a normal DC and a memory DC for the entire screen. The 
00408     // normal DC provides a "snapshot" of the screen contents. The 
00409     // memory DC keeps a copy of this "snapshot" in the associated 
00410     // bitmap. 
00411  
00412     HDC hdcScreen = wglGetCurrentDC();
00413     HDC hdcCompatible = CreateCompatibleDC(hdcScreen); 
00414  
00415     // Create a compatible bitmap for hdcScreen. 
00416 
00417     HBITMAP hbmScreen = CreateCompatibleBitmap(hdcScreen, 
00418                            //  GetDeviceCaps(hdcScreen, HORZRES), 
00419                            //  GetDeviceCaps(hdcScreen, VERTRES)); 
00420                              w, 
00421                              h ); 
00422 
00423     if (hbmScreen == 0)
00424         {
00425         fprintf( stderr, "hbmScreen == NULL\nExiting.\n" );
00426         exit( -1 );
00427         //errhandler("hbmScreen", hwnd); 
00428         }
00429  
00430     // Select the bitmaps into the compatible DC. 
00431  
00432     if (!SelectObject(hdcCompatible, hbmScreen)) 
00433         {
00434         fprintf( stderr, "Couldn't SelectObject()\nExiting.\n" );
00435         exit( -1 );
00436         //errhandler("Compatible Bitmap Selection", hwnd); 
00437         }
00438  
00439     // Hide the application window. 
00440  
00441      //       ShowWindow(hwnd, SW_HIDE); 
00442  
00443     //Copy color data for the entire display into a 
00444     //bitmap that is selected into a compatible DC. 
00445  
00446     if (!BitBlt(hdcCompatible, 
00447                  0,0, 
00448                  w, h, 
00449                  hdcScreen, 
00450                 // 512,512,
00451                  0, 0,
00452                  SRCCOPY)) 
00453         {
00454         fprintf( stderr, "Screen to Compat Blt Failed\nExiting.\n" );
00455         exit( -1 );
00456         //errhandler("Screen to Compat Blt Failed", hwnd); 
00457         }
00458  
00459    // Redraw the application window.  
00460    //ShowWindow(hwnd, SW_SHOW); 
00461 
00462     DeleteDC( hdcCompatible );
00463 
00464     return( hbmScreen );
00465 }
00466 
00467 #elif LL_DARWIN
00468 
00469  #include <AGL/agl.h>
00470  #include <AGL/gl.h>
00471  #include <AGL/glu.h>
00472 
00473 // BAD Apple.  BAD!
00474 #ifdef verify
00475         #undef verify
00476 #endif
00477 
00478 #include "llviewerwindow.h"
00479 #include "llworld.h"
00480 
00481 MovieMaker::MovieMaker()
00482 {
00483         movie = NULL;
00484         movieResRef = 0;
00485         track = NULL;
00486         media = NULL;
00487         width = 0;
00488         height = 0;
00489         bufferSize = 0;
00490         rowBytes = 0;
00491         buffer = NULL;
00492         invertedBuffer = NULL;
00493         ci = NULL;
00494         gworld = NULL;
00495         idh = NULL;
00496 }
00497 
00498 MovieMaker::~MovieMaker()
00499 {
00500         EndCapture();
00501 }
00502 
00503 void MovieMaker::StartCapture( char *name , int x, int y)
00504 {
00505     strncpy( fname, name, sizeof(fname));               /* Flawfinder: ignore */
00506         width = x;
00507         height = y;
00508         
00509         setupMovie();
00510 }
00511 
00512 OSStatus MovieMaker::setupMovie()
00513 {
00514         OSStatus        error = noErr;
00515         FSRef           fileRef;
00516         FSSpec          fileSpec;
00517         
00518         rowBytes = width * 4;
00519         bufferSize = height * rowBytes;
00520         LLMemType mt(LLMemType::MTYPE_SCRIPT);
00521         buffer = (char*) new char(bufferSize);
00522         invertedBuffer = (char*) new char(bufferSize);
00523 
00524         rect.left = 0;
00525         rect.top = 0;
00526         rect.right = width;
00527         rect.bottom = height;
00528         
00529         error = NewGWorldFromPtr(&gworld, k32ARGBPixelFormat, &rect, 0, 0, 0, buffer, rowBytes);
00530 
00531         if (error == noErr)
00532         {
00533                 LockPixels(GetGWorldPixMap(gworld));
00534         }
00535 
00536 // MBW -- I think this needs to happen after all the dialogs, etc.      
00537 //      if (error == noErr)
00538 //      {
00539 //              Microseconds(&lastFrameTime);
00540 //              error = grabFrame();
00541 //      }
00542 
00543         if (error == noErr)
00544         {
00545                 error = EnterMovies();
00546         }
00547         
00548         if (error == noErr)
00549         {
00550                 ci = OpenDefaultComponent(StandardCompressionType,StandardCompressionSubType);
00551                 if(ci == NULL)
00552                         error = paramErr;
00553         }
00554                 
00555         if (error == noErr)
00556         {
00557                 long flags;
00558                 
00559                 SCGetInfo(ci,scPreferenceFlagsType,&flags);
00560                 flags &= ~scShowBestDepth;
00561                 flags |= scAllowZeroFrameRate;
00562                 SCSetInfo(ci,scPreferenceFlagsType,&flags);
00563         }
00564 
00565         if (error == noErr)
00566         {
00567                 send_agent_pause();
00568                 gViewerWindow->mWindow->beforeDialog();
00569 
00570                 error = SCRequestSequenceSettings(ci);
00571 
00572                 gViewerWindow->mWindow->afterDialog();
00573                 send_agent_resume();
00574 
00575                 if (error == scUserCancelled) 
00576                 {
00577                         // deal with user cancelling.
00578                         EndCapture();
00579                 }
00580         }
00581         
00582         if (error == noErr)
00583         {
00584                 // This is stoopid. I have to take the passed full path, create the file so I can get an FSRef, and Get Info to get the FSSpec for QuickTime. Could Apple make this any more difficult...
00585                 FILE* file = LLFile::fopen(fname, "w");         /* Flawfinder: ignore */
00586                 if (file)
00587                 {
00588                         fclose(file);
00589                         
00590                         error = FSPathMakeRef((UInt8*)fname, &fileRef, NULL);
00591                         if (error == noErr)
00592                                 error = FSGetCatalogInfo(&fileRef, 0, NULL, NULL, &fileSpec, NULL);
00593                 }
00594                 else
00595                 {
00596                         error = paramErr;
00597                 }
00598         }
00599         
00600         if (error == noErr)
00601         {
00602                 error = CreateMovieFile(&fileSpec, 'TVOD', smCurrentScript, createMovieFileDeleteCurFile | createMovieFileDontCreateResFile, &movieResRef, &movie);
00603         }
00604         
00605         if (error == noErr)
00606         {
00607                 track = NewMovieTrack(movie, FixRatio(width, 1), FixRatio(height, 1), kNoVolume);
00608                 error = GetMoviesError();
00609         }
00610         
00611         if (error == noErr)
00612         {
00613                 media = NewTrackMedia(track, VideoMediaType, 600, NULL, 0);
00614                 error = GetMoviesError();
00615         }
00616         
00617         if (error == noErr)
00618         {
00619                 Microseconds(&lastFrameTime);
00620                 error = grabFrame();
00621         }
00622 
00623         if (error == noErr)
00624         {
00625                 error = SCCompressSequenceBegin(ci,GetPortPixMap(gworld),nil,&idh);
00626         }
00627 
00628         if (error == noErr)
00629         {
00630                 error = BeginMediaEdits(media);
00631         }
00632         
00633         if (error != noErr)
00634         {
00635                 media = NULL;
00636         }
00637         
00638         return error;
00639 }
00640 
00641 void MovieMaker::EndCapture()
00642 {
00643         OSStatus        error = noErr;
00644 
00645         if (movie && movieResRef)
00646         {
00647                 if (media && track)
00648                 {
00649                         // Errors adding the frame aren't too important here.
00650                         (void)addFrame();
00651                         
00652                         error = EndMediaEdits(media);
00653                         if (error == noErr)
00654                         {
00655                                 error = SCCompressSequenceEnd(ci);
00656                         }
00657 
00658                         if (error == noErr)
00659                         {
00660                                 error = InsertMediaIntoTrack(track, 0, 0, GetMediaDuration(media), fixed1);
00661                         }
00662                         media = NULL;
00663                         track = NULL;
00664                 }
00665                 
00666                 short resId = movieInDataForkResID;
00667                 error = AddMovieResource(movie, movieResRef, &resId, "\pSecond Life");
00668                 CloseMovieFile(movieResRef);
00669                 movieResRef = 0;
00670                 movie = NULL;
00671         }
00672         
00673         // NOTE:  idh is disposed by SCCompressSequenceEnd.
00674         idh = NULL;
00675         
00676         if(ci)
00677         {
00678                 CloseComponent(ci);
00679                 ci = NULL;
00680         }
00681         
00682         if(gworld)
00683         {
00684                 DisposeGWorld(gworld);
00685                 gworld = NULL;
00686         }
00687 
00688         if(buffer)
00689         {
00690                 delete(buffer);
00691                 buffer = NULL;
00692         }
00693 
00694         if(invertedBuffer)
00695         {
00696                 delete(invertedBuffer);
00697                 invertedBuffer = NULL;
00698         }
00699 }
00700 
00701 OSStatus MovieMaker::grabFrame()
00702 {
00703         OSStatus        error = noErr;
00704         GLenum          glerr;
00705         
00706         // Grab a frome from GL
00707         glReadBuffer(GL_BACK);
00708         glReadPixels(0 ,0, width, height,  
00709 #ifdef LL_BIG_ENDIAN    
00710         // PowerPC Mac
00711         GL_BGRA,
00712         GL_UNSIGNED_INT_8_8_8_8_REV,
00713 #else                           
00714         // Intel Mac
00715         GL_BGRA,
00716         GL_UNSIGNED_INT_8_8_8_8,
00717 #endif  
00718         invertedBuffer);
00719         glerr = glGetError();
00720         
00721         // Invert the lines top to bottom
00722         if (glerr == GL_NO_ERROR)
00723         {
00724                 long i, j;
00725                 
00726                 i = j = 0;
00727                         
00728                 // Copy rows into tmp buffer one at a time, reversing their order
00729                 for (i = 0, j = bufferSize - rowBytes; i < bufferSize; i += rowBytes, j -= rowBytes)
00730                         BlockMoveData(&invertedBuffer[i], &buffer[j], rowBytes);
00731         }
00732         else
00733         {
00734                 error = paramErr;
00735         }
00736         
00737         return error;
00738 }
00739 
00740 OSStatus MovieMaker::addFrame()
00741 {
00742         OSStatus        error = noErr;
00743         Handle  compressedData;
00744         short   syncFlag;
00745         long    dataSize;
00746         UnsignedWide now;
00747 
00748         CGrafPtr oldPort;
00749         GDHandle oldGDeviceH;
00750 
00751         GetGWorld(&oldPort, &oldGDeviceH);
00752         SetGWorld(gworld, nil);
00753         
00754         // Compress the frame and add it to the movie
00755 
00756         error = SCCompressSequenceFrame(ci,GetPortPixMap(gworld),&rect,&compressedData,&dataSize,&syncFlag);
00757         
00758         Microseconds(&now);
00759 
00760         if (error == noErr)
00761         {
00762                 double duration = (now.lo - lastFrameTime.lo);  // duration in microseconds
00763                 duration *= GetMovieTimeScale(movie);   
00764                 duration *= 1.0 / 1000000.0;                            
00765 
00766                 error = AddMediaSample(
00767                                 media,
00768                                 compressedData,
00769                                 0,
00770                                 dataSize,
00771                                 (TimeValue)duration,
00772                                 (SampleDescriptionHandle)idh,
00773                                 1,
00774                                 syncFlag,
00775                                 nil);
00776                 
00777         }
00778 
00779         lastFrameTime = now;
00780 
00781         SetGWorld(oldPort, oldGDeviceH);
00782         
00783         return error;
00784 }
00785 
00786 bool MovieMaker::Snap()
00787 {
00788         bool    result = false;
00789         
00790         if (movie && movieResRef && media && track)
00791         {
00792                 OSStatus error = noErr;
00793                 
00794                 error = addFrame();
00795                 
00796                 if (error == noErr)
00797                 {
00798                         error = grabFrame();
00799                 }
00800 
00801                 if (error == noErr)
00802                 {
00803                         result = true;
00804                 }
00805         }
00806         
00807         return result;
00808 }
00809 
00810 #endif
00811 

Generated on Thu Jul 1 06:09:57 2010 for Second Life Viewer by  doxygen 1.4.7