📄 ddcam.cpp.svn-base
字号:
#include <windows.h>
#include <mmsystem.h>
#include <streams.h>
#include <cs.h>
#include <csmedia.h>
#include <camera.h>
#include <aygshell.h>
#include "ddcam.h"
#include "grabber.h"
#define MAX_LOADSTRING 100
#define WM_GRAPHNOTIFY WM_APP + 1
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
#define FOURCC_Y444 MAKEFOURCC('Y', '4', '4', '4') // TIYUV: 1394 conferencing camera 4:4:4 mode 0
#define FOURCC_UYVY MAKEFOURCC('U', 'Y', 'V', 'Y') // MSYUV: 1394 conferencing camera 4:4:4 mode 1 and 3
#define FOURCC_Y411 MAKEFOURCC('Y', '4', '1', '1') // TIYUV: 1394 conferencing camera 4:1:1 mode 2
#define FOURCC_Y800 MAKEFOURCC('Y', '8', '0', '0') // TIYUV: 1394 conferencing camera 4:1:1 mode 5
#define FOURCC_YUV422 MAKEFOURCC('U', 'Y', 'V', 'Y')
#define FOURCC_YV16 MAKEFOURCC('Y', 'V', '1', '6')
const GUID MEDIASUBTYPE_YV16 = {FOURCC_YV16, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};
typedef struct
{
const unsigned short *text;
const GUID *guid;
} MEDIA_SUBTYPE_LIST;
const MEDIA_SUBTYPE_LIST media_list[] = {
{TEXT("YVU9"),&MEDIASUBTYPE_YVU9},
{TEXT("Y411"),&MEDIASUBTYPE_Y411},
{TEXT("Y41P"),&MEDIASUBTYPE_Y41P},
{TEXT("YUY2"),&MEDIASUBTYPE_YUY2},
{TEXT("YVYU"),&MEDIASUBTYPE_YVYU},
{TEXT("UYVY"),&MEDIASUBTYPE_UYVY},
{TEXT("Y211"),&MEDIASUBTYPE_Y211},
{TEXT("YV12"),&MEDIASUBTYPE_YV12},
{TEXT("YV16"),&MEDIASUBTYPE_YV16},
{TEXT("Overlay"),&MEDIASUBTYPE_Overlay},
{TEXT("RGB1"),&MEDIASUBTYPE_RGB1},
{TEXT("RGB4"),&MEDIASUBTYPE_RGB4},
{TEXT("RGB8"),&MEDIASUBTYPE_RGB8},
{TEXT("RGB565"),&MEDIASUBTYPE_RGB565},
{TEXT("RGB555"),&MEDIASUBTYPE_RGB555},
{TEXT("RGB24"),&MEDIASUBTYPE_RGB24},
{TEXT("RGB32"),&MEDIASUBTYPE_RGB32},
};
#define MLIST_SIZE (sizeof(media_list)/sizeof(media_list[0]))
#define StillWidth 480
#define StillHeight 640
unsigned long light;
unsigned long gain;
struct _capstuff
{
TCHAR szCaptureFile[_MAX_PATH];
WORD wCapFileSize;
ICaptureGraphBuilder2 *pBuilder;
IVideoWindow *pVWS, *pVWP;
IMediaEventEx *pME;
IAMDroppedFrames *pDF;
IAMVideoCompression *pVC;
IAMVideoControl *pAMVidControl;
IAMCameraControl *pCamControl;
IAMVideoProcAmp *pVProcAmp;
IAMStreamConfig *pConfigP; //Preview config
// IAMVfwCaptureDialogs *pDlg;
IAMStreamConfig *pVSC; // for video cap
IBaseFilter *pRenderS; //Still render
IBaseFilter *pRenderP; //Preview render
IBaseFilter *pCap;
IBasicVideo *pBV; //basic video for still video render
IGraphBuilder *pGraph;
CSampleGrabber *pGrab;
IDirectDrawVideo *pDdrawVideoP; //Preview directdraw video
IDirectDrawVideo *pDdrawVideoS; //Still directdraw video
IFileSinkFilter *pSink;
BOOL fStillGraphBuilt;
BOOL fPreviewGraphBuilt;
BOOL fStillCapturing;
BOOL fPreviewing;
double FrameRate;
BOOL fWantPreview;
} gcap;
int exposure = 3;
int picture_number=0;
// Global Variables:
HINSTANCE hInst; // The current instance
HWND hWndApp; //The window instance
HWND hWndMenu = NULL; //Menu handle
HWND hWndMenuStill = NULL;
HMENU hMenu;
REFERENCE_TIME rtStart = 10000000, rtStop = 50000000;
const WORD wStartCookie = 1, wStopCookie = 2; // Arbitrary values.
const TCHAR *picture_path = TEXT("\\My Documents\\My Pictures") ;
//const TCHAR *picture_path = TEXT("\\Storage Card") ;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass (HINSTANCE, LPTSTR);
BOOL InitInstance (HINSTANCE, int);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);
BOOL ConvertGuidToString(GUID * guid,unsigned short *str);
HRESULT SetCapMode(IBaseFilter *pCap);
HRESULT OpenCamera(LPCOLESTR lpFile,BOOL bCapture,BOOL bStill,BOOL bPreview);
void WriteBMPToDisk(unsigned char *pStillImageBuffer);
void UpdatePictureNumber();
HRESULT ActivatePreviousInstance(const TCHAR* pszClass,const TCHAR* pszTitle,BOOL* pfActivated);
HRESULT Callback( IMediaSample * pSample, REFERENCE_TIME * StartTime, REFERENCE_TIME *
StopTime,BOOL TypeChanged )
{
unsigned char *pbuf;
HRESULT hr;
// NOTE: We cannot do anything with this sample until we call GetConnectedMediaType
// on the filter to find out what format these samples are.
RETAILMSG(1, (TEXT("Callback with sample %lx for time %ld"), pSample, long( *StartTime / 10000 ) ) );
hr = pSample->GetPointer(&pbuf);
WriteBMPToDisk(pbuf);
return S_OK;
}
// Start previewing
//
BOOL StartPreview()
{
HRESULT hr;
// way ahead of you
if(gcap.fPreviewing)
return TRUE;
// run the graph
IMediaControl *pMC = NULL;
hr = gcap.pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC);
if(SUCCEEDED(hr))
{
hr = pMC->Run();
if(FAILED(hr))
{
// stop parts that ran
pMC->Stop();
}
pMC->Release();
}
if(FAILED(hr))
{
return FALSE;
}
gcap.pVWS->put_WindowState(SW_HIDE);
gcap.pVWP->put_WindowState(SW_SHOW);
gcap.fPreviewing = TRUE;
return TRUE;
}
// stop the preview graph
//
BOOL StopPreview()
{
// way ahead of you
if(!gcap.fPreviewing)
{
return FALSE;
}
// stop the graph
IMediaControl *pMC = NULL;
HRESULT hr = gcap.pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC);
if(SUCCEEDED(hr))
{
hr = pMC->Stop();
pMC->Release();
}
if(FAILED(hr))
{
return FALSE;
}
gcap.fPreviewing = FALSE;
return TRUE;
}
HRESULT CloseCamera()
{
HRESULT hr;
StopPreview();
SAFE_RELEASE(gcap.pCap);
SAFE_RELEASE(gcap.pConfigP);
if(gcap.pVWS)
{
gcap.pVWS->put_Visible(OAFALSE);
gcap.pVWS->put_Owner(NULL);
hr = gcap.pVWS->Release();
}
if(gcap.pVWP)
{
gcap.pVWP->put_Visible(OAFALSE);
gcap.pVWP->put_Owner(NULL);
hr = gcap.pVWP->Release();
}
SAFE_RELEASE(gcap.pGraph);
SAFE_RELEASE(gcap.pBuilder);
// Finished with COM
//CoUninitialize();
// bOpenCamera = FALSE;
return hr;
}
HRESULT RenderStill()
{
HRESULT hr;
hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_STILL,&MEDIATYPE_Video, gcap.pCap, NULL, NULL);
return hr;
}
HRESULT CaptureStillImage()
{
HRESULT hr;
IBaseFilter *pMux = NULL;
IFileSinkFilter *pSink = NULL;
IMediaControl *pMC = NULL;
SHMENUBARINFO mbi;
if (!hWndMenuStill)
{
ZeroMemory(&mbi, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWndApp;
mbi.nToolBarId = IDM_MENU_STILL;
mbi.hInstRes = hInst;
mbi.dwFlags = SHCMBF_HMENU|SHCMBF_HIDDEN|SHCMBF_HIDESIPBUTTON ;
if(!SHCreateMenuBar(&mbi))
{
//Couldn't create the menu bar. Fail creation of the window.
}
hWndMenuStill = mbi.hwndMB;
}
if (gcap.fPreviewing)
{
hr = SetCapMode(gcap.pCap); //Run still pin
ShowWindow(hWndMenu,SW_HIDE);
ShowWindow(hWndMenuStill,SW_SHOW);
gcap.pVWP->put_WindowState(SW_HIDE);
gcap.pVWS->put_WindowState(SW_SHOW);
gcap.fPreviewing=false;
// create the menu bar
}
else
{
ShowWindow(hWndMenu,SW_SHOW);
ShowWindow(hWndMenuStill,SW_HIDE);
gcap.pVWS->put_WindowState(SW_HIDE);
gcap.pVWP->put_WindowState(SW_SHOW);
gcap.fPreviewing=true;
}
return hr;
}
HRESULT InitCapFilter()
{
HRESULT hr;
IPersistPropertyBag *pPropertyBag = NULL;
// Create Capture Filter
hr = CoCreateInstance(CLSID_VideoCapture, NULL, CLSCTX_INPROC_SERVER,IID_IBaseFilter,
(void **)&gcap.pCap);
GUID clsid = DEVCLASS_CAMERA_GUID;
DEVMGR_DEVICE_INFORMATION pdi;
HANDLE hand = FindFirstDevice(DeviceSearchByGuid,&clsid,&pdi);
RETAILMSG(1, (TEXT("CamTest: Find device: %x %x\r\n"),hand,pdi.szDeviceName));
hr = gcap.pCap->QueryInterface(IID_IPersistPropertyBag, (void **)&pPropertyBag);
if (!SUCCEEDED(hr))
return hr;
VARIANT varCamName;
IPropertyBag *propBag = NULL;
varCamName.byref = L"CAM1:" ;
//hr = gcap.pCap->QueryInterface(IID_IPropertyBag, (void **)&propBag);
//hr = propBag->Write(L"VCapName", &varCamName);
hr = pPropertyBag->Load(propBag,NULL);
pPropertyBag->Release();
return S_OK;
}
void SetupVideoWindow(IVideoWindow *pVW)
{
RECT rt;
long lWidth, lHeight;
HRESULT hr;
if (!pVW)
{
hr = pVW->put_Owner((OAHWND)hWndApp) ;
hr = pVW->put_WindowStyle(WS_CHILD);
}
if (GetWindowRect(hWndApp, &rt))
{
pVW->get_Width(&lWidth);
pVW->get_Height(&lHeight);
if ((lWidth < rt.right)&&(lHeight<rt.bottom))
{
pVW->put_Left(rt.left + (rt.right-rt.left-lWidth)/2);
pVW->put_Top( (rt.bottom-rt.top-lHeight)/2);
}
else
{
pVW->put_Left(rt.left);
pVW->put_Top(0);
pVW->put_Width(rt.right);
pVW->put_Height(rt.bottom-rt.top);
}
}
}
HRESULT ConnectFilters(IGraphBuilder *pGraph,IBaseFilter *pF1, int iPin1,IBaseFilter *pF2,int iPin2,IPin **ppPinout)
{
IPin *pPin1, *pPin2;
IEnumPins *pEnum;
unsigned long fetched;
HRESULT hr;
hr = pF1->EnumPins(&pEnum);
while (iPin1>0)
{
hr = pEnum->Next(1,&pPin1,&fetched); //Skip Capture pin
iPin1--;
}
hr = pEnum->Next(1,&pPin1,&fetched);
hr = pF2->EnumPins(&pEnum);
while (iPin2>0)
{
hr = pEnum->Next(1,&pPin2,&fetched); //Skip Capture pin
iPin2--;
}
hr = pEnum->Next(1,&pPin2,&fetched);
hr = pGraph->Connect(pPin1,pPin2);
if (ppPinout)
{
*ppPinout = pPin1;
}
if (!SUCCEEDED(hr))
RETAILMSG(1, (TEXT("CamTest: Fail to Connect Pin! %x\r\n"),hr));
return hr;
}
HRESULT OpenCamera(LPCOLESTR lpFile,BOOL bCapture,BOOL bStill,BOOL bPreview)
{
HRESULT hr;
IBaseFilter *pMux = NULL;
IPin *pPin;
gcap.pGrab = new CSampleGrabber(NULL,&hr,FALSE);
gcap.pGrab->AddRef();
gcap.pGrab->SetCallback(&Callback);
CMediaType mt;
mt.SetType(&MEDIATYPE_Video);
mt.SetSubtype(&MEDIASUBTYPE_RGB565);
gcap.pGrab->SetAcceptedMediaType(&mt);
// Create the Filter Graph Manager.
hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&gcap.pGraph);
// Create the Capture Graph Builder.
hr = CoCreateInstance(CLSID_CaptureGraphBuilder, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
(void **)&gcap.pBuilder);
gcap.pBuilder->SetFiltergraph(gcap.pGraph);
hr = CoCreateInstance(CLSID_VideoRenderer, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(void **)&gcap.pRenderP);
hr = CoCreateInstance(CLSID_VideoRenderer, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(void **)&gcap.pRenderS);
hr = gcap.pGraph->AddFilter(gcap.pCap,L"Video Capture Source");
hr = gcap.pGraph->AddFilter(gcap.pRenderP,L"Video Render1");
//Add filter to graph builder
hr = gcap.pGraph->AddFilter(gcap.pRenderS,L"Video Render2");
hr = gcap.pGraph->AddFilter(gcap.pGrab,L"Grabber");
if (bStill)
{
if (lpFile == NULL)
{
ConnectFilters(gcap.pGraph,gcap.pCap,1,gcap.pGrab,0,&pPin); // 1 is still pin
ConnectFilters(gcap.pGraph,gcap.pGrab,1,gcap.pRenderS,0,NULL); // 1 is grab's output pin
gcap.pGraph->Render(pPin);
hr = gcap.pRenderS->QueryInterface(IID_IVideoWindow, (void**)&gcap.pVWS);
hr = gcap.pRenderS->QueryInterface(IID_IBasicVideo, (void**)&gcap.pBV);
hr = gcap.pRenderS->QueryInterface(IID_IDirectDrawVideo, (void **)&gcap.pDdrawVideoS);
gcap.pBV->SetDestinationPosition(0,0,240,300);
gcap.pVWS->put_Owner((OAHWND)hWndApp);
SetupVideoWindow(gcap.pVWS);
}
else
{
hr = gcap.pBuilder->SetOutputFileName(&MEDIASUBTYPE_Asf,lpFile,&pMux,NULL);
hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_STILL,&MEDIATYPE_Video, gcap.pCap, NULL, pMux);
}
}
//Start capture
if (bCapture) //capture to file
{
if (lpFile == NULL)
{
hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video, gcap.pCap, NULL, NULL);
}
else
{
hr = gcap.pBuilder->SetOutputFileName(&MEDIASUBTYPE_Asf,lpFile,&pMux,NULL);
hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video, gcap.pCap, NULL, pMux);
}
gcap.pBuilder->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, gcap.pCap, 0, 0, // Start and stop times.
wStartCookie, wStopCookie);
}
if (bPreview)
{
hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video, gcap.pCap, NULL, gcap.pRenderP);
hr = gcap.pRenderP->QueryInterface(IID_IVideoWindow, (void**)&gcap.pVWP);
hr = gcap.pRenderP->QueryInterface(IID_IDirectDrawVideo, (void **)&gcap.pDdrawVideoP);
SetupVideoWindow(gcap.pVWP);
}
// Query for video interfaces, which may not be relevant for audio files
hr = gcap.pGraph->QueryInterface(IID_IMediaEventEx, (void **)&gcap.pME);
hr = gcap.pCap->QueryInterface(IID_IAMCameraControl,(void **)&gcap.pCamControl);
hr = gcap.pCap->QueryInterface(IID_IAMVideoProcAmp,(void **)&gcap.pVProcAmp);
// Query the output pin for IAMStreamConfig (not shown).
hr = gcap.pBuilder->FindInterface(
&PIN_CATEGORY_PREVIEW, // Preview pin.
0, // Any media type.
gcap.pCap, // Pointer to the capture filter.
IID_IAMStreamConfig, (void**)&gcap.pConfigP);
// Have the graph signal event via window callbacks for performance
hr = gcap.pME->SetNotifyWindow((OAHWND)hWndApp, WM_GRAPHNOTIFY, 0);
return hr;
}
HRESULT SetCapMode(IBaseFilter *pCap)
{
HRESULT hr;
IPin *pPin = NULL;
IEnumPins *pEnum;
unsigned long fetched;
int nPin = 1; //Still Pin
hr = gcap.pCap->QueryInterface(IID_IAMVideoControl,(void **)&gcap.pAMVidControl);
hr = gcap.pCap->EnumPins(&pEnum);
while (nPin>0)
{
hr = pEnum->Next(1,&pPin,&fetched);
nPin--;
}
hr = pEnum->Next(1,&pPin,&fetched);
if (SUCCEEDED(hr))
{
//hr = gcap.pAMVidControl->SetMode(pPin, VideoControlFlag_ExternalTriggerEnable);
hr = gcap.pAMVidControl->SetMode(pPin, VideoControlFlag_Trigger);
//pPin->Release();
}
else
{
RETAILMSG(1, (TEXT("CamTest: Fail to Find Pin! %x\r\n"),hr));
}
return hr;
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
//Init COM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -