61 #define BI_I420 0x30323449
62 #define BI_YUY2 0x32595559
77 #define myClip(x) (((x) > 255) ? 255 : ((x) < 0) ? 0 : (unsigned char) (x))
78 static inline void yuv2rgb(
unsigned char y,
unsigned char u,
unsigned char v,
unsigned char *out)
81 int D = (int) u - 128;
82 int E = (int) v - 128;
84 int R = (( 298 * C + 409 * E + 128) >> 8);
85 int G = (( 298 * C - 100 * D - 208 * E + 128) >> 8);
86 int B = (( 298 * C + 516 * D + 128) >> 8);
101 return (LRESULT) TRUE;
104 pCapturedImage->
pixels = (
unsigned char *) lpVHdr->lpData;
108 return (LRESULT) TRUE;
126 m_nDriverIndex = nDriverIndex;
129 m_bCameraOpened =
false;
131 for (
int i = 0; i < 1024; i++)
132 m_clip[i] = i < 256 ? i : 255;
143 DestroyWindow(m_hCaptureWnd);
164 m_hCaptureWnd = capCreateCaptureWindow(
"Capture Window", 0, 0, 0, 640, 480, NULL, 0);
169 if (!capSetCallbackOnFrame(m_hCaptureWnd,
CallbackProc))
171 DestroyWindow(m_hCaptureWnd);
178 if (!capDriverConnect(m_hCaptureWnd, m_nDriverIndex))
180 DestroyWindow(m_hCaptureWnd);
187 capOverlay(m_hCaptureWnd, FALSE);
188 capPreview(m_hCaptureWnd, FALSE);
191 s.dwRequestMicroSecPerFrame = 41667;
192 s.fMakeUserHitOKToCapture = FALSE;
193 s.wPercentDropForError = 10;
195 s.dwIndexSize = 34952;
196 s.wChunkGranularity = 0;
197 s.fUsingDOSMemory = FALSE;
198 s.wNumVideoRequested = 10;
199 s.fCaptureAudio = FALSE;
201 s.vKeyAbort = VK_ESCAPE;
202 s.fAbortLeftMouse = FALSE;
203 s.fAbortRightMouse = FALSE;
204 s.fLimitEnabled = FALSE;
206 s.fMCIControl = FALSE;
210 s.fStepCaptureAt2x = FALSE;
211 s.wStepCaptureAverageFrames = 1;
212 s.dwAudioBufferSize = 0;
213 s.fDisableWriteCache = FALSE;
214 s.AVStreamMaster = AVSTREAMMASTER_NONE;
216 capCaptureSetSetup(m_hCaptureWnd, &s,
sizeof(CAPTUREPARMS));
219 m_bCameraOpened =
true;
230 capDriverDisconnect(m_hCaptureWnd);
236 m_bCameraOpened =
false;
243 char szVersion[1000];
245 if (!capGetDriverDescription(nDriverIndex, szName,
sizeof(szName), szVersion,
sizeof(szVersion)))
258 CAPDRIVERCAPS gCapDriverCaps;
261 if (m_hCaptureWnd && capDriverGetCaps(m_hCaptureWnd, &gCapDriverCaps,
sizeof(CAPDRIVERCAPS)))
263 if (gCapDriverCaps.fHasDlgVideoFormat)
265 capDlgVideoFormat(m_hCaptureWnd);
275 CAPDRIVERCAPS gCapDriverCaps;
278 if (m_hCaptureWnd && capDriverGetCaps(m_hCaptureWnd, &gCapDriverCaps,
sizeof(CAPDRIVERCAPS)))
280 if (gCapDriverCaps.fHasDlgVideoSource)
282 capDlgVideoSource(m_hCaptureWnd);
288 void CVFWCapture::UpdateInformation()
292 BITMAPINFO bitmapInfo;
294 if (m_hCaptureWnd && capGetVideoFormat(m_hCaptureWnd, &bitmapInfo,
sizeof(BITMAPINFO)))
296 m_nWidth = bitmapInfo.bmiHeader.biWidth;
297 m_nHeight = abs(bitmapInfo.bmiHeader.biHeight);
298 m_nBitsPerPixel = bitmapInfo.bmiHeader.biBitCount;
299 m_nCompression = bitmapInfo.bmiHeader.biCompression;
310 if (m_nCompression != BI_RGB && m_nCompression != BI_BITFIELDS)
312 printf(
"fourcc = %08x (%c%c%c%c)\n", m_nCompression, (m_nCompression >> 0) & 0xff, (m_nCompression >> 8) & 0xff, (m_nCompression >> 16) & 0xff, (m_nCompression >> 24) & 0xff);
319 if (bitmapInfo.bmiHeader.biHeight > 0)
329 pCapturedImage =
new CByteImage(m_nWidth, m_nHeight, m_type,
true);
337 capGrabFrameNoStop(m_hCaptureWnd);
342 if (!m_bCameraOpened || !m_hCaptureWnd || !ppImages || !ppImages[0] || m_nWidth != ppImages[0]->width || m_nHeight != ppImages[0]->height || m_type != ppImages[0]->type)
348 if (pCapturedImage && pCapturedImage->
pixels)
352 unsigned char *output = ppImages[0]->
pixels;
354 if (m_nCompression == BI_RGB)
356 if (m_nBitsPerPixel == 24)
358 const int nBytes = m_nWidth * m_nHeight * 3;
359 const unsigned char *input = pCapturedImage->
pixels;
361 for (
int i = 0; i < nBytes; i += 3)
363 output[i] = input[i + 2];
364 output[i + 1] = input[i + 1];
365 output[i + 2] = input[i];
369 else if (m_nCompression == BI_BITFIELDS)
371 printf(
"error: BI_BITFIELDS not yet implemented\n");
378 const int nBytes = m_nWidth * m_nHeight;
379 const unsigned char *inputY = pCapturedImage->
pixels;
380 const unsigned char *inputU = inputY + nBytes;
381 const unsigned char *inputV = inputU + nBytes / 4;
384 for (
int h = 0; h < m_nHeight; h += 1)
386 for (
int w = 0; w < m_nWidth; w += 1)
388 int j = (h / 2) * (m_nWidth / 2) + (w / 2);
389 yuv2rgb(inputY[i], inputU[j], inputV[j], &output[3 * i]);
394 else if (m_nCompression ==
BI_YUY2)
396 const int nBytes = m_nWidth * m_nHeight * 2;
397 const unsigned char *input = pCapturedImage->
pixels;
399 for (
int i = 0; i < nBytes; i += 4)
401 unsigned char y0 = *input++;
402 unsigned char u = *input++;
403 unsigned char y1 = *input++;
404 unsigned char v = *input++;
bool CopyImage(const CByteImage *pInputImage, CByteImage *pOutputImage, const MyRegion *pROI=0, bool bUseSameSize=false)
Copies one CByteImage to another.
static void yuv2rgb(unsigned char y, unsigned char u, unsigned char v, unsigned char *out)
void ShowVideoSourceDialog()
static CByteImage * pCapturedImage
bool FlipY(const CByteImage *pInputImage, CByteImage *pOutputImage)
Flips the rows in a CByteImage vertically and writes the result to a CByteImage.
bool GetDriverName(int nDriverIndex, std::string &sName)
void ShowVideoFormatDialog()
static LRESULT CALLBACK CallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)
CRITICAL_SECTION critical_section
ImageType type
The type of the image.
CVFWCapture(int nDriverIndex)
bool CaptureImage(CByteImage **ppImages)
unsigned char * pixels
The pointer to the the pixels.
Data structure for the representation of 8-bit grayscale images and 24-bit RGB (or HSV) color images ...