AVICAPTURE.CPP
Upload User: nthssl
Upload Date: 2022-04-05
Package Size: 25357k
Code Size: 5k
Category:

OpenCV

Development Platform:

Visual C++

  1. // AVICapture.cpp: implementation of the AVICapture class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "3DEditor.h"
  6. #include "AVICapture.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. AVICapture::AVICapture() :
  16.     width(-1),
  17.     height(-1),
  18.     frameRate(30.0f),
  19.     frameCounter(0),
  20.     capturing(false),
  21.     aviFile(NULL),
  22.     aviStream(NULL),
  23.     compAviStream(NULL),
  24.     image(NULL)
  25. {
  26.     AVIFileInit();
  27. }
  28. AVICapture::~AVICapture()
  29. {
  30.     cleanup();
  31.     AVIFileExit();
  32. }
  33. bool AVICapture::start(CString filename,
  34.                        int w, int h,
  35.                        float fps)
  36. {
  37.     if (capturing)
  38.         return false;
  39.     width = w;
  40.     height = h;
  41.     frameRate = fps;
  42.     if (HIWORD(VideoForWindowsVersion()) < 0x010a)
  43.     {
  44.         // We need to be running on version 1.1 or later
  45.         return false;
  46.     }
  47.     // Compute the width of a row in bytes; pad so that rows are aligned on
  48.     // 4 byte boundaries.
  49.     int rowBytes = (width * 3 + 3) & ~0x3;
  50.     image = new unsigned char[rowBytes * height]; 
  51.     HRESULT hr = AVIFileOpen(&aviFile,
  52.                              filename,
  53.                              OF_WRITE | OF_CREATE,
  54.                              NULL);
  55.     if (hr != AVIERR_OK)
  56.     {
  57.         MessageBox(NULL,"Erroring creating avi file for capture.","ERROR",MB_OK);
  58.         return false;
  59.     }
  60.     AVISTREAMINFO info;
  61.     ZeroMemory(&info, sizeof info);
  62.     info.fccType = streamtypeVIDEO;
  63.     info.fccHandler = 0;
  64.     info.dwScale = 1;
  65.     info.dwRate = (DWORD) frameRate;
  66.     info.dwSuggestedBufferSize = rowBytes * height;
  67.     SetRect(&info.rcFrame, 0, 0, width, height);
  68.     hr = AVIFileCreateStream(aviFile, &aviStream, &info);
  69.     if (hr != AVIERR_OK)
  70.     {
  71.         MessageBox(NULL,"Error creating AVI stream.","ERROR",MB_OK);
  72.         cleanup();
  73.         return false;
  74.     }
  75.     // Display a dialog to allow the user to select compression options
  76.     AVICOMPRESSOPTIONS options;
  77.     AVICOMPRESSOPTIONS* arrOptions[1] = { &options };
  78.     ZeroMemory(&options, sizeof options);
  79.     if (!AVISaveOptions(NULL, 0, 1, &aviStream, 
  80.                         (LPAVICOMPRESSOPTIONS*) &arrOptions))
  81.     {
  82.         // The user either clicked on cancel or there was an error
  83.         cleanup();
  84.         return false;
  85.     }
  86.     hr = AVIMakeCompressedStream(&compAviStream, aviStream, &options, NULL);
  87.     if (hr != AVIERR_OK)
  88.     {
  89.         MessageBox(NULL,"Error creating compressed AVI stream.", "ERROR",MB_OK);
  90.         cleanup();
  91.         return false;
  92.     }
  93.     BITMAPINFOHEADER bi;
  94.     ZeroMemory(&bi, sizeof bi);
  95.     bi.biSize = sizeof bi;
  96.     bi.biWidth = width;
  97.     bi.biHeight = height;
  98.     bi.biPlanes = 1;
  99.     bi.biBitCount = 24;
  100.     bi.biCompression = BI_RGB;
  101.     bi.biSizeImage = rowBytes * height;
  102.     bi.biXPelsPerMeter = 0;
  103.     bi.biYPelsPerMeter = 0;
  104.     bi.biClrUsed = 0;
  105.     bi.biClrImportant = 0;
  106.     hr = AVIStreamSetFormat(compAviStream, 0, &bi, sizeof bi);
  107.     if (hr != AVIERR_OK)
  108.     {
  109.         MessageBox(NULL,"AVIStreamSetFormat failed.","ERROR",MB_OK);
  110.         cleanup();
  111.         return false;
  112.     }
  113.     capturing = true;
  114.     frameCounter = 0;
  115.     return true;
  116. }
  117. bool AVICapture::end()
  118. {
  119.     capturing = false;
  120.     cleanup();
  121.     return true;
  122. }
  123. bool AVICapture::captureFrame()
  124. {
  125.     if (!capturing)
  126.         return false;
  127.     // Get the dimensions of the current viewport
  128.     int viewport[4];
  129.     glGetIntegerv(GL_VIEWPORT, viewport);
  130.     int x = viewport[0] + (viewport[2] - width) / 2;
  131.     int y = viewport[1] + (viewport[3] - height) / 2;
  132.     glReadPixels(x, y, width, height,
  133.                  GL_BGR_EXT, GL_UNSIGNED_BYTE,
  134.                  image);
  135.     int rowBytes = (width * 3 + 3) & ~0x3;
  136.     LONG samplesWritten = 0;
  137.     LONG bytesWritten = 0;
  138.     HRESULT hr = AVIStreamWrite(compAviStream,
  139.                                 frameCounter,
  140.                                 1,
  141.                                 image,
  142.                                 rowBytes * height,
  143.                                 AVIIF_KEYFRAME,
  144.                                 &samplesWritten,
  145.                                 &bytesWritten);
  146.     if (hr != AVIERR_OK)
  147.     {
  148.         MessageBox(NULL,"AVIStreamWrite failed on frame.", "ERROR",MB_OK);
  149.         return false;
  150.     }
  151.     // printf("Writing frame: %d  %d => %d bytesn",
  152.     //        frameCounter, rowBytes * height, bytesWritten);
  153.     frameCounter++;
  154.     return true;
  155. }
  156. void AVICapture::cleanup()
  157. {
  158.     if (aviStream != NULL)
  159.     {
  160.         AVIStreamRelease(aviStream);
  161.         aviStream = NULL;
  162.     }
  163.     if (compAviStream != NULL)
  164.     {
  165.         AVIStreamRelease(compAviStream);
  166.         compAviStream = NULL;
  167.     }
  168.     if (aviFile != NULL)
  169.     {
  170.         AVIFileRelease(aviFile);
  171.         aviFile = NULL;
  172.     }
  173.     if (image != NULL)
  174.     {
  175.         delete[] image;
  176.         image = NULL;
  177.     }
  178. }
  179. int AVICapture::getWidth() const
  180. {
  181.     return width;
  182. }
  183. int AVICapture::getHeight() const
  184. {
  185.     return height;
  186. }
  187. float AVICapture::getFrameRate() const
  188. {
  189.     return frameRate;
  190. }