Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

353 lines
12 KiB

  1. //==========================================================================;
  2. // MSVidVideoRenderer.h : Declaration of the CMSVidVideoRenderer
  3. // copyright (c) Microsoft Corp. 1998-1999.
  4. //==========================================================================;
  5. #ifndef __MSVidVIDEORENDERER_H_
  6. #define __MSVidVIDEORENDERER_H_
  7. #pragma once
  8. #include <algorithm>
  9. #include <evcode.h>
  10. #include <uuids.h>
  11. #include <amvideo.h>
  12. #include <strmif.h>
  13. #include <objectwithsiteimplsec.h>
  14. #include "vidrect.h"
  15. #include "vidvidimpl.h"
  16. #include "vrsegimpl.h"
  17. #include "devimpl.h"
  18. #include "seg.h"
  19. #include "videorenderercp.h"
  20. #include "strmif.h"
  21. #include "resource.h" // main symbols
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CMSVidVideoRenderer
  24. class ATL_NO_VTABLE __declspec(uuid("37B03543-A4C8-11d2-B634-00C04F79498E")) CMSVidVideoRenderer :
  25. public CComObjectRootEx<CComSingleThreadModel>,
  26. public CComCoClass<CMSVidVideoRenderer, &__uuidof(CMSVidVideoRenderer)>,
  27. public IObjectWithSiteImplSec<CMSVidVideoRenderer>,
  28. public ISupportErrorInfo,
  29. public CProxy_IMSVidVideoRenderer<CMSVidVideoRenderer>,
  30. public IConnectionPointContainerImpl<CMSVidVideoRenderer>,
  31. public IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>,
  32. public IProvideClassInfo2Impl<&CLSID_MSVidVideoRenderer, &IID_IMSVidVideoRendererEvent, &LIBID_MSVidCtlLib>
  33. {
  34. public:
  35. CMSVidVideoRenderer()
  36. {
  37. m_APid = -1;
  38. m_compositorGuid = GUID_NULL;
  39. m_opacity = -1;
  40. m_rectPosition.top = -1;
  41. m_rectPosition.left = -1;
  42. m_rectPosition.bottom = -1;
  43. m_rectPosition.right = -1;
  44. m_SourceSize = sslFullSize;
  45. m_lOverScan = 1;
  46. }
  47. virtual ~CMSVidVideoRenderer() {
  48. m_PQIPicture.Release();
  49. CleanupVMR();
  50. }
  51. REGISTER_AUTOMATION_OBJECT(IDS_PROJNAME,
  52. IDS_REG_VIDEORENDERER_PROGID,
  53. IDS_REG_VIDEORENDERER_DESC,
  54. LIBID_MSVidCtlLib,
  55. __uuidof(CMSVidVideoRenderer));
  56. DECLARE_PROTECT_FINAL_CONSTRUCT()
  57. BEGIN_COM_MAP(CMSVidVideoRenderer)
  58. COM_INTERFACE_ENTRY(IMSVidVideoRenderer)
  59. COM_INTERFACE_ENTRY(IMSVidVRGraphSegment)
  60. COM_INTERFACE_ENTRY(IMSVidGraphSegment)
  61. COM_INTERFACE_ENTRY(IMSVidVideoRenderer2)
  62. COM_INTERFACE_ENTRY(IMSVidOutputDevice)
  63. COM_INTERFACE_ENTRY(IMSVidDevice)
  64. COM_INTERFACE_ENTRY(IDispatch)
  65. COM_INTERFACE_ENTRY(IObjectWithSite)
  66. COM_INTERFACE_ENTRY(IConnectionPointContainer)
  67. COM_INTERFACE_ENTRY(ISupportErrorInfo)
  68. COM_INTERFACE_ENTRY(IPersist)
  69. COM_INTERFACE_ENTRY(IProvideClassInfo2)
  70. COM_INTERFACE_ENTRY(IProvideClassInfo)
  71. END_COM_MAP()
  72. BEGIN_CATEGORY_MAP(CMSVidVideoRenderer)
  73. IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
  74. IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
  75. IMPLEMENTED_CATEGORY(CATID_PersistsToPropertyBag)
  76. END_CATEGORY_MAP()
  77. BEGIN_CONNECTION_POINT_MAP(CMSVidVideoRenderer)
  78. // CONNECTION_POINT_ENTRY(IID_IMSVidVideoRendererEvent2)
  79. CONNECTION_POINT_ENTRY(IID_IMSVidVideoRendererEvent)
  80. END_CONNECTION_POINT_MAP()
  81. // ISupportsErrorInfo
  82. protected:
  83. DSPinList connectedPins;
  84. public:
  85. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
  86. // IMSVidDevice
  87. CComBSTR __declspec(property(get=GetName)) m_Name;
  88. CComBSTR GetName(void) {
  89. CString csName;
  90. if(m_iVideoRenderer != -1){
  91. csName = (m_Filters[m_iVideoRenderer]).GetName();
  92. }
  93. if (csName.IsEmpty()) {
  94. csName = _T("Video Mixing Renderer");
  95. }
  96. csName += _T(" Segment");
  97. return CComBSTR(csName);
  98. }
  99. STDMETHOD(get_Name)(BSTR * Name) {
  100. if (!m_fInit) {
  101. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  102. }
  103. if (Name == NULL)
  104. return E_POINTER;
  105. try {
  106. *Name = m_Name.Copy();
  107. } catch(...) {
  108. return E_POINTER;
  109. }
  110. return NOERROR;
  111. }
  112. STDMETHOD(get_Status)(LONG * Status) {
  113. if (!m_fInit) {
  114. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  115. }
  116. if (Status == NULL)
  117. return E_POINTER;
  118. return E_NOTIMPL;
  119. }
  120. STDMETHOD(get_Segment)(IMSVidGraphSegment * * pIMSVidGraphSegment)
  121. {
  122. if (!m_fInit) {
  123. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  124. }
  125. try {
  126. if (pIMSVidGraphSegment == NULL) {
  127. return E_POINTER;
  128. }
  129. *pIMSVidGraphSegment = reinterpret_cast<IMSVidGraphSegment*>(this);
  130. AddRef();
  131. return NOERROR;
  132. } catch(...) {
  133. return E_POINTER;
  134. }
  135. }
  136. STDMETHOD(put_SuppressEffects)(/*in*/ VARIANT_BOOL bSuppress);
  137. STDMETHOD(get_SuppressEffects)(/*out, retval*/ VARIANT_BOOL *bSuppress);
  138. // Methods to access the allocator presenter object in the vmr
  139. STDMETHOD(SetAllocator)(/*[in]*/ IUnknown *Allocator, long ID = -1){
  140. try{
  141. if(!Allocator){
  142. return _SetAllocator(NULL, ID);
  143. }
  144. PQVMRSAlloc qiAllocator(Allocator);
  145. if(!qiAllocator){
  146. _ASSERT(false);
  147. return E_UNEXPECTED;
  148. }
  149. return _SetAllocator(qiAllocator, ID);
  150. }
  151. catch(...){
  152. _ASSERT(false);
  153. return E_UNEXPECTED;
  154. }
  155. }
  156. STDMETHOD(_SetAllocator)(/*[in]*/ IVMRSurfaceAllocator *Allocator, long ID = -1){
  157. try{
  158. PQVMRSAlloc qiAllocator(Allocator);
  159. HRESULT hr = CleanupVMR();
  160. if(FAILED(hr)){
  161. return hr;
  162. }
  163. qiSurfAlloc = qiAllocator;
  164. m_APid = ID;
  165. return S_OK;
  166. }
  167. catch(...){
  168. _ASSERT(false);
  169. return E_UNEXPECTED;
  170. }
  171. }
  172. STDMETHOD(get_Allocator)(/*[in]*/ IUnknown **Allocator){
  173. try{
  174. if(!Allocator){
  175. return E_POINTER;
  176. }
  177. if(!qiSurfAlloc){
  178. return E_FAIL;
  179. }
  180. PUnknown retVal(qiSurfAlloc);
  181. if(!retVal){
  182. _ASSERT(false);
  183. return E_UNEXPECTED;
  184. }
  185. *Allocator = retVal.Detach();
  186. _ASSERT(Allocator);
  187. return S_OK;
  188. }
  189. catch(...){
  190. _ASSERT(false);
  191. return E_UNEXPECTED;
  192. }
  193. }
  194. STDMETHOD(get__Allocator)(/*[in]*/ IVMRSurfaceAllocator **Allocator){
  195. try{
  196. if(!Allocator){
  197. return E_POINTER;
  198. }
  199. if(!qiSurfAlloc){
  200. return E_FAIL; // should be un-inited failure
  201. }
  202. PQVMRSAlloc qiAllocator(qiSurfAlloc);
  203. if(!qiAllocator){
  204. _ASSERT(false);
  205. return E_UNEXPECTED;
  206. }
  207. *Allocator = qiAllocator.Detach();
  208. _ASSERT(Allocator);
  209. return S_OK;
  210. }
  211. catch(...){
  212. _ASSERT(false);
  213. return E_UNEXPECTED;
  214. }
  215. }
  216. STDMETHOD(get_Allocator_ID)(long *ID){
  217. try{
  218. if(!ID){
  219. return E_POINTER;
  220. }
  221. *ID = m_APid;
  222. return S_OK;
  223. }
  224. catch(...){
  225. _ASSERT(false);
  226. return E_UNEXPECTED;
  227. }
  228. }
  229. STDMETHOD(OnEventNotify)(LONG lEventCode, LONG_PTR lEventParm1, LONG_PTR lEventParm2){
  230. if (lEventCode == EC_VMR_RENDERDEVICE_SET) {
  231. VARIANT_BOOL fUsingOverlay;
  232. get_UsingOverlay(&fUsingOverlay);
  233. if (fUsingOverlay == VARIANT_TRUE && !(lEventParm1 & VMR_RENDER_DEVICE_OVERLAY)) {
  234. put_UsingOverlay(VARIANT_FALSE);
  235. Fire_OverlayUnavailable();
  236. ReComputeSourceRect();
  237. return NOERROR;
  238. }
  239. }
  240. if (lEventCode == EC_VMR_RENDERDEVICE_SET ||
  241. lEventCode == EC_VIDEO_SIZE_CHANGED) {
  242. ReComputeSourceRect();
  243. }
  244. return E_NOTIMPL;
  245. }
  246. STDMETHOD(PostStop)(){
  247. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop()"), "");
  248. HRESULT hr = IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>::PostStop();
  249. if(FAILED(hr)){
  250. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() base class PostStop failed; hr = " << std::hex << hr), "");
  251. return hr;
  252. }
  253. // need stestrops fix for deallocate on stop
  254. DSFilter sp_VMR = m_Filters[m_iVideoRenderer];
  255. if(!sp_VMR){
  256. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() could not get vmr filter"), "");
  257. return E_UNEXPECTED;
  258. }
  259. int i = 0;
  260. for(DSFilter::iterator pin = sp_VMR.begin(); pin != sp_VMR.end(); ++pin, ++i){
  261. if( (*pin).IsConnected()){
  262. hr = (*pin).Disconnect();
  263. if(FAILED(hr)){
  264. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() disconnect failed; hr = " << std::hex << hr), "");
  265. return hr;
  266. }
  267. }
  268. }
  269. #ifdef _WIN64
  270. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() NumPins: " << (long)connectedPins.size() << " pins."), "");
  271. #endif
  272. return S_OK;
  273. }
  274. STDMETHOD(PreRun)(){
  275. HRESULT hr = IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>::PreRun();
  276. if(FAILED(hr)){
  277. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PreRun() base class PostStop failed; hr = " << std::hex << hr), "");
  278. return hr;
  279. }
  280. // need stestrops fix for deallocate on stop
  281. DSFilter sp_VMR = m_Filters[m_iVideoRenderer];
  282. if(!sp_VMR){
  283. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() could not get vmr filter"), "");
  284. return E_UNEXPECTED;
  285. }
  286. if(connectedPins.size() == 0){ // if the pin list is empty rebuild it otherwise reconnect the pins
  287. int i = 0;
  288. for(DSFilter::iterator pin = sp_VMR.begin(); pin != sp_VMR.end(); ++pin, ++i){
  289. if( (*pin).IsConnected()){
  290. connectedPins.push_back((*pin).GetConnection());
  291. }
  292. }
  293. #ifndef _WIN64
  294. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() Storing: " << connectedPins.size() << " pins."), "");
  295. #endif
  296. }
  297. else{
  298. DSFilter::iterator vmrPin = sp_VMR.begin();
  299. for(DSPinList::iterator pin = connectedPins.begin(); pin != connectedPins.end() && vmrPin != sp_VMR.end(); ++pin, ++vmrPin){
  300. if(!(*vmrPin).IsConnected()){
  301. hr = (*vmrPin).Connect(*pin);
  302. if(FAILED(hr)){
  303. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PreRun() connect failed; hr = " << std::hex << hr), "");
  304. return hr;
  305. }
  306. }
  307. else{
  308. _ASSERT((*vmrPin).GetConnection() != (*pin));
  309. }
  310. }
  311. }
  312. return S_OK;
  313. }
  314. STDMETHOD(Decompose)(){
  315. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::Decompose() killing pin list"), "");
  316. connectedPins.clear();
  317. HRESULT hr = IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>::Decompose();
  318. if(FAILED(hr) && hr != E_NOTIMPL){
  319. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PreRun() base class Decompose failed; hr = " << std::hex << hr), "");
  320. return hr;
  321. }
  322. return S_OK;
  323. }
  324. #if 0
  325. STDMETHOD(get__CustomCompositorClass)(/*[out, retval]*/ GUID* CompositorCLSID) {
  326. return IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>::get__CustomCompositorClass(CompositorCLSID);
  327. }
  328. #endif
  329. };
  330. #endif //__MSVidVIDEORENDERER_H_