/* * Generic Implementation of strmbase video classes * * Copyright 2012 Aric Stewart, CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COBJMACROS #include <assert.h> #include "dshow.h" #include "uuids.h" #include "vfwmsgs.h" #include "wine/debug.h" #include "wine/unicode.h" #include "wine/strmbase.h" WINE_DEFAULT_DEBUG_CHANNEL(strmbase); static inline BaseControlVideo *impl_from_IBasicVideo(IBasicVideo *iface) { return CONTAINING_RECORD(iface, BaseControlVideo, IBasicVideo_iface); } HRESULT WINAPI BaseControlVideo_Init(BaseControlVideo *pControlVideo, const IBasicVideoVtbl *lpVtbl, BaseFilter *owner, CRITICAL_SECTION *lock, BasePin* pPin, const BaseControlVideoFuncTable* pFuncsTable) { pControlVideo->IBasicVideo_iface.lpVtbl = lpVtbl; pControlVideo->pFilter = owner; pControlVideo->pInterfaceLock = lock; pControlVideo->pPin = pPin; pControlVideo->pFuncsTable = pFuncsTable; BaseDispatch_Init(&pControlVideo->baseDispatch, &IID_IBasicVideo); return S_OK; } HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo) { return BaseDispatch_Destroy(&pControlVideo->baseDispatch); } HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT *pctinfo) { BaseControlVideo *This = impl_from_IBasicVideo(iface); return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo); } HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { BaseControlVideo *This = impl_from_IBasicVideo(iface); return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo); } HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { BaseControlVideo *This = impl_from_IBasicVideo(iface); return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId); } HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr) { BaseControlVideo *This = impl_from_IBasicVideo(iface); HRESULT hr = S_OK; ITypeInfo *pTypeInfo; hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo); if (SUCCEEDED(hr)) { hr = ITypeInfo_Invoke(pTypeInfo, &This->IBasicVideo_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); ITypeInfo_Release(pTypeInfo); } return hr; } HRESULT WINAPI BaseControlVideoImpl_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame) { VIDEOINFOHEADER *vih; BaseControlVideo *This = impl_from_IBasicVideo(iface); if (!This->pPin->pConnectedTo) return VFW_E_NOT_CONNECTED; TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame); vih = This->pFuncsTable->pfnGetVideoFormat(This); *pAvgTimePerFrame = vih->AvgTimePerFrame; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_BitRate(IBasicVideo *iface, LONG *pBitRate) { VIDEOINFOHEADER *vih; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate); if (!This->pPin->pConnectedTo) return VFW_E_NOT_CONNECTED; vih = This->pFuncsTable->pfnGetVideoFormat(This); *pBitRate = vih->dwBitRate; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_BitErrorRate(IBasicVideo *iface, LONG *pBitErrorRate) { VIDEOINFOHEADER *vih; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate); if (!This->pPin->pConnectedTo) return VFW_E_NOT_CONNECTED; vih = This->pFuncsTable->pfnGetVideoFormat(This); *pBitErrorRate = vih->dwBitErrorRate; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_VideoWidth(IBasicVideo *iface, LONG *pVideoWidth) { VIDEOINFOHEADER *vih; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth); vih = This->pFuncsTable->pfnGetVideoFormat(This); *pVideoWidth = vih->bmiHeader.biWidth; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_VideoHeight(IBasicVideo *iface, LONG *pVideoHeight) { VIDEOINFOHEADER *vih; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight); vih = This->pFuncsTable->pfnGetVideoFormat(This); *pVideoHeight = abs(vih->bmiHeader.biHeight); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_put_SourceLeft(IBasicVideo *iface, LONG SourceLeft) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); SourceRect.left = SourceLeft; This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_SourceLeft(IBasicVideo *iface, LONG *pSourceLeft) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); *pSourceLeft = SourceRect.left; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_put_SourceWidth(IBasicVideo *iface, LONG SourceWidth) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); SourceRect.right = SourceRect.left + SourceWidth; This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_SourceWidth(IBasicVideo *iface, LONG *pSourceWidth) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); *pSourceWidth = SourceRect.right - SourceRect.left; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_put_SourceTop(IBasicVideo *iface, LONG SourceTop) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); SourceRect.top = SourceTop; This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_SourceTop(IBasicVideo *iface, LONG *pSourceTop) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); *pSourceTop = SourceRect.top; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_put_SourceHeight(IBasicVideo *iface, LONG SourceHeight) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); SourceRect.bottom = SourceRect.top + SourceHeight; This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_SourceHeight(IBasicVideo *iface, LONG *pSourceHeight) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); *pSourceHeight = SourceRect.bottom - SourceRect.top; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_put_DestinationLeft(IBasicVideo *iface, LONG DestinationLeft) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); DestRect.left = DestinationLeft; This->pFuncsTable->pfnSetTargetRect(This, &DestRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_DestinationLeft(IBasicVideo *iface, LONG *pDestinationLeft) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); *pDestinationLeft = DestRect.left; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_put_DestinationWidth(IBasicVideo *iface, LONG DestinationWidth) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); DestRect.right = DestRect.left + DestinationWidth; This->pFuncsTable->pfnSetTargetRect(This, &DestRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_DestinationWidth(IBasicVideo *iface, LONG *pDestinationWidth) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); *pDestinationWidth = DestRect.right - DestRect.left; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_put_DestinationTop(IBasicVideo *iface, LONG DestinationTop) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); DestRect.top = DestinationTop; This->pFuncsTable->pfnSetTargetRect(This, &DestRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_DestinationTop(IBasicVideo *iface, LONG *pDestinationTop) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); *pDestinationTop = DestRect.top; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_put_DestinationHeight(IBasicVideo *iface, LONG DestinationHeight) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); DestRect.right = DestRect.left + DestinationHeight; This->pFuncsTable->pfnSetTargetRect(This, &DestRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_get_DestinationHeight(IBasicVideo *iface, LONG *pDestinationHeight) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); *pDestinationHeight = DestRect.right - DestRect.left; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_SetSourcePosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); SourceRect.left = Left; SourceRect.top = Top; SourceRect.right = Left + Width; SourceRect.bottom = Top + Height; This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_GetSourcePosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight) { RECT SourceRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); *pLeft = SourceRect.left; *pTop = SourceRect.top; *pWidth = SourceRect.right - SourceRect.left; *pHeight = SourceRect.bottom - SourceRect.top; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_SetDefaultSourcePosition(IBasicVideo *iface) { BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->()\n", This, iface); return This->pFuncsTable->pfnSetDefaultSourceRect(This); } HRESULT WINAPI BaseControlVideoImpl_SetDestinationPosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); DestRect.left = Left; DestRect.top = Top; DestRect.right = Left + Width; DestRect.bottom = Top + Height; This->pFuncsTable->pfnSetTargetRect(This, &DestRect); return S_OK; } HRESULT WINAPI BaseControlVideoImpl_GetDestinationPosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight) { RECT DestRect; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); This->pFuncsTable->pfnGetTargetRect(This, &DestRect); *pLeft = DestRect.left; *pTop = DestRect.top; *pWidth = DestRect.right - DestRect.left; *pHeight = DestRect.bottom - DestRect.top; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_SetDefaultDestinationPosition(IBasicVideo *iface) { BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->()\n", This, iface); return This->pFuncsTable->pfnSetDefaultTargetRect(This); } HRESULT WINAPI BaseControlVideoImpl_GetVideoSize(IBasicVideo *iface, LONG *pWidth, LONG *pHeight) { VIDEOINFOHEADER *vih; BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); vih = This->pFuncsTable->pfnGetVideoFormat(This); *pHeight = vih->bmiHeader.biHeight; *pWidth = vih->bmiHeader.biWidth; return S_OK; } HRESULT WINAPI BaseControlVideoImpl_GetVideoPaletteEntries(IBasicVideo *iface, LONG StartIndex, LONG Entries, LONG *pRetrieved, LONG *pPalette) { BaseControlVideo *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette); if (pRetrieved) *pRetrieved = 0; return VFW_E_NO_PALETTE_AVAILABLE; } HRESULT WINAPI BaseControlVideoImpl_GetCurrentImage(IBasicVideo *iface, LONG *pBufferSize, LONG *pDIBImage) { BaseControlVideo *This = impl_from_IBasicVideo(iface); return This->pFuncsTable->pfnGetStaticImage(This, pBufferSize, pDIBImage); } HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultSource(IBasicVideo *iface) { BaseControlVideo *This = impl_from_IBasicVideo(iface); return This->pFuncsTable->pfnIsDefaultSourceRect(This); } HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultDestination(IBasicVideo *iface) { BaseControlVideo *This = impl_from_IBasicVideo(iface); return This->pFuncsTable->pfnIsDefaultTargetRect(This); }