HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state) { TRACE("%p -> (%p)\n", capBox, state); if (*state == State_Stopped) return S_OK; EnterCriticalSection(&capBox->CritSect); if (capBox->thread) { if (*state == State_Paused) ResumeThread(capBox->thread); capBox->stopped = 1; capBox->thread = 0; if (capBox->iscommitted) { IMemInputPin *pMem = NULL; IMemAllocator * pAlloc = NULL; IPin *pConnect = NULL; HRESULT hr; capBox->iscommitted = 0; hr = IPin_ConnectedTo(capBox->pOut, &pConnect); if (SUCCEEDED(hr)) hr = IPin_QueryInterface(pConnect, &IID_IMemInputPin, (void **) &pMem); if (SUCCEEDED(hr)) hr = IMemInputPin_GetAllocator(pMem, &pAlloc); if (SUCCEEDED(hr)) hr = IMemAllocator_Decommit(pAlloc); if (pAlloc) IMemAllocator_Release(pAlloc); if (pMem) IMemInputPin_Release(pMem); if (pConnect) IPin_Release(pConnect); if (hr != S_OK && hr != VFW_E_NOT_COMMITTED) WARN("Decommitting allocator: %x\n", hr); } V4l_Unprepare(capBox); } *state = State_Stopped; LeaveCriticalSection(&capBox->CritSect); return S_OK; }
HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state) { TRACE("%p -> (%p)\n", capBox, state); if (*state == State_Stopped) return S_OK; EnterCriticalSection(&capBox->CritSect); if (capBox->thread) { if (*state == State_Paused) ResumeThread(capBox->thread); capBox->stopped = 1; capBox->thread = 0; if (capBox->iscommitted) { BaseOutputPin *out; HRESULT hr; capBox->iscommitted = 0; out = (BaseOutputPin*)capBox->pOut; hr = IMemAllocator_Decommit(out->pAllocator); if (hr != S_OK && hr != VFW_E_NOT_COMMITTED) WARN("Decommitting allocator: %x\n", hr); } V4l_Unprepare(capBox); } *state = State_Stopped; LeaveCriticalSection(&capBox->CritSect); return S_OK; }
static DWORD WINAPI ReadThread(LPVOID lParam) { Capture * capBox = lParam; HRESULT hr; IMediaSample *pSample = NULL; unsigned long framecount = 0; unsigned char *pTarget, *pInput, *pOutput; hr = V4l_Prepare(capBox); if (FAILED(hr)) goto fail; pOutput = CoTaskMemAlloc(capBox->width * capBox->height * capBox->bitDepth / 8); capBox->curframe = 0; do { V4l_FreeFrame(capBox); } while (capBox->curframe != 0); while (1) { EnterCriticalSection(&capBox->CritSect); if (capBox->stopped) break; hr = OutputPin_GetDeliveryBuffer((OutputPin *)capBox->pOut, &pSample, NULL, NULL, 0); if (SUCCEEDED(hr)) { int len; if (!capBox->swresize) len = capBox->height * capBox->width * capBox->bitDepth / 8; else len = capBox->outputheight * capBox->outputwidth * capBox->bitDepth / 8; IMediaSample_SetActualDataLength(pSample, len); len = IMediaSample_GetActualDataLength(pSample); TRACE("Data length: %d KB\n", len / 1024); IMediaSample_GetPointer(pSample, &pTarget); /* FIXME: Check return values.. */ V4l_GetFrame(capBox, &pInput); capBox->renderer(capBox, pOutput, pInput); Resize(capBox, pTarget, pOutput); hr = OutputPin_SendSample((OutputPin *)capBox->pOut, pSample); TRACE("%p -> Frame %lu: %x\n", capBox, ++framecount, hr); IMediaSample_Release(pSample); V4l_FreeFrame(capBox); } LeaveCriticalSection(&capBox->CritSect); if (FAILED(hr) && hr != VFW_E_NOT_CONNECTED) { ERR("Received error: %x\n", hr); goto cfail; } } LeaveCriticalSection(&capBox->CritSect); CoTaskMemFree(pOutput); return 0; cfail: CoTaskMemFree(pOutput); V4l_Unprepare(capBox); LeaveCriticalSection(&capBox->CritSect); fail: capBox->thread = 0; capBox->stopped = 1; FIXME("Stop IFilterGraph\n"); return 0; }