DirectShow DirectShow Æ©Å丮¾ó »ùÇà grabberÀÇ »ç¿ë¹ý   [¸ñÂ÷¿­¶÷] [ÁÖ¼Òº¹»ç] [½½·Ôºñ¿ì±â]
»ùÇà grabberÀÇ »ç¿ë¹ý
 
Microsoft DirectX 9.0

»ùÇà grabberÀÇ »ç¿ë¹ý

»ùÇà grabber ÇÊÅÍ´Â º¯È¯ ÇÊÅÍ·Î, ÀÌ ÇÊÅ͸¦ »ç¿ëÇØ ½ºÆ®¸²ÀÌ ÇÊÅÍ ±×·¡ÇÁ¸¦ Åë°úÇÒ °æ¿ì¿¡ ½ºÆ®¸²À¸·ÎºÎÅÍ ¹Ìµð¾î »ùÇÃÀ» Æ÷ÂøÇÒ ¼ö ÀÖ´Ù.

´Ù¸¸ ºñµð¿À ÆÄÀϷκÎÅÍ ºñÆ® ¸ÊÀ» Æ÷ÂøÇÒ »Ó(¸¸Å­)ÀÇ °æ¿ì´Â,¹Ìµð¾î detector (MediaDet) °³Ã¼¸¦ »ç¿ëÇÏ´Â °ÍÀÌ °£´ÜÇÏ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â, ¡¸Æ÷½ºÅÍ ÇÁ·¹ÀÓÀÇ Æ÷Âø¡¹À» ÂüÁ¶ÇÒ°Í. ´Ù¸¸, »ùÇà grabber°¡ À¯¿¬ÇÏ´Ù. ¿Ö³ÄÇϸé, »ùÇà grabber´Â °ÅÀÇ ¸ðµç ¹Ìµð¾î ŸÀÔ (¿¹¿Ü¿¡ ´ëÇØ¼­´Â, ¡¸ISampleGrabber::SetMediaType ¡¹¸¦ ÂüÁ¶ÇÒ°Í)À» Á¶ÀÛÇØ, ¾ÖÇø®ÄÉÀ̼ÇÀ» Á¦¾îÇÒ ¼ö ÀÖ´Â ¹üÀ§¸¦ º¸´Ù ¸¹ÀÌ Á¦°øÇϱ⠶§¹®ÀÌ´Ù.

ÇÊÅÍ ±×·¡ÇÁ¿¡ »ùÇà grabber¸¦ Ãß°¡ÇÑ´Ù

ÃÖÃÊ·Î, »ùÇà grabber ÇÊÅÍÀÇ ÀνºÅϽº¸¦ »ý¼º ÇØ, ±× ÀνºÅϽº¸¦ ÇÊÅÍ ±×·¡ÇÁ¿¡ Ãß°¡ÇÑ´Ù.

// »ùÇà grabber¸¦ »ý¼º ÇÑ´Ù.
IBaseFilter *pGrabberF = NULL;
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
    IID_IBaseFilter, (void**) &pGrabberF);
if (FAILED(hr))
{
    // ¿¡·¯¸¦ µ¹·ÁÁØ´Ù.
}
hr = pGraph->AddFilter(pGrabberF, L"Sample Grabber");
if (FAILED(hr)
{
    // ¿¡·¯¸¦ µ¹·ÁÁØ´Ù.
}

»ùÇà grabber¿¡ ISampleGrabber ÀÎÅÍÆäÀ̽ºÀÇ À¯¹«¸¦ ¹®ÀÇÇÑ´Ù.

ISampleGrabber *pGrabber;
pGrabberF->QueryInterface(IID_ISampleGrabber, (void**) &pGrabber);

¹Ìµð¾î ŸÀÔÀ» ¼³Á¤ÇÑ´Ù

»ùÇà grabber¸¦ ÃÖÃÊ·Î »ý¼º ÇßÀ» ¶§´Â, ¿ì¼± ¹Ìµð¾î ŸÀÔÀº ¼³Á¤µÇÁö ¾Ê´Ù. À̰ÍÀº, ±×·¡ÇÁ³»ÀÇ °ÅÀÇ ¸ðµç ÇÊÅÍ¿¡ Á¢¼ÓÀº ÇÒ ¼ö ÀÖÁö¸¸, ¹Þ´Â µ¥ÀÌÅÍ Å¸ÀÔÀ» Á¦¾î ¼º°úÀÎ ÀÌÅä¿ì°ÍÀÌ´Ù. µû¶ó¼­, ³ª¸ÓÁöÀÇ ±×·¡ÇÁ¸¦ »ý¼º Çϱâ Àü¿¡,ISampleGrabber::SetMediaType ¸Þ¼­µå¸¦ È£ÃâÇØ, »ùÇà grabber¿¡ ´ëÇØ¼­ ¹Ìµð¾î ŸÀÔÀ» ¼³Á¤ÇÏ´Â °Í.

»ùÇà grabber´Â, Á¢¼ÓÇßÀ» ¶§¿¡ ´Ù¸¥ ÇÊÅͰ¡ Á¦°øÇÏ´Â ¹Ìµð¾î ŸÀÔ°ú ÀÌ ¼³Á¤µÈ ¹Ìµð¾î ŸÀÔÀ» ºñ±³ÇÑ´Ù. Á¶»çÇÏ´Â Çʵå´Â, ¸ÞÀÌÀú ŸÀÔ, ¼­ºê ŸÀÔ, Æ÷¸Ë ŸÀÔ »ÓÀÌ´Ù. ÀÌ·¯ÇÑ Çʵ忡¼­´Â, °ª GUID_NULL ´Â "¸ðµç °ªÀ» ¹Þ¾ÆµéÀδÙ" ¶ó°í ÇÏ´Â ÀǹÌÀÌ´Ù. º¸ÅëÀº, ¸ÞÀÌÀú ŸÀÔ°ú ¼­ºê ŸÀÔÀ» ¼³Á¤ÇÑ´Ù. ¿¹¸¦ µé¾î, ÀÌÇÏÀÇ Äڵ忡¼­´Â ºñ¾ÐÃà 24 ºñÆ® RGB ºñµð¿À¸¦ ÁöÁ¤ÇÑ´Ù.

AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pGrabber->SetMediaType(&mt);

´ÙÀ½ÀÇ ¿¹¿¡¼­´Â, µð½ºÇ÷¹ÀÌÀÇ ºñÆ® ±íÀÌ¿¡ ±Ù°ÅÇØ ¹Ìµð¾î ŸÀÔÀ» ¼³Á¤ÇÑ´Ù.

// ÇöÀçÀÇ ºñÆ® ±íÀ̸¦ ¾ò¾î¿Â´Ù.
HDC hdc = GetDC(NULL);
int iBitDepth = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(NULL, hdc);

// ¹Ìµð¾î ŸÀÔÀ» ¼³Á¤ÇÑ´Ù.
mt.majortype = MEDIATYPE_Video;
switch (iBitDepth)
{
case 8:
    mt.subtype = MEDIASUBTYPE_RGB8;
    break;
case 16:
    mt.subtype = MEDIASUBTYPE_RGB555;
    break;
case 24:
    mt.subtype = MEDIASUBTYPE_RGB24;
    break;
case 32:
    mt.subtype = MEDIASUBTYPE_RGB32;
    break;
default:
    return E_FAIL;
}
hr = pGrabber->SetMediaType(&mt);

ÇÊÅÍ ±×·¡ÇÁ¸¦ »ý¼º ÇÑ´Ù

À̰ÍÀ¸·Î, ³ª¸ÓÁöÀÇ ÇÊÅÍ ±×·¡ÇÁ¸¦ »ý¼º ÇÒ ¼ö ÀÖ´Ù. »ùÇà grabber´Â, ÁöÁ¤µÈ ¹Ìµð¾î ŸÀÔÀ» »ç¿ëÇØ Á¢¼ÓÇÒ »Ó(¸¸Å­)À̹ǷÎ, ±×·¡ÇÁ¸¦ »ý¼º ÇÒ °æ¿ì¿¡ ÇÊÅÍ ±×·¡ÇÁ ¸Å´ÏÀúÀÇÀÎÅÚ¸®ÀüÆ® Á¢¼Ó ¸ÞÄ«´ÏÁòÀ» ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù.

¿¹¸¦ µé¾î, ºñ¾ÐÃà ºñµð¿À¸¦ ÁöÁ¤ÇßÀ» °æ¿ì, ¼Ò½º ÇÊÅ͸¦ »ùÇà grabber¿¡ Á¢¼Ó Çϸé, ÇÊÅÍ ±×·¡ÇÁ ¸Å´ÏÀú´Â ÀÚµ¿ÀûÀ¸·Î ÆÄÀÏ ÆÄ¼­¿Í µðÄÚ´õ¸¦ Ãß°¡ÇÑ´Ù. ´ÙÀ½ÀÇ ¿¹¿¡¼­´Â, ConnectFilters ÇïÆÛ-ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ÀÌ ÇïÆÛ-ÇÔ¼ö´Â ¡¸2 °³ÀÇ ÇÊÅÍÀÇ Á¢¼Ó¡¹¿¡ ±âÀçµÇ¾î ÀÖ´Ù.

IBaseFilter *pSrc;
hr = pGraph->AddSourceFilter(wszFileName, L"Source", &pSrc);
if (FAILED(hr))
{
    // ¿¡·¯ Äڵ带 µ¹·ÁÁØ´Ù.
}
hr = ConnectFilters(pGraph, pSrc, pGrabberF);

»ùÇà grabber´Â º¯È¯ ÇÊÅÍÀ̹ǷÎ, Ãâ·Â ÇÉÀº ´Ù¸¥ ÇÊÅÍ¿¡ Á¢¼ÓÇØ µÑ Çʿ䰡 ÀÖ´Ù. º¸Åë, ´Ù »ç¿ëÇÑ »ùÇÃÀº ÆÄ±âÇÏ´Â °Í¸¸À¸·Î ÀÖ´Ù. ±×·¯ÇÑ °æ¿ì, »ùÇà grabber¸¦ Null ·»´õ¸µ ÇÊÅÍ¿¡ Á¢¼ÓÇÑ´Ù. Null ·»´õ¸µ ÇÊÅÍ´Â, ¹ÞÀº µ¥ÀÌÅ͸¦ ÆÄ±âÇÑ´Ù.

Á¶½ÉÇÏÁö ¾ÊÀ¸¸é ¾È µÇ´Â °ÍÀº, »ùÇà grabber¸¦ ºñµð¿À µðÄÚ´õ¿Í ºñµð¿À ·»´õ·¯ÀÇ »çÀÌ¿¡ ¹èÄ¡ Çϸé, ·»´õ¸µÀÇ ÆÛÆ÷¸Õ½º°¡ ÇöÀúÇÏ°Ô ÀúÇÏÇÑ´Ù°í ÇÏ´Â Á¡ÀÌ´Ù. »ùÇà grabber´Â º¯È¯ ÀÎ Ç÷¹À̽º ÇÊÅÍÀÌ´Ù. À̰ÍÀº, Ãâ·Â ¹öÆÛ°¡ ÀÔ·Â ¹öÆÛ¿Í °°´Ù¶ó°í ¸»ÇÏ´Â ÀǹÌÀÌ´Ù. ºñµð¿ÀÀÇ ·»´õ¸µÀÇ °æ¿ì, Ãâ·Â ¹öÆÛ´Â ±×·¡ÇÈ Ä«µå»ó¿¡ ÀÖÀ» °¡´É¼ºÀÌ ³ôÁö¸¸, ±×·¡ÇÈ Ä«µå¿¡¼­ÀÇ Àб⠼ӵµ´Â ¸ÞÀÎ ¸Þ¸ð¸®¿¡¼­ÀÇ Àб⠼ӵµ¿Í ºñ±³ÇØ ±ØÈ÷ ´Ê¾îÁø´Ù.

±×·¡ÇÁ¸¦ ½ÇÇàÇÑ´Ù

»ùÇà grabber°¡ ±â´ÉÇÏ´Â ¸ðµå´Â 2 °³ ÀÖ´Ù.

¿©±â¿¡¼­´Â, ¹öÆÛ¸µ ¸ðµå¿¡ ´ëÇØ ¼³¸íÇÑ´Ù. ÄÝ¹é ¸ðµå¸¦ »ç¿ëÇϱ⿡ ÁîÀ½Çؼ­´Â, Äݹé ÇÔ¼öÀÇ »ç¿ëÀº »ó´ç Á¦ÇÑÇØ¾ß ÇÑ´Ù¶ó°í ¸»ÇÏ´Â Á¡¿¡ ÁÖÀÇ ÇØ¾ß ÇÑ´Ù. Á¦ÇÑÇÏÁö ¾ÊÀ¸¸é ÆÛÆ÷¸Õ½º°¡ Å«ÆøÀ¸·Î ÀúÇÏÇÏ´ÂÁö, °æ¿ì¿¡ µû¶ó¼­´Â µ¥µå ·ÏÀÌ ÀϾ °¡´É¼ºÀÌ ÀÖ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â,ISampleGrabber::SetCallback ¡¹¸¦ ÂüÁ¶ÇÒ°Í. ¹öÆÛ¸µ ¸ðµå¸¦ ¾×ƼºêÇÏ°Ô ÇÏ·Á¸é , °ª TRUE ¸¦ ¼³Á¤ÇØ ISampleGrabber::SetBufferSamples ¸Þ¼­µå¸¦ È£ÃâÇÑ´Ù.

¿É¼ÇÀ¸·Î, °ª TRUE ¸¦ ¼³Á¤ÇØ ISampleGrabber::SetOneShot ¸Þ¼­µå¸¦ È£ÃâÇÑ´Ù. ÀÌ ¸Þ¼­µå¸¦ È£ÃâÇϸé, »ùÇà grabber´Â ÃÖÃÊÀÇ ¹Ìµð¾î »ùÇÃÀ» ¹ÞÀº ´ÙÀ½¿¡ ±×·¡ÇÁ¸¦ Á¤ÁöÇÑ´Ù. À̰ÍÀº ½ºÆ®¸²À¸·ÎºÎÅÍ 1 °³ÀÇ ÇÁ·¹ÀÓÀ» Æ÷ÂøÇÏ°í ½ÍÀº °æ¿ì¿¡ Æí¸®ÇÏ´Ù. ¸ñÀûÀÇ ½Ã°£¿¡ ½ÃÅ© ÇØ, ±×·¡ÇÁ¸¦ ½ÇÇàÇØ,EC_COMPLETE À̺¥Æ®¸¦ ±â´Ù¸°´Ù. ÇÁ·¹ÀÓ¾ÆÅ¥·¹ÀÌÆ®ÀÇ ·¹º§Àº, ¼Ò½º¿¡ µû¶ó¼­ ´Ù¸£´Ù. ¿¹¸¦ µé¾î, MPEG ÆÄÀÏÀÇ ½ÃÅ©´Â º¸ÅëÀº ÇÁ·¹ÀÓ¾ÆÅ¥·¹ÀÌÆ®´Â ¾Æ´Ï´Ù.

// one-shot ¸ðµå¿Í ¹öÆÛ¸µÀ» ¼³Á¤ÇÑ´Ù.
hr = pGrabber->SetOneShot(TRUE);
hr = pGrabber->SetBufferSamples(TRUE);

pControl->Run(); // ±×·¡ÇÁ¸¦ ½ÇÇàÇÑ´Ù.
pEvent->WaitForCompletion(INFINITE, &evCode); // ¿Ï·áÇÒ ¶§±îÁö ´ë±âÇÑ´Ù.

ÇÒ ¼ö ÀÖ´Â ÇÑ »¡¸® ±×·¡ÇÁ¸¦ ½ÇÇàÇÏ·Á¸é , ¡¸±×·¡ÇÁ Ŭ·°ÀÇ ¼³Á¤¡¹À¸·Î ¼³¸íÇϵµ·Ï(µíÀÌ) ±×·¡ÇÁ Ŭ·°À» ¿ÀÇÁ·Î ÇÑ´Ù.

»ùÇÃÀ» Æ÷ÂøÇÑ´Ù

¹öÆÛ¸µ ¸ðµå¿¡¼­´Â, »ùÇà grabber´Â °¢ »ùÇÃÀÇ º¹»ç¸¦ º¸Á¸ÇÑ´Ù. ISampleGrabber::GetCurrentBuffer ¸Þ¼­µå´Â, ¹öÆÛ¸¦ È£ÃâÇØ ¿ø ÇÒ´çÇÏ°í ³¡³­ ¹è¿­¿¡ º¹»ç ÇÑ´Ù. ÇÊ¿äÇÑ ¹è¿­ÀÇ »çÀÌÁ ÆÇ´ÜÇÏ·Á¸é , ÃÖÃÊ·Î ¹è¿­ ÁÖ¼Ò¿¡ ´ëÇØ¼­ NULL Æ÷ÀÎÅ͸¦ ÁöÁ¤ÇØ GetCurrentBuffer ¸¦ È£ÃâÇÑ´Ù.

// ÇÊ¿äÇÑ ¹öÆÛ »çÀÌÁ ¾ò¾î¿Â´Ù.
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);

¹è¿­À» ÇÒ´çÇÏ°í ³ª¼­, ÀÌ ¸Þ¼­µå¸¦ ´Ù½Ã È£ÃâÇØ, ¹öÆÛ¸¦ º¹»ç ÇÑ´Ù.

char *pBuffer = new char[cbBuffer];
if (! pBuffer) 
{
    // ¸Þ¸ð¸® ºÎÁ·. ¿¡·¯ Äڵ带 µ¹·ÁÁØ´Ù.
}
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*) pBuffer);

ISampleGrabber::GetConnectedMediaType ¸Þ¼­µå´Â, ¹öÆÛÀÇ Æ÷¸ËÀ» µ¹·ÁÁØ´Ù.

AM_MEDIA_TYPE mt;
hr = pGrabber->GetConnectedMediaType(&mt);
if (FAILED(hr))
{
    // ¿¡·¯ Äڵ带 µ¹·ÁÁØ´Ù.
}
// Æ÷¸Ë ºí·ÏÀ» Á¶»çÇÑ´Ù.
VIDEOINFOHEADER *pVih;
if ((mt.formattype == FORMAT_VideoInfo) && 
    (mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
    (mt.pbFormat != NULL) ) 
{
    pVih = (VIDEOINFOHEADER*) mt.pbFormat;
}
else 
{
    // Æ÷¸ËÀÌ À߸øµÇ¾î ÀÖ´Ù. Æ÷¸Ë ºí·ÏÀ» ¸±¸®Áî ÇØ, ¿¡·¯¸¦ µ¹·ÁÁØ´Ù.
    FreeMediaType(mt);
    return VFW_E_INVALIDMEDIATYPE; 
}
// ¹Ìµð¾î ŸÀÔÀ» »ç¿ëÇØ BITMAPINFOHEADRE Á¤º¸¿¡ ¾×¼¼½º ÇÒ ¼ö ÀÖ´Ù.
// ¿¹¸¦ µé¾î, ´ÙÀ½ ÄÚµå´Â GDI ¸¦ »ç¿ëÇØ ºñÆ® ¸ÊÀ» ±×¸°´Ù.
SetDIBitsToDevice(
    hdc, 0, 0, 
    pVih->bmiHeader.biWidth,
    pVih->bmiHeader.biHeight,
    0, 0, 
    0,
    pVih->bmiHeader.biHeight,
    pBuffer,
    (BITMAPINFO*) &pVih->bmiHeader,
    DIB_RGB_COLORS
);

// ¿Ï·áÇÏ¸é Æ÷¸Ë ºí·ÏÀ» ¸±¸®Áî ÇÑ´Ù.
FreeMediaType(mt);
¡èTOP