*\r
*/\r
\r
-#define SAFE_RELEASE(x) { if (x) x->lpVtbl->Release(x); x = NULL; }\r
+#define SAFE_RELEASE(x) \\r
+ do { \\r
+ if (x) { \\r
+ (x)->lpVtbl->Release(x); \\r
+ x = NULL; \\r
+ } \\r
+ } while(0)\r
\r
typedef HRESULT (STDAPICALLTYPE *CallbackFn)(ULONG dwSize, BYTE *pBuffer);\r
\r
HWCGrabCallback *This = (HWCGrabCallback *)g_malloc0(sizeof(HWCGrabCallback));\r
\r
if (!This) {\r
+ ERR("failed to HWCGrabCallback_Construct, E_OUTOFMEMORY\n");\r
return E_OUTOFMEMORY;\r
}\r
\r
\r
if (InterlockedDecrement(&This->m_cRef) == 0)\r
{\r
- if (This->m_pCFilter) {\r
- IBaseFilter_Release(This->m_pCFilter);\r
- This->m_pCFilter = NULL;\r
- }\r
if (This->m_pCallback) {\r
- IGrabCallback_Release(This->m_pCallback);\r
- This->m_pCallback = NULL;\r
+ SAFE_RELEASE(This->m_pCallback);\r
}\r
if (This->m_pConnectedPin) {\r
- IPin_Release(This->m_pConnectedPin);\r
- This->m_pConnectedPin = NULL;\r
+ SAFE_RELEASE(This->m_pConnectedPin);\r
}\r
g_free((void*)This);\r
return 0;\r
if (This->m_pConnectedPin == NULL) {\r
hr = S_FALSE;\r
} else {\r
- IPin_Release(This->m_pConnectedPin);\r
- This->m_pConnectedPin = NULL;\r
+ SAFE_RELEASE(This->m_pConnectedPin);\r
hr = S_OK;\r
}\r
return hr;\r
\r
if (InterlockedDecrement(&This->m_cRef) == 0)\r
{\r
- if (This->m_pCFilter) {\r
- IBaseFilter_Release(This->m_pCFilter);\r
- This->m_pCFilter = NULL;\r
- }\r
if (This->m_pCallback) {\r
- IGrabCallback_Release(This->m_pCallback);\r
- This->m_pCallback = NULL;\r
+ SAFE_RELEASE(This->m_pCallback);\r
}\r
if (This->m_pConnectedPin) {\r
- IPin_Release(This->m_pConnectedPin);\r
- This->m_pConnectedPin = NULL;\r
+ SAFE_RELEASE(This->m_pConnectedPin);\r
}\r
g_free((void*)This);\r
return 0;\r
HWCInPin *This = impl_from_IPin(iface);\r
\r
if (pCaptureCB == NULL) {\r
- IGrabCallback_Release(This->m_pCallback);\r
- This->m_pCallback = NULL;\r
+ SAFE_RELEASE(This->m_pCallback);\r
} else {\r
This->m_pCallback = pCaptureCB;\r
IGrabCallback_AddRef(This->m_pCallback);\r
This->IMemInputPin_iface.lpVtbl = &HWCMemInputPin_Vtbl;\r
This->m_bReadOnly = FALSE;\r
This->m_pCFilter = pFilter;\r
- if (This->m_pCFilter) {\r
- IBaseFilter_AddRef(This->m_pCFilter);\r
- }\r
This->m_pConnectedPin = NULL;\r
This->m_pCallback = NULL;\r
This->m_cRef = 1;\r
\r
if (InterlockedDecrement(&This->m_cRef) == 0) {\r
if (This->m_pFilter) {\r
- IBaseFilter_Release(This->m_pFilter);\r
- This->m_pFilter = NULL;\r
+ SAFE_RELEASE(This->m_pFilter);\r
}\r
This->m_nPos = 0;\r
g_free((void*)This);\r
static STDMETHODIMP HWCEnumPins_Next(IEnumPins *iface, ULONG cPins, IPin **ppPins,\r
ULONG *pcFetched)\r
{\r
+ ULONG fetched;\r
HWCEnumPins *This = impl_from_IEnumPins(iface);\r
\r
if (ppPins == NULL)\r
return E_POINTER;\r
\r
- ULONG fetched;\r
if (This->m_nPos < 1 && cPins > 0) {\r
IPin *pPin;\r
IBaseFilter_FindPin(This->m_pFilter, HWCPinName, &pPin);\r
*ppPins = pPin;\r
- IPin_AddRef(pPin);\r
fetched = 1;\r
This->m_nPos++;\r
} else {\r
\r
if (InterlockedDecrement(&This->m_cRef) == 0) {\r
if (This->m_pPin) {\r
- IPin_Release(This->m_pPin);\r
- This->m_pPin = NULL;\r
- }\r
- if (This->m_pFilterGraph) {\r
- IFilterGraph_Release(This->m_pFilterGraph);\r
- This->m_pFilterGraph = NULL;\r
+ SAFE_RELEASE(This->m_pPin);\r
}\r
g_free((void*)This);\r
return 0;\r
HWCFilter *This = impl_from_IBaseFilter(iface);\r
\r
This->m_pFilterGraph = pGraph;\r
- if (pGraph) {\r
- IFilterGraph_AddRef(pGraph);\r
- }\r
return S_OK;\r
}\r
\r
HRESULT hr;\r
\r
hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC, &IID_IGraphBuilder, (void**)&g_pGB);\r
- if (FAILED(hr))\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to create instance of GraphBuilder, 0x%x\n", hr);\r
return hr;\r
+ }\r
\r
hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, &IID_ICaptureGraphBuilder2, (void**)&g_pCGB);\r
- if (FAILED(hr))\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to create instance of CaptureGraphBuilder2, 0x%x\n", hr);\r
return hr;\r
+ }\r
\r
hr = g_pCGB->lpVtbl->SetFiltergraph(g_pCGB, g_pGB);\r
- if (FAILED(hr))\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to SetFiltergraph, 0x%x\n", hr);\r
return hr;\r
+ }\r
\r
hr = g_pGB->lpVtbl->QueryInterface(g_pGB, &IID_IMediaControl, (void **)&g_pMediaControl);\r
- if (FAILED(hr))\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to QueryInterface for IMediaControl, 0x%x\n", hr);\r
return hr;\r
+ }\r
\r
hr = HWCGrabCallback_Construct(&g_pCallback);\r
if (g_pCallback == NULL)\r
IMoniker *pMoniKer;\r
\r
hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void**)&pCreateDevEnum);\r
- if (FAILED(hr))\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to create instance of CreateDevEnum, 0x%x\n", hr);\r
return hr;\r
+ }\r
\r
hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum, &CLSID_VideoInputDeviceCategory, &pEnumMK, 0);\r
- if (FAILED(hr))\r
- {\r
- pCreateDevEnum->lpVtbl->Release(pCreateDevEnum);\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to get VideoInputDeviceCategory, 0x%x\n", hr);\r
+ SAFE_RELEASE(pCreateDevEnum);\r
return hr;\r
}\r
\r
if (!pEnumMK)\r
{\r
- pCreateDevEnum->lpVtbl->Release(pCreateDevEnum);\r
+ ERR("ClassEnumerator moniker is NULL\n");\r
+ SAFE_RELEASE(pCreateDevEnum);\r
return E_FAIL;\r
}\r
pEnumMK->lpVtbl->Reset(pEnumMK);\r
}\r
SysFreeString(var.bstrVal);\r
}\r
- pBag->lpVtbl->Release(pBag);\r
+ SAFE_RELEASE(pBag);\r
}\r
- pMoniKer->lpVtbl->Release(pMoniKer);\r
+ SAFE_RELEASE(pMoniKer);\r
}\r
\r
if (SUCCEEDED(hr))\r
if (hr != S_OK && hr != S_FALSE)\r
{\r
ERR("Counldn't add Video Capture filter to our graph!\n");\r
+ SAFE_RELEASE(g_pSrcFilter);\r
}\r
}\r
+ SAFE_RELEASE(pEnumMK);\r
+ SAFE_RELEASE(pCreateDevEnum);\r
\r
return hr;\r
}\r
if (FAILED(hr))\r
{\r
ERR("Counldn't add HWCFilterr to our graph!\n");\r
+ SAFE_RELEASE(g_pDstFilter);\r
}\r
}\r
return hr;\r
HRESULT hr;\r
\r
hr = GetPin(g_pSrcFilter, PINDIR_OUTPUT , &g_pOutputPin);\r
- if (FAILED(hr))\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to get output pin. 0x%x\n", hr);\r
return hr;\r
+ }\r
\r
hr = GetPin(g_pDstFilter, PINDIR_INPUT , &g_pInputPin);\r
- if (FAILED(hr))\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to get input pin. 0x%x\n", hr);\r
return hr;\r
+ }\r
\r
hr = g_pGB->lpVtbl->Connect(g_pGB, g_pOutputPin, g_pInputPin);\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to connect pins. 0x%x\n", hr);\r
+ }\r
+ return hr;\r
+}\r
+\r
+static STDMETHODIMP DisconnectPins(void)\r
+{\r
+ HRESULT hr;\r
+\r
+ hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pOutputPin);\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to disconnect output pin. 0x%x\n", hr);\r
+ return hr;\r
+ }\r
+\r
+ hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pInputPin);\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to disconnect input pin. 0x%x\n", hr);\r
+ }\r
+\r
+ return hr;\r
+}\r
+\r
+static STDMETHODIMP RemoveFilters(void)\r
+{\r
+ HRESULT hr;\r
+\r
+ hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pSrcFilter);\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to remove source filer. 0x%x\n", hr);\r
+ return hr;\r
+ }\r
+\r
+ hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pDstFilter);\r
+ if (FAILED(hr)) {\r
+ ERR("Failed to remove destination filer. 0x%x\n", hr);\r
+ }\r
+\r
return hr;\r
}\r
\r
if (FAILED(hr))\r
{\r
ERR("failed to GetNumberOfCapabilities method\n");\r
- pSConfig->lpVtbl->Release(pSConfig);\r
+ SAFE_RELEASE(pSConfig);\r
return hr;\r
}\r
\r
hr = E_FAIL;\r
}\r
}\r
- pSConfig->lpVtbl->Release(pSConfig);\r
+ SAFE_RELEASE(pSConfig);\r
return hr;\r
}\r
\r
hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum, &CLSID_VideoInputDeviceCategory, &pEnumMK, 0);\r
if (FAILED(hr))\r
{\r
- pCreateDevEnum->lpVtbl->Release(pCreateDevEnum);\r
ERR("[%s] failed to create class enumerator\n", __func__);\r
goto error;\r
}\r
\r
if (!pEnumMK)\r
{\r
- pCreateDevEnum->lpVtbl->Release(pCreateDevEnum);\r
ERR("[%s] class enumerator is NULL!!\n", __func__);\r
goto error;\r
}\r
ret = 1;\r
SysFreeString(var.bstrVal);\r
}\r
- pBag->lpVtbl->Release(pBag);\r
+ SAFE_RELEASE(pBag);\r
}\r
- pMoniKer->lpVtbl->Release(pMoniKer);\r
+ SAFE_RELEASE(pMoniKer);\r
}\r
\r
error:\r
+ SAFE_RELEASE(pEnumMK);\r
+ SAFE_RELEASE(pCreateDevEnum);\r
CoUninitialize();\r
return ret;\r
}\r
return;\r
\r
error_failed:\r
+ DisconnectPins();\r
+ RemoveFilters();\r
CloseInterfaces();\r
CoUninitialize();\r
param->errCode = EINVAL;\r
MaruCamParam *param = state->param;\r
param->top = 0;\r
\r
+ DisconnectPins();\r
+ RemoveFilters();\r
CloseInterfaces();\r
CoUninitialize();\r
INFO("Close successfully!!!\n");\r
MaruCamParam *param = state->param;\r
param->top = 0;\r
\r
+ ready_count = 0;\r
width = supported_dst_frames[cur_frame_idx].width;\r
height = supported_dst_frames[cur_frame_idx].height;\r
pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;\r
\r
qemu_mutex_lock(&state->thread_mutex);\r
state->streamon = 1;\r
- ready_count = 0;\r
qemu_mutex_unlock(&state->thread_mutex);\r
\r
INFO("Start preview!!!\n");\r