[56] | 1 | //////////////////////////////////////////////////////////// |
---|
[335] | 2 | // Copyright (C) Roman Ryltsov, 2008-2014 |
---|
[56] | 3 | // Created by Roman Ryltsov roman@alax.info |
---|
| 4 | |
---|
| 5 | #pragma once |
---|
| 6 | |
---|
| 7 | #include <dxgi.h> |
---|
| 8 | #include "AboutDialog.h" |
---|
| 9 | #include <dshow.h> |
---|
| 10 | #include <d3d9.h> |
---|
| 11 | #include <vmr9.h> |
---|
| 12 | #include <evr.h> |
---|
| 13 | #include <evr9.h> |
---|
| 14 | #include "rodshow.h" |
---|
| 15 | |
---|
| 16 | #pragma comment(lib, "dxgi.lib") |
---|
| 17 | |
---|
| 18 | //////////////////////////////////////////////////////////// |
---|
[174] | 19 | // CVmr7Window |
---|
| 20 | |
---|
| 21 | class CVmr7Window : |
---|
| 22 | public CControlWindowT<CVmr7Window> |
---|
| 23 | { |
---|
| 24 | public: |
---|
| 25 | |
---|
| 26 | BEGIN_MSG_MAP_EX(CVmr7Window) |
---|
| 27 | //CHAIN_MSG_MAP(CControlWindowT<CVmr7Window>) |
---|
| 28 | MSG_WM_ERASEBKGND(OnEraseBkgnd) |
---|
| 29 | MSG_WM_PAINT(OnPaint) |
---|
| 30 | MSG_WM_DISPLAYCHANGE(OnDisplayChange) |
---|
| 31 | MSG_WM_SIZE(OnSize) |
---|
| 32 | MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk) |
---|
| 33 | END_MSG_MAP() |
---|
| 34 | |
---|
| 35 | public: |
---|
| 36 | CComPtr<IBaseFilter> m_pBaseFilter; |
---|
| 37 | CComPtr<IVMRWindowlessControl> m_pVmrWindowlessControl; |
---|
| 38 | |
---|
| 39 | public: |
---|
| 40 | // CVmr7Window |
---|
| 41 | static CLSID GetRendererClassIdentifier() throw() |
---|
| 42 | { |
---|
| 43 | return CLSID_VideoMixingRenderer; |
---|
| 44 | } |
---|
| 45 | static CComPtr<IBaseFilter> CoCreateBaseFilterInstance() |
---|
| 46 | { |
---|
| 47 | CComPtr<IBaseFilter> pBaseFilter; |
---|
| 48 | __C(pBaseFilter.CoCreateInstance(GetRendererClassIdentifier())); |
---|
| 49 | return pBaseFilter; |
---|
| 50 | } |
---|
| 51 | VOID Initialize(IBaseFilter* pBaseFilter) |
---|
| 52 | { |
---|
| 53 | _A(pBaseFilter); |
---|
| 54 | _A(!m_pBaseFilter && !m_pVmrWindowlessControl); |
---|
| 55 | m_pBaseFilter = pBaseFilter; |
---|
| 56 | const CComQIPtr<IVMRFilterConfig> pVmrFilterConfig = pBaseFilter; |
---|
| 57 | __D(pVmrFilterConfig, E_NOINTERFACE); |
---|
| 58 | __C(pVmrFilterConfig->SetRenderingMode(VMRMode_Windowless)); |
---|
| 59 | m_pVmrWindowlessControl = CComQIPtr<IVMRWindowlessControl>(m_pBaseFilter); |
---|
| 60 | __D(m_pVmrWindowlessControl, E_NOINTERFACE); |
---|
| 61 | __C(m_pVmrWindowlessControl->SetVideoClippingWindow(m_hWnd)); |
---|
| 62 | CRect VideoPosition = GetVideoPosition(); |
---|
| 63 | _Z4(atlTraceGeneral, 4, _T(".m_pVmrWindowlessControl 0x%p, VideoPosition at (%d, %d) size (%d, %d)\n"), m_pVmrWindowlessControl, VideoPosition.left, VideoPosition.top, VideoPosition.Width(), VideoPosition.Height()); |
---|
| 64 | __C(m_pVmrWindowlessControl->SetVideoPosition(NULL, VideoPosition)); |
---|
| 65 | } |
---|
| 66 | VOID Terminate() throw() |
---|
| 67 | { |
---|
| 68 | m_pBaseFilter = NULL; |
---|
| 69 | m_pVmrWindowlessControl = NULL; |
---|
| 70 | } |
---|
| 71 | CRect GetVideoPosition() const throw() |
---|
| 72 | { |
---|
| 73 | CRect Position; |
---|
| 74 | _W(GetClientRect(Position)); |
---|
| 75 | return Position; |
---|
| 76 | } |
---|
| 77 | |
---|
| 78 | // Window Message Handlers |
---|
| 79 | LRESULT OnEraseBkgnd(CDCHandle Dc) |
---|
| 80 | { |
---|
| 81 | Dc; |
---|
| 82 | if(m_pVmrWindowlessControl) |
---|
| 83 | { |
---|
| 84 | return TRUE; |
---|
| 85 | } else |
---|
| 86 | SetMsgHandled(FALSE); |
---|
| 87 | return 0; |
---|
| 88 | } |
---|
| 89 | LRESULT OnPaint(CDCHandle) |
---|
| 90 | { |
---|
| 91 | if(m_pVmrWindowlessControl) |
---|
| 92 | { |
---|
| 93 | CPaintDC Dc(m_hWnd); |
---|
| 94 | const HRESULT nRepaintVideoResult = m_pVmrWindowlessControl->RepaintVideo(m_hWnd, Dc); |
---|
| 95 | _Z45_HRESULT(nRepaintVideoResult); |
---|
| 96 | } else |
---|
| 97 | SetMsgHandled(FALSE); |
---|
| 98 | return 0; |
---|
| 99 | } |
---|
| 100 | LRESULT OnDisplayChange(UINT nDepth, CSize Extent) |
---|
| 101 | { |
---|
| 102 | if(m_pVmrWindowlessControl) |
---|
| 103 | { |
---|
| 104 | const HRESULT nDisplayModeChangedResult = m_pVmrWindowlessControl->DisplayModeChanged(); |
---|
| 105 | _Z45_HRESULT(nDisplayModeChangedResult); |
---|
| 106 | } |
---|
| 107 | return 0; |
---|
| 108 | } |
---|
| 109 | LRESULT OnSize(UINT nType, CSize) |
---|
| 110 | { |
---|
| 111 | if(nType != SIZE_MINIMIZED) |
---|
| 112 | if(m_pVmrWindowlessControl) |
---|
| 113 | { |
---|
| 114 | CRect VideoPosition = GetVideoPosition(); |
---|
| 115 | const HRESULT nSetVideoPositionResult = m_pVmrWindowlessControl->SetVideoPosition(NULL, &VideoPosition); |
---|
| 116 | _Z45_HRESULT(nSetVideoPositionResult); |
---|
| 117 | } |
---|
| 118 | return 0; |
---|
| 119 | } |
---|
| 120 | LRESULT OnLButtonDblClk(UINT, CPoint) |
---|
| 121 | { |
---|
| 122 | COlePropertyFrameDialog Dialog(m_pBaseFilter, _T("VMR-7")); |
---|
| 123 | Dialog.SetObjectPages(); |
---|
| 124 | Dialog.DoModal(m_hWnd); |
---|
| 125 | return 0; |
---|
| 126 | } |
---|
| 127 | }; |
---|
| 128 | |
---|
| 129 | //////////////////////////////////////////////////////////// |
---|
[56] | 130 | // CEvrWindow |
---|
| 131 | |
---|
| 132 | class CEvrWindow : |
---|
| 133 | public CControlWindowT<CEvrWindow> |
---|
| 134 | { |
---|
| 135 | public: |
---|
| 136 | |
---|
| 137 | BEGIN_MSG_MAP_EX(CEvrWindow) |
---|
| 138 | //CHAIN_MSG_MAP(CControlWindowT<CEvrWindow>) |
---|
| 139 | MSG_WM_ERASEBKGND(OnEraseBkgnd) |
---|
| 140 | MSG_WM_PAINT(OnPaint) |
---|
| 141 | MSG_WM_SIZE(OnSize) |
---|
| 142 | MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk) |
---|
| 143 | END_MSG_MAP() |
---|
| 144 | |
---|
| 145 | public: |
---|
| 146 | CComPtr<IBaseFilter> m_pBaseFilter; |
---|
| 147 | CComPtr<IMFVideoDisplayControl> m_pMfVideoDisplayControl; |
---|
| 148 | |
---|
| 149 | public: |
---|
| 150 | // CEvrWindow |
---|
| 151 | static CLSID GetRendererClassIdentifier() throw() |
---|
| 152 | { |
---|
| 153 | return CLSID_EnhancedVideoRenderer; |
---|
| 154 | } |
---|
[166] | 155 | static CComPtr<IBaseFilter> CoCreateBaseFilterInstance() |
---|
| 156 | { |
---|
| 157 | CComPtr<IBaseFilter> pBaseFilter; |
---|
| 158 | HRESULT nCoCreateInstanceResult = pBaseFilter.CoCreateInstance(GetRendererClassIdentifier()); |
---|
| 159 | _Z45_HRESULT(nCoCreateInstanceResult); |
---|
| 160 | if(nCoCreateInstanceResult == REGDB_E_CLASSNOTREG) |
---|
| 161 | { |
---|
| 162 | #pragma region Windows XP Second Chance Instantiation |
---|
| 163 | HINSTANCE hInstance = CoLoadLibrary(CT2OLE(_T("evr.dll")), TRUE); |
---|
| 164 | if(hInstance) |
---|
| 165 | { |
---|
| 166 | _ATLTRY |
---|
| 167 | { |
---|
| 168 | typedef HRESULT (STDMETHODCALLTYPE *DLLGETCLASSOBJECT)(REFCLSID ClassIdentifier, REFIID InterfaceIdentifier, LPVOID* ppvObject); |
---|
| 169 | DLLGETCLASSOBJECT pDllGetClassObject = (DLLGETCLASSOBJECT) GetProcAddress(hInstance, "DllGetClassObject"); |
---|
| 170 | __E(pDllGetClassObject); |
---|
| 171 | CComPtr<IClassFactory> pClassFactory; |
---|
| 172 | __C((pDllGetClassObject)(GetRendererClassIdentifier(), __uuidof(IClassFactory), (VOID**) &pClassFactory)); |
---|
| 173 | _A(pClassFactory); |
---|
| 174 | const HRESULT nCreateInstanceResult = pClassFactory->CreateInstance(NULL, __uuidof(IBaseFilter), (VOID**) &pBaseFilter); |
---|
| 175 | _Z45_HRESULT(nCreateInstanceResult); |
---|
| 176 | if(SUCCEEDED(nCreateInstanceResult)) |
---|
| 177 | nCoCreateInstanceResult = nCreateInstanceResult; |
---|
| 178 | } |
---|
| 179 | _ATLCATCHALL() |
---|
| 180 | { |
---|
| 181 | _Z_EXCEPTION(); |
---|
| 182 | } |
---|
| 183 | //CoFreeLibrary(hInstance); |
---|
| 184 | } |
---|
| 185 | #pragma endregion |
---|
| 186 | } |
---|
| 187 | __C(nCoCreateInstanceResult); |
---|
| 188 | return pBaseFilter; |
---|
| 189 | } |
---|
[56] | 190 | VOID Initialize(IBaseFilter* pBaseFilter) |
---|
| 191 | { |
---|
| 192 | _A(pBaseFilter); |
---|
| 193 | _A(!m_pBaseFilter && !m_pMfVideoDisplayControl); |
---|
| 194 | m_pBaseFilter = pBaseFilter; |
---|
| 195 | CComQIPtr<IMFGetService> pMfGetInterface = pBaseFilter; |
---|
| 196 | CComPtr<IMFVideoDisplayControl> pMfVideoDisplayControl; |
---|
| 197 | __C(pMfGetInterface->GetService(MR_VIDEO_RENDER_SERVICE, __uuidof(IMFVideoDisplayControl), (VOID**) &pMfVideoDisplayControl)); |
---|
| 198 | _A(pMfVideoDisplayControl); |
---|
| 199 | m_pMfVideoDisplayControl = pMfVideoDisplayControl; |
---|
| 200 | __C(pMfVideoDisplayControl->SetVideoWindow(m_hWnd)); |
---|
| 201 | CRect VideoPosition = GetVideoPosition(); |
---|
| 202 | _Z4(atlTraceGeneral, 4, _T("pMfVideoDisplayControl 0x%p, VideoPosition at (%d, %d) size (%d, %d)\n"), pMfVideoDisplayControl, VideoPosition.left, VideoPosition.top, VideoPosition.Width(), VideoPosition.Height()); |
---|
| 203 | __C(pMfVideoDisplayControl->SetVideoPosition(NULL, VideoPosition)); |
---|
| 204 | //__C(pMfVideoDisplayControl->SetAspectRatioMode(MFVideoARMode_None)); // As opposed to default MFVideoARMode_Picture - disable letterboxing |
---|
| 205 | } |
---|
| 206 | VOID Terminate() throw() |
---|
| 207 | { |
---|
| 208 | m_pBaseFilter = NULL; |
---|
| 209 | m_pMfVideoDisplayControl = NULL; |
---|
| 210 | } |
---|
| 211 | CRect GetVideoPosition() const throw() |
---|
| 212 | { |
---|
| 213 | CRect Position; |
---|
| 214 | _W(GetClientRect(Position)); |
---|
| 215 | return Position; |
---|
| 216 | } |
---|
| 217 | |
---|
| 218 | // Window Message Handlers |
---|
| 219 | LRESULT OnEraseBkgnd(CDCHandle Dc) |
---|
| 220 | { |
---|
| 221 | Dc; |
---|
| 222 | if(m_pMfVideoDisplayControl) |
---|
| 223 | { |
---|
| 224 | return TRUE; |
---|
| 225 | } else |
---|
| 226 | SetMsgHandled(FALSE); |
---|
| 227 | return 0; |
---|
| 228 | } |
---|
| 229 | LRESULT OnPaint(CDCHandle) |
---|
| 230 | { |
---|
| 231 | if(m_pMfVideoDisplayControl) |
---|
| 232 | { |
---|
| 233 | CPaintDC Dc(m_hWnd); |
---|
| 234 | const HRESULT nRepaintVideoResult = m_pMfVideoDisplayControl->RepaintVideo(); |
---|
| 235 | _Z4(atlTraceUI, SUCCEEDED(nRepaintVideoResult) ? 6 : 4, _T("nRepaintVideoResult 0x%08x\n"), nRepaintVideoResult); |
---|
| 236 | } else |
---|
| 237 | SetMsgHandled(FALSE); |
---|
| 238 | return 0; |
---|
| 239 | } |
---|
| 240 | LRESULT OnSize(UINT nType, CSize) |
---|
| 241 | { |
---|
| 242 | if(nType != SIZE_MINIMIZED) |
---|
| 243 | if(m_pMfVideoDisplayControl) |
---|
| 244 | { |
---|
| 245 | CRect VideoPosition = GetVideoPosition(); |
---|
| 246 | const HRESULT nSetVideoPositionResult = m_pMfVideoDisplayControl->SetVideoPosition(NULL, &VideoPosition); |
---|
| 247 | _Z4(atlTraceUI, SUCCEEDED(nSetVideoPositionResult) ? 6 : 4, _T("nSetVideoPositionResult 0x%08x\n"), nSetVideoPositionResult); |
---|
| 248 | } |
---|
| 249 | return 0; |
---|
| 250 | } |
---|
| 251 | LRESULT OnLButtonDblClk(UINT, CPoint Position) |
---|
| 252 | { |
---|
[174] | 253 | COlePropertyFrameDialog Dialog(m_pBaseFilter, _T("EVR")); |
---|
[56] | 254 | Dialog.SetObjectPages(); |
---|
| 255 | Dialog.DoModal(m_hWnd); |
---|
| 256 | return 0; |
---|
| 257 | } |
---|
| 258 | }; |
---|
| 259 | |
---|
| 260 | //////////////////////////////////////////////////////////// |
---|
[174] | 261 | // CBaseVideoDialog |
---|
[56] | 262 | |
---|
[174] | 263 | class CBaseVideoDialog |
---|
[56] | 264 | { |
---|
| 265 | public: |
---|
[174] | 266 | // CBaseVideoDialog |
---|
| 267 | virtual HWND Create(HWND hParentWindow) = 0; |
---|
| 268 | virtual BOOL DestroyWindow() = 0; |
---|
| 269 | virtual BOOL IsWindow() = 0; |
---|
| 270 | virtual BOOL MoveWindow(const CRect& Position) = 0; |
---|
| 271 | virtual INT ShowWindow(INT nShowCommand) = 0; |
---|
| 272 | }; |
---|
| 273 | |
---|
| 274 | //////////////////////////////////////////////////////////// |
---|
| 275 | // CVideoDialogT |
---|
| 276 | |
---|
| 277 | template <typename T, typename CVrWindow, LPCTSTR* t_ppszType> |
---|
| 278 | class CVideoDialogT : |
---|
| 279 | public CDialogImpl<T>, |
---|
| 280 | public CDialogResize<T>, |
---|
| 281 | public CBaseVideoDialog |
---|
| 282 | { |
---|
| 283 | typedef CVideoDialogT<T, CVrWindow, t_ppszType> CVideoDialog; |
---|
| 284 | |
---|
| 285 | public: |
---|
[56] | 286 | enum { IDD = IDD_VIDEO }; |
---|
| 287 | |
---|
| 288 | BEGIN_MSG_MAP_EX(CVideoDialog) |
---|
| 289 | //CHAIN_MSG_MAP(CDialogImpl<CVideoDialog>) |
---|
[174] | 290 | CHAIN_MSG_MAP(CDialogResize<T>) |
---|
[56] | 291 | MSG_WM_INITDIALOG(OnInitDialog) |
---|
| 292 | MSG_WM_DESTROY(OnDestroy) |
---|
| 293 | COMMAND_ID_HANDLER_EX(IDCANCEL, OnCommand) |
---|
| 294 | COMMAND_ID_HANDLER_EX(IDC_VIDEO_RUN, OnRunButtonClicked) |
---|
| 295 | COMMAND_ID_HANDLER_EX(IDC_VIDEO_PAUSE, OnPauseButtonClicked) |
---|
| 296 | COMMAND_ID_HANDLER_EX(IDC_VIDEO_STOP, OnStopButtonClicked) |
---|
| 297 | MESSAGE_HANDLER_EX(WM_FILTERGRAPHEVENT, OnFilterGraphEvent) |
---|
| 298 | END_MSG_MAP() |
---|
| 299 | |
---|
| 300 | BEGIN_DLGRESIZE_MAP(CVideoDialog) |
---|
| 301 | DLGRESIZE_CONTROL(IDC_VIDEO_AREA, DLSZ_SIZE_X | DLSZ_SIZE_Y) |
---|
| 302 | DLGRESIZE_CONTROL(IDC_VIDEO_RUN, DLSZ_MOVE_Y) |
---|
| 303 | DLGRESIZE_CONTROL(IDC_VIDEO_PAUSE, DLSZ_MOVE_Y) |
---|
| 304 | DLGRESIZE_CONTROL(IDC_VIDEO_STOP, DLSZ_MOVE_Y) |
---|
| 305 | DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y) |
---|
| 306 | END_DLGRESIZE_MAP() |
---|
| 307 | |
---|
| 308 | public: |
---|
| 309 | |
---|
| 310 | //////////////////////////////////////////////////////// |
---|
| 311 | // Window Message Identifiers |
---|
| 312 | |
---|
| 313 | enum |
---|
| 314 | { |
---|
| 315 | WM_FIRST = WM_APP, |
---|
| 316 | WM_FILTERGRAPHEVENT, |
---|
| 317 | }; |
---|
| 318 | |
---|
| 319 | //////////////////////////////////////////////////////// |
---|
| 320 | // CSourceFilter |
---|
| 321 | |
---|
| 322 | class ATL_NO_VTABLE CSourceFilter : |
---|
| 323 | public CComObjectRootEx<CComMultiThreadModelNoCS>, |
---|
| 324 | public CComCoClass<CSourceFilter>, |
---|
| 325 | public CPushSourceFilterT<CSourceFilter>, |
---|
| 326 | public CBasePersistT<CSourceFilter>, |
---|
| 327 | public CAmFilterMiscFlagsT<CSourceFilter, AM_FILTER_MISC_FLAGS_IS_SOURCE> |
---|
| 328 | { |
---|
| 329 | public: |
---|
| 330 | |
---|
| 331 | DECLARE_NO_REGISTRY() |
---|
| 332 | |
---|
| 333 | DECLARE_PROTECT_FINAL_CONSTRUCT() |
---|
| 334 | |
---|
| 335 | //DECLARE_QI_TRACE(CSourceFilter) |
---|
| 336 | |
---|
| 337 | BEGIN_COM_MAP(CSourceFilter) |
---|
| 338 | COM_INTERFACE_ENTRY(IBaseFilter) |
---|
| 339 | COM_INTERFACE_ENTRY(IMediaFilter) |
---|
| 340 | COM_INTERFACE_ENTRY_IID(__uuidof(IPersist), IBaseFilter) |
---|
| 341 | COM_INTERFACE_ENTRY(IAMFilterMiscFlags) |
---|
| 342 | END_COM_MAP() |
---|
| 343 | |
---|
| 344 | public: |
---|
| 345 | |
---|
| 346 | //////////////////////////////////////////////////////// |
---|
| 347 | // COutputPin |
---|
| 348 | |
---|
| 349 | class ATL_NO_VTABLE COutputPin : |
---|
| 350 | public CComObjectRootEx<CComMultiThreadModelNoCS>, |
---|
| 351 | public CPushSourceFilterT<CSourceFilter>::COutputPinT<COutputPin, CSourceFilter, CThreadContext>, |
---|
| 352 | public CAmPushSourceT<COutputPin, 0> |
---|
| 353 | { |
---|
| 354 | public: |
---|
| 355 | |
---|
| 356 | //DECLARE_QI_TRACE(CSourceFilter::COutputPin) |
---|
| 357 | |
---|
| 358 | BEGIN_COM_MAP(COutputPin) |
---|
| 359 | COM_INTERFACE_ENTRY(IPin) |
---|
| 360 | COM_INTERFACE_ENTRY(IAMPushSource) |
---|
| 361 | COM_INTERFACE_ENTRY(IAMLatency) |
---|
| 362 | END_COM_MAP() |
---|
| 363 | |
---|
| 364 | public: |
---|
| 365 | // COutputPin |
---|
| 366 | COutputPin() throw() |
---|
| 367 | { |
---|
| 368 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
| 369 | } |
---|
| 370 | ~COutputPin() throw() |
---|
| 371 | { |
---|
| 372 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
| 373 | } |
---|
| 374 | VOID EnumerateMediaTypes(CAtlList<CMediaType>& MediaTypeList) |
---|
| 375 | { |
---|
| 376 | //CRoCriticalSectionLock DataLock(GetDataCriticalSection()); |
---|
| 377 | _W(MediaTypeList.AddTail(GetFilter()->m_pRequestedMediaType)); |
---|
| 378 | } |
---|
| 379 | BOOL CheckMediaType(const CMediaType& pMediaType) const throw() |
---|
| 380 | { |
---|
| 381 | _A(pMediaType); |
---|
| 382 | //CRoCriticalSectionLock DataLock(GetDataCriticalSection()); |
---|
| 383 | _A(GetFilter()->m_pRequestedMediaType); |
---|
| 384 | return CVideoInfoHeader::Compare(&GetFilter()->m_pRequestedMediaType.GetCompatibleVideoInfoHeader(), &pMediaType.GetCompatibleVideoInfoHeader(), FALSE); |
---|
| 385 | } |
---|
| 386 | BOOL DecideMemAllocatorProperties(IMemAllocator* pMemAllocator, ALLOCATOR_PROPERTIES Properties) throw() |
---|
| 387 | { |
---|
| 388 | static const SIZE_T g_nMiminalBufferCount = 8; |
---|
| 389 | Properties.cBuffers = max(Properties.cBuffers, (LONG) g_nMiminalBufferCount); |
---|
| 390 | CRoCriticalSectionLock DataLock(GetDataCriticalSection()); |
---|
| 391 | const CMediaType& pMediaType = GetMediaTypeReference(); |
---|
| 392 | const CVideoInfoHeader VideoInfoHeader = pMediaType.GetCompatibleVideoInfoHeader(); |
---|
| 393 | const CSize Extent = VideoInfoHeader.GetExtent(); |
---|
| 394 | SIZE_T nBufferSize; |
---|
| 395 | if(Extent.cx >= 1080) |
---|
| 396 | { |
---|
| 397 | // NOTE: At higher resolutions we are good to go with much smaller buffers |
---|
| 398 | static const UINT g_nPixelBitCount = 7; |
---|
| 399 | nBufferSize = Extent.cy * Extent.cx * g_nPixelBitCount / 8; |
---|
| 400 | } else |
---|
| 401 | { |
---|
| 402 | static const UINT g_nPixelBitCount = 14; |
---|
| 403 | nBufferSize = Extent.cy * Extent.cx * g_nPixelBitCount / 8; |
---|
| 404 | } |
---|
| 405 | return SetMemAllocatorBufferSize(pMemAllocator, Properties, nBufferSize); |
---|
| 406 | } |
---|
| 407 | BOOL ComposeMediaSample(CThreadContext& ThreadContext, IMediaSample* pMediaSample) |
---|
| 408 | { |
---|
| 409 | CMediaSampleProperties OutputProperties(pMediaSample); |
---|
| 410 | #pragma region Dynamic Type Change |
---|
| 411 | if(OutputProperties.dwSampleFlags & AM_SAMPLE_TYPECHANGED) |
---|
| 412 | { |
---|
| 413 | _A(OutputProperties.pMediaType); |
---|
| 414 | _A(CheckMediaType(OutputProperties.pMediaType)); |
---|
| 415 | SetMediaType(OutputProperties.pMediaType); |
---|
| 416 | } else |
---|
| 417 | _A(!OutputProperties.pMediaType); |
---|
| 418 | #pragma endregion |
---|
| 419 | OutputProperties.dwTypeSpecificFlags = 0; |
---|
| 420 | OutputProperties.dwSampleFlags = 0; // AM_SAMPLE_DATADISCONTINUITY |
---|
| 421 | OutputProperties.lActual = GetMediaType().GetCompatibleVideoInfoHeader().GetDataSize(); |
---|
| 422 | OutputProperties.dwStreamId = 0; |
---|
| 423 | FillMemory(OutputProperties.pbBuffer, OutputProperties.lActual, rand() & 0xFF); |
---|
| 424 | OutputProperties.Set(); |
---|
| 425 | return TRUE; |
---|
| 426 | } |
---|
| 427 | }; |
---|
| 428 | |
---|
| 429 | private: |
---|
| 430 | CObjectPtr<COutputPin> m_pOutputPin; |
---|
| 431 | CMediaType m_pRequestedMediaType; |
---|
| 432 | |
---|
| 433 | public: |
---|
| 434 | // CSourceFilter |
---|
| 435 | CSourceFilter() throw() : |
---|
| 436 | CBasePersistT<CSourceFilter>(GetDataCriticalSection()) |
---|
| 437 | { |
---|
| 438 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
| 439 | } |
---|
| 440 | ~CSourceFilter() throw() |
---|
| 441 | { |
---|
| 442 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
| 443 | } |
---|
| 444 | HRESULT FinalConstruct() throw() |
---|
| 445 | { |
---|
| 446 | _ATLTRY |
---|
| 447 | { |
---|
| 448 | m_pOutputPin.Construct()->Initialize(this, L"Output"); |
---|
| 449 | AddPin(m_pOutputPin); |
---|
| 450 | } |
---|
| 451 | _ATLCATCH(Exception) |
---|
| 452 | { |
---|
| 453 | _C(Exception); |
---|
| 454 | } |
---|
| 455 | return S_OK; |
---|
| 456 | } |
---|
| 457 | VOID FinalRelease() throw() |
---|
| 458 | { |
---|
| 459 | m_pOutputPin = NULL; |
---|
| 460 | } |
---|
| 461 | VOID DeliverBeginFlush(IPin*) |
---|
| 462 | { |
---|
| 463 | m_pOutputPin->DeliverBeginFlush(); |
---|
| 464 | } |
---|
| 465 | VOID DeliverEndFlush(IPin*) |
---|
| 466 | { |
---|
| 467 | m_pOutputPin->DeliverEndFlush(); |
---|
| 468 | } |
---|
| 469 | VOID DeliverNewSegment(IPin*, REFERENCE_TIME nStartTime, REFERENCE_TIME nStopTime, DOUBLE fRate) |
---|
| 470 | { |
---|
| 471 | m_pOutputPin->DeliverNewSegment(nStartTime, nStopTime, fRate); |
---|
| 472 | } |
---|
| 473 | static BOOL CanCue() throw() |
---|
| 474 | { |
---|
| 475 | return FALSE; |
---|
| 476 | } |
---|
| 477 | VOID CueFilter() |
---|
| 478 | { |
---|
| 479 | m_pOutputPin->CuePin(); |
---|
| 480 | } |
---|
| 481 | VOID RunFilter(REFERENCE_TIME nStartTime) |
---|
| 482 | { |
---|
| 483 | m_pOutputPin->RunPin(nStartTime); |
---|
| 484 | } |
---|
| 485 | VOID PauseFilter() throw() |
---|
| 486 | { |
---|
| 487 | m_pOutputPin->PausePin(); |
---|
| 488 | } |
---|
| 489 | VOID StopFilter() throw() |
---|
| 490 | { |
---|
| 491 | m_pOutputPin->StopPin(); |
---|
| 492 | } |
---|
| 493 | const CObjectPtr<COutputPin>& GetOutputPin() const throw() |
---|
| 494 | { |
---|
| 495 | return m_pOutputPin; |
---|
| 496 | } |
---|
| 497 | VOID Initialize(CMediaType& pMediaType) |
---|
| 498 | { |
---|
| 499 | _A(!m_pRequestedMediaType && pMediaType); |
---|
| 500 | m_pRequestedMediaType = pMediaType; |
---|
| 501 | } |
---|
| 502 | }; |
---|
| 503 | |
---|
| 504 | private: |
---|
| 505 | CMediaType m_pMediaType; |
---|
| 506 | SIZE_T m_nLayout; |
---|
| 507 | CStatic m_AreaStatic; |
---|
| 508 | CGenericFilterGraph m_FilterGraph; |
---|
[174] | 509 | CRoArrayT<CVrWindow> m_VrWindowArray; |
---|
[56] | 510 | CButton m_RunButton; |
---|
| 511 | CButton m_PauseButton; |
---|
| 512 | CButton m_StopButton; |
---|
| 513 | |
---|
| 514 | CRect GetVideoPosition(const CRect& Position, SIZE_T nIndex) |
---|
| 515 | { |
---|
| 516 | CRect VideoPosition; |
---|
| 517 | VideoPosition.SetRectEmpty(); |
---|
| 518 | switch(m_nLayout) |
---|
| 519 | { |
---|
| 520 | case 0: // 1 |
---|
| 521 | if(nIndex < 1) |
---|
| 522 | VideoPosition = Position; |
---|
| 523 | break; |
---|
| 524 | case 1: // 4 |
---|
| 525 | case 2: // 9 |
---|
| 526 | case 3: // 16 |
---|
| 527 | case 4: // 25 |
---|
| 528 | case 5: // 36 |
---|
| 529 | if(nIndex < (m_nLayout + 1) * (m_nLayout + 1)) |
---|
| 530 | { |
---|
| 531 | const SIZE_T nZ = m_nLayout + 1; |
---|
| 532 | VideoPosition.left = (LONG) (Position.left + (Position.Width() - (nZ - 1) * Position.left) * (nIndex % nZ) / nZ + Position.left * (nIndex % nZ)); |
---|
| 533 | VideoPosition.top = (LONG) (Position.top + (Position.Height() - (nZ - 1) * Position.top) * (nIndex / nZ) / nZ + Position.top * (nIndex / nZ)); |
---|
| 534 | VideoPosition.right = (LONG) (VideoPosition.left + (Position.Width() - (nZ - 1) * Position.left) / nZ); |
---|
| 535 | VideoPosition.bottom = (LONG) (VideoPosition.top + (Position.Height() - (nZ - 1) * Position.top) / nZ); |
---|
| 536 | } |
---|
| 537 | break; |
---|
| 538 | //default: |
---|
| 539 | //VideoPosition.SetRectEmpty(); |
---|
| 540 | } |
---|
| 541 | _A(!VideoPosition.IsRectEmpty()); |
---|
| 542 | return VideoPosition; |
---|
| 543 | } |
---|
| 544 | CRect GetVideoPosition(SIZE_T nIndex) |
---|
| 545 | { |
---|
| 546 | CRect Position; |
---|
| 547 | _W(m_AreaStatic.GetWindowRect(Position)); |
---|
| 548 | _W(ScreenToClient(Position)); |
---|
| 549 | return GetVideoPosition(Position, nIndex); |
---|
| 550 | } |
---|
| 551 | VOID UpdateControls() |
---|
| 552 | { |
---|
| 553 | if(m_FilterGraph.m_pMediaControl) |
---|
| 554 | { |
---|
| 555 | OAFilterState State; |
---|
| 556 | if(SUCCEEDED(m_FilterGraph.m_pMediaControl->GetState(0, &State))) |
---|
| 557 | { |
---|
| 558 | m_RunButton.EnableWindow(State != State_Running); |
---|
| 559 | m_PauseButton.EnableWindow(State != State_Paused); |
---|
| 560 | m_StopButton.EnableWindow(State != State_Stopped); |
---|
| 561 | return; |
---|
| 562 | } |
---|
| 563 | } |
---|
| 564 | m_RunButton.EnableWindow(FALSE); |
---|
| 565 | m_PauseButton.EnableWindow(FALSE); |
---|
| 566 | m_StopButton.EnableWindow(FALSE); |
---|
| 567 | } |
---|
| 568 | |
---|
| 569 | public: |
---|
| 570 | // CVideoDialog |
---|
[174] | 571 | CVideoDialogT(const CMediaType& pMediaType, SIZE_T nLayout) : |
---|
[56] | 572 | m_pMediaType(pMediaType), |
---|
| 573 | m_nLayout(nLayout) |
---|
| 574 | { |
---|
| 575 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
| 576 | } |
---|
[174] | 577 | ~CVideoDialogT() throw() |
---|
[56] | 578 | { |
---|
| 579 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
| 580 | } |
---|
| 581 | |
---|
[174] | 582 | // CDialogImpl |
---|
| 583 | VOID OnFinalMessage(HWND) |
---|
| 584 | { |
---|
| 585 | T* pT = static_cast<T*>(this); |
---|
| 586 | delete pT; |
---|
| 587 | } |
---|
| 588 | |
---|
| 589 | // CBaseVideoDialog |
---|
| 590 | HWND Create(HWND hParentWindow) |
---|
| 591 | { |
---|
| 592 | return CDialogImpl<T>::Create(hParentWindow); |
---|
| 593 | } |
---|
| 594 | BOOL DestroyWindow() |
---|
| 595 | { |
---|
| 596 | return CDialogImpl<T>::DestroyWindow(); |
---|
| 597 | } |
---|
| 598 | BOOL IsWindow() |
---|
| 599 | { |
---|
| 600 | return CDialogImpl<T>::IsWindow(); |
---|
| 601 | } |
---|
| 602 | BOOL MoveWindow(const CRect& Position) |
---|
| 603 | { |
---|
| 604 | return CDialogImpl<T>::MoveWindow(Position); |
---|
| 605 | } |
---|
| 606 | INT ShowWindow(INT nShowCommand) |
---|
| 607 | { |
---|
| 608 | return CDialogImpl<T>::ShowWindow(nShowCommand); |
---|
| 609 | } |
---|
| 610 | |
---|
[56] | 611 | // CDialogResize |
---|
| 612 | VOID DlgResize_UpdateLayout(INT nWidth, INT nHeight) |
---|
| 613 | { |
---|
| 614 | __super::DlgResize_UpdateLayout(nWidth, nHeight); |
---|
| 615 | CRect Position; |
---|
| 616 | _W(m_AreaStatic.GetWindowRect(Position)); |
---|
| 617 | _W(ScreenToClient(Position)); |
---|
| 618 | CDeferWindowPos DeferWindowPos; |
---|
[174] | 619 | _W(DeferWindowPos.Begin((INT) m_VrWindowArray.GetCount())); |
---|
| 620 | for(SIZE_T nIndex = 0; nIndex < m_VrWindowArray.GetCount(); nIndex++) |
---|
| 621 | _W(DeferWindowPos.SetWindowPos(m_VrWindowArray[nIndex], NULL, GetVideoPosition(Position, nIndex), SWP_NOZORDER | SWP_NOACTIVATE)); |
---|
[56] | 622 | _W(DeferWindowPos.End()); |
---|
| 623 | } |
---|
| 624 | |
---|
| 625 | // Window Message Handelrs |
---|
| 626 | LRESULT OnInitDialog(HWND, LPARAM) |
---|
| 627 | { |
---|
| 628 | m_AreaStatic = GetDlgItem(IDC_VIDEO_AREA); |
---|
| 629 | m_AreaStatic.ShowWindow(SW_HIDE); |
---|
| 630 | m_RunButton = GetDlgItem(IDC_VIDEO_RUN); |
---|
| 631 | m_PauseButton = GetDlgItem(IDC_VIDEO_PAUSE); |
---|
| 632 | m_StopButton = GetDlgItem(IDC_VIDEO_STOP); |
---|
| 633 | DlgResize_Init(TRUE); |
---|
| 634 | UpdateControls(); |
---|
| 635 | m_FilterGraph.CoCreateInstance(); |
---|
| 636 | const SIZE_T nCount = (m_nLayout + 1) * (m_nLayout + 1); // 1, 4, 9, 16, ... |
---|
[174] | 637 | _A(m_VrWindowArray.IsEmpty()); |
---|
| 638 | _W(m_VrWindowArray.SetCount(0, (INT) nCount)); |
---|
[56] | 639 | for(SIZE_T nIndex = 0; nIndex < nCount; nIndex++) |
---|
| 640 | { |
---|
[174] | 641 | CVrWindow& VrWindow = m_VrWindowArray[m_VrWindowArray.Add()]; |
---|
| 642 | CComPtr<IBaseFilter> pBaseFilter = CVrWindow::CoCreateBaseFilterInstance(); |
---|
[56] | 643 | __C(m_FilterGraph->AddFilter(pBaseFilter, CT2CW(AtlFormatString(_T("Renderer %02d"), nIndex + 1)))); |
---|
[174] | 644 | VrWindow.Create(m_hWnd); |
---|
| 645 | VrWindow.ShowWindow(SW_SHOWNORMAL); |
---|
| 646 | VrWindow.Initialize(pBaseFilter); |
---|
[56] | 647 | CObjectPtr<CSourceFilter> pSourceFilter; |
---|
| 648 | pSourceFilter.Construct()->Initialize(m_pMediaType); |
---|
| 649 | __C(m_FilterGraph->AddFilter(pSourceFilter, CT2CW(AtlFormatString(_T("Source %02d"), nIndex + 1)))); |
---|
[174] | 650 | m_FilterGraph->Connect(pSourceFilter->GetOutputPin(), _FilterGraphHelper::GetFilterPin(VrWindow.m_pBaseFilter)); |
---|
[56] | 651 | } |
---|
| 652 | __C(m_FilterGraph.m_pMediaEventEx->SetNotifyWindow((OAHWND) m_hWnd, WM_FILTERGRAPHEVENT, (LONG_PTR) this)); |
---|
| 653 | UpdateControls(); |
---|
| 654 | CRect Position; |
---|
| 655 | _W(GetClientRect(Position)); |
---|
| 656 | DlgResize_UpdateLayout(Position.Width(), Position.Height()); |
---|
| 657 | CString sCaption; |
---|
| 658 | GetWindowText(sCaption); |
---|
| 659 | const CSize Extent = m_pMediaType.GetCompatibleVideoInfoHeader().GetExtent(); |
---|
[174] | 660 | SetWindowText(AtlFormatString(sCaption, nCount, *t_ppszType, Extent.cx, Extent.cy)); |
---|
[56] | 661 | return 0; |
---|
| 662 | } |
---|
| 663 | LRESULT OnDestroy() throw() |
---|
| 664 | { |
---|
| 665 | if(m_FilterGraph.m_pMediaControl) |
---|
| 666 | _V(m_FilterGraph.m_pMediaControl->Stop()); |
---|
[174] | 667 | for(SIZE_T nIndex = 0; nIndex < m_VrWindowArray.GetCount(); nIndex++) |
---|
| 668 | m_VrWindowArray[nIndex].Terminate(); |
---|
[56] | 669 | m_FilterGraph.Release(); |
---|
[174] | 670 | CWindow OwnerWindow = GetWindow(GW_OWNER); |
---|
| 671 | if(OwnerWindow.IsWindow()) |
---|
| 672 | OwnerWindow.SendMessage(WM_COMMAND, 'CL', (LPARAM) (CBaseVideoDialog*) this); |
---|
[56] | 673 | return 0; |
---|
| 674 | } |
---|
| 675 | LRESULT OnCommand(UINT, INT nIdentifier, HWND) |
---|
| 676 | { |
---|
| 677 | DestroyWindow(); |
---|
| 678 | return 0; |
---|
| 679 | } |
---|
| 680 | LRESULT OnRunButtonClicked(UINT, INT, HWND) |
---|
| 681 | { |
---|
| 682 | CWaitCursor WaitCursor; |
---|
| 683 | __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE); |
---|
| 684 | __C(m_FilterGraph.m_pMediaControl->Run()); |
---|
| 685 | UpdateControls(); |
---|
| 686 | return 0; |
---|
| 687 | } |
---|
| 688 | LRESULT OnPauseButtonClicked(UINT, INT, HWND) |
---|
| 689 | { |
---|
| 690 | CWaitCursor WaitCursor; |
---|
| 691 | __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE); |
---|
| 692 | __C(m_FilterGraph.m_pMediaControl->Pause()); |
---|
| 693 | UpdateControls(); |
---|
| 694 | return 0; |
---|
| 695 | } |
---|
| 696 | LRESULT OnStopButtonClicked(UINT, INT, HWND) |
---|
| 697 | { |
---|
| 698 | CWaitCursor WaitCursor; |
---|
| 699 | if(m_FilterGraph.m_pMediaControl) |
---|
| 700 | _V(m_FilterGraph.m_pMediaControl->Stop()); |
---|
| 701 | UpdateControls(); |
---|
| 702 | return 0; |
---|
| 703 | } |
---|
| 704 | LRESULT OnFilterGraphEvent(UINT, WPARAM, LPARAM) |
---|
| 705 | { |
---|
| 706 | if(!m_FilterGraph.m_pMediaEventEx) |
---|
| 707 | return 0; |
---|
| 708 | _ATLTRY |
---|
| 709 | { |
---|
| 710 | for(; ; ) |
---|
| 711 | { |
---|
| 712 | LONG nEventCode; |
---|
| 713 | LONG_PTR nParameter1, nParameter2; |
---|
| 714 | const HRESULT nGetEventResult = m_FilterGraph.m_pMediaEventEx->GetEvent(&nEventCode, &nParameter1, &nParameter2, 0); |
---|
| 715 | if(nGetEventResult == E_ABORT) |
---|
| 716 | break; |
---|
| 717 | __C(nGetEventResult); |
---|
| 718 | _ATLTRY |
---|
| 719 | { |
---|
| 720 | switch(nEventCode) |
---|
| 721 | { |
---|
| 722 | case EC_ERRORABORT: |
---|
| 723 | _Z2(atlTraceGeneral, 2, _T("nEventCode EC_ERRORABORT 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2); |
---|
| 724 | _A(FAILED(nParameter1)); |
---|
| 725 | AtlMessageBoxEx(m_hWnd, (LPCTSTR) AtlFormatString(_T("EC_ERRORABORT Event: %s."), AtlFormatSystemMessage((HRESULT) nParameter1).TrimRight(_T("\t\n\r ."))), IDS_ERROR, MB_ICONERROR | MB_OK); |
---|
| 726 | break; |
---|
| 727 | default: |
---|
| 728 | _Z1(atlTraceGeneral, 1, _T("nEventCode 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2); |
---|
| 729 | } |
---|
| 730 | } |
---|
| 731 | _ATLCATCHALL() |
---|
| 732 | { |
---|
| 733 | _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2)); |
---|
| 734 | _ATLRETHROW; |
---|
| 735 | } |
---|
| 736 | _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2)); |
---|
| 737 | } |
---|
| 738 | } |
---|
| 739 | _ATLCATCHALL() |
---|
| 740 | { |
---|
| 741 | _Z_EXCEPTION(); |
---|
| 742 | } |
---|
| 743 | return 0; |
---|
| 744 | } |
---|
| 745 | }; |
---|
| 746 | |
---|
| 747 | //////////////////////////////////////////////////////////// |
---|
[174] | 748 | // CVmr7VideoDialog, CEvrVideoDialog |
---|
| 749 | |
---|
| 750 | LPCTSTR g_pszVmr7 = _T("VMR-7"); |
---|
| 751 | |
---|
| 752 | class CVmr7VideoDialog : |
---|
| 753 | public CVideoDialogT<CVmr7VideoDialog, CVmr7Window, &g_pszVmr7> |
---|
| 754 | { |
---|
| 755 | public: |
---|
| 756 | // CVmr7VideoDialog |
---|
| 757 | CVmr7VideoDialog(const CMediaType& pMediaType, SIZE_T nLayout) : |
---|
| 758 | CVideoDialogT<CVmr7VideoDialog, CVmr7Window, &g_pszVmr7>(pMediaType, nLayout) |
---|
| 759 | { |
---|
| 760 | } |
---|
| 761 | }; |
---|
| 762 | |
---|
| 763 | LPCTSTR g_pszEvr = _T("EVR"); |
---|
| 764 | |
---|
| 765 | class CEvrVideoDialog : |
---|
| 766 | public CVideoDialogT<CEvrVideoDialog, CEvrWindow, &g_pszEvr> |
---|
| 767 | { |
---|
| 768 | public: |
---|
| 769 | // CEvrVideoDialog |
---|
| 770 | CEvrVideoDialog(const CMediaType& pMediaType, SIZE_T nLayout) : |
---|
| 771 | CVideoDialogT<CEvrVideoDialog, CEvrWindow, &g_pszEvr>(pMediaType, nLayout) |
---|
| 772 | { |
---|
| 773 | } |
---|
| 774 | }; |
---|
| 775 | |
---|
| 776 | //////////////////////////////////////////////////////////// |
---|
[56] | 777 | // CMainDialog |
---|
| 778 | |
---|
| 779 | class CMainDialog : |
---|
| 780 | public CDialogImpl<CMainDialog> |
---|
| 781 | { |
---|
| 782 | public: |
---|
| 783 | enum { IDD = IDD_MAIN }; |
---|
| 784 | |
---|
| 785 | BEGIN_MSG_MAP_EX(CMainDialog) |
---|
| 786 | //CHAIN_MSG_MAP(CDialogImpl<CMainDialog>) |
---|
| 787 | MSG_WM_INITDIALOG(OnInitDialog) |
---|
| 788 | MSG_WM_DESTROY(OnDestroy) |
---|
| 789 | MSG_WM_TIMER(OnTimer) |
---|
| 790 | MSG_WM_SYSCOMMAND(OnSysCommand) |
---|
| 791 | COMMAND_ID_HANDLER_EX(IDCANCEL, OnCommand) |
---|
| 792 | COMMAND_ID_HANDLER_EX(IDC_CREATE, OnCreateButtonClicked) |
---|
[174] | 793 | COMMAND_ID_HANDLER_EX('CL', OnCloseVideoDialog) |
---|
[56] | 794 | REFLECT_NOTIFICATIONS() |
---|
| 795 | END_MSG_MAP() |
---|
| 796 | |
---|
| 797 | public: |
---|
| 798 | |
---|
| 799 | //////////////////////////////////////////////////////// |
---|
| 800 | // Time Identifiers |
---|
| 801 | |
---|
| 802 | enum |
---|
| 803 | { |
---|
| 804 | TIMER_FIRST = 0, |
---|
| 805 | TIMER_UPDATEADAPTERS, |
---|
| 806 | }; |
---|
| 807 | |
---|
| 808 | private: |
---|
| 809 | CRoEdit m_DxgiEdit; |
---|
| 810 | CComPtr<IDXGIFactory> m_pDxgiFactory; |
---|
| 811 | CRect m_DefaultPosition; |
---|
[174] | 812 | CRoListT<CBaseVideoDialog*> m_VideoDialogList; |
---|
[56] | 813 | |
---|
| 814 | public: |
---|
| 815 | // CMainDialog |
---|
| 816 | CMainDialog() |
---|
| 817 | { |
---|
| 818 | } |
---|
| 819 | |
---|
| 820 | // Window Message Handelrs |
---|
| 821 | LRESULT OnInitDialog(HWND, LPARAM) |
---|
| 822 | { |
---|
| 823 | SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), TRUE); |
---|
| 824 | SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE); |
---|
| 825 | CMenuHandle Menu = GetSystemMenu(FALSE); |
---|
| 826 | _W(Menu.AppendMenu(MF_SEPARATOR)); |
---|
| 827 | _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About..."))); |
---|
| 828 | { |
---|
| 829 | CString sCaption; |
---|
| 830 | GetWindowText(sCaption); |
---|
| 831 | #if defined(_WIN64) |
---|
[174] | 832 | sCaption.Append(_T(" (64-bit)")); |
---|
[56] | 833 | #else |
---|
[174] | 834 | if(SafeIsWow64Process()) |
---|
| 835 | sCaption.Append(_T(" (32-bit)")); |
---|
[56] | 836 | #endif // defined(_WIN64) |
---|
| 837 | SetWindowText(sCaption); |
---|
| 838 | } |
---|
| 839 | _W(CenterWindow()); |
---|
[174] | 840 | CButton(GetDlgItem(IDC_TYPE_EVR)).SetCheck(TRUE); |
---|
[56] | 841 | CButton(GetDlgItem(IDC_RESOLUTION_19201080)).SetCheck(TRUE); |
---|
| 842 | CButton(GetDlgItem(IDC_PIXELFORMAT_NV12)).SetCheck(TRUE); |
---|
| 843 | CButton(GetDlgItem(IDC_LAYOUT_9)).SetCheck(TRUE); |
---|
| 844 | #pragma region DXGI |
---|
| 845 | m_DxgiEdit = GetDlgItem(IDC_DXGI); |
---|
[166] | 846 | if(GetOsVersion() >= 0x00060000) // Windows Vista+ |
---|
[56] | 847 | { |
---|
[166] | 848 | _ATLTRY |
---|
| 849 | { |
---|
| 850 | __C(CreateDXGIFactory(__uuidof(IDXGIFactory), (VOID**) &m_pDxgiFactory)); |
---|
| 851 | SetTimer(TIMER_UPDATEADAPTERS, 5 * 1000); // 5 seconds |
---|
| 852 | _W(PostMessage(WM_TIMER, TIMER_UPDATEADAPTERS)); |
---|
| 853 | } |
---|
| 854 | _ATLCATCH(Exception) |
---|
| 855 | { |
---|
| 856 | _Z_ATLEXCEPTION(Exception); |
---|
| 857 | m_DxgiEdit.SetValue(AtlFormatString(_T("Failed to initialize with DXGI: %s."), AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r .")))); |
---|
| 858 | } |
---|
| 859 | } else |
---|
| 860 | m_DxgiEdit.SetValue(_T("DXGI is not available.")); |
---|
[56] | 861 | #pragma endregion |
---|
| 862 | _W(GetWindowRect(m_DefaultPosition)); |
---|
| 863 | GetDlgItem(IDC_CREATE).SetFocus(); |
---|
| 864 | return FALSE; |
---|
| 865 | } |
---|
| 866 | LRESULT OnDestroy() throw() |
---|
| 867 | { |
---|
| 868 | for(POSITION Position = m_VideoDialogList.GetHeadPosition(); Position; m_VideoDialogList.GetNext(Position)) |
---|
| 869 | { |
---|
[174] | 870 | CBaseVideoDialog* pVideoDialog = m_VideoDialogList.GetAt(Position); |
---|
[56] | 871 | _A(pVideoDialog); |
---|
| 872 | if(pVideoDialog->IsWindow()) |
---|
| 873 | _W(pVideoDialog->DestroyWindow()); |
---|
| 874 | } |
---|
| 875 | m_VideoDialogList.RemoveAll(); |
---|
| 876 | return 0; |
---|
| 877 | } |
---|
| 878 | LRESULT OnTimer(UINT_PTR nEvent) |
---|
| 879 | { |
---|
| 880 | switch(nEvent) |
---|
| 881 | { |
---|
| 882 | case TIMER_UPDATEADAPTERS: |
---|
| 883 | _ATLTRY |
---|
| 884 | { |
---|
| 885 | _A(m_pDxgiFactory); |
---|
| 886 | CWaitCursor WaitCursor; |
---|
| 887 | CString sText; |
---|
| 888 | for(UINT nAdapter = 0; ; nAdapter++) |
---|
| 889 | { |
---|
| 890 | CComPtr<IDXGIAdapter> pDxgiAdapter; |
---|
| 891 | const HRESULT nEnumAdaptersResult = m_pDxgiFactory->EnumAdapters(nAdapter, &pDxgiAdapter); |
---|
| 892 | _Z4(atlTraceGeneral, 4, _T("nAdapter %d, nEnumAdaptersResult 0x%08x\n"), nAdapter, nEnumAdaptersResult); |
---|
| 893 | if(nEnumAdaptersResult == DXGI_ERROR_NOT_FOUND) |
---|
| 894 | break; |
---|
| 895 | _ATLTRY |
---|
| 896 | { |
---|
| 897 | DXGI_ADAPTER_DESC Description; |
---|
| 898 | __C(pDxgiAdapter->GetDesc(&Description)); |
---|
| 899 | sText.AppendFormat(_T("Adatper %d: %ls, Vendor 0x%x, Device 0x%x, Subsystem 0x%x, Revision 0x%x\n"), nAdapter, Description.Description, Description.VendorId, Description.DeviceId, Description.SubSysId, Description.Revision); |
---|
| 900 | sText.AppendFormat( |
---|
| 901 | _T(" ") _T("DedicatedVideoMemory %s") _T("\n") |
---|
| 902 | _T(" ") _T("DedicatedSystemMemory %s") _T("\n") |
---|
| 903 | _T(" ") _T("SharedSystemMemory %s") _T("\n") |
---|
| 904 | _T(" ") _T("AdapterLuid %d.%u") _T("\n") |
---|
| 905 | , |
---|
| 906 | _StringHelper::FormatNumber((LONGLONG) Description.DedicatedVideoMemory), |
---|
| 907 | _StringHelper::FormatNumber((LONGLONG) Description.DedicatedSystemMemory), |
---|
| 908 | _StringHelper::FormatNumber((LONGLONG) Description.SharedSystemMemory), |
---|
| 909 | Description.AdapterLuid.HighPart, Description.AdapterLuid.LowPart, |
---|
| 910 | 0); |
---|
| 911 | } |
---|
| 912 | _ATLCATCH(Exception) |
---|
| 913 | { |
---|
| 914 | _Z_ATLEXCEPTION(Exception); |
---|
| 915 | sText.AppendFormat(_T("Adatper %d Failure: %s\n"), nAdapter, AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r ."))); |
---|
| 916 | } |
---|
| 917 | } |
---|
| 918 | sText.Replace(_T("\n"), _T("\r\n")); |
---|
| 919 | m_DxgiEdit.SetValue(sText); |
---|
| 920 | } |
---|
| 921 | _ATLCATCH(Exception) |
---|
| 922 | { |
---|
| 923 | _Z_ATLEXCEPTION(Exception); |
---|
| 924 | m_DxgiEdit.SetValue(AtlFormatString(_T("Failed to initialize with DXGI: %s."), AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r .")))); |
---|
| 925 | } |
---|
| 926 | break; |
---|
| 927 | default: |
---|
| 928 | SetMsgHandled(FALSE); |
---|
| 929 | } |
---|
| 930 | return 0; |
---|
| 931 | } |
---|
| 932 | LRESULT OnSysCommand(UINT nCommand, CPoint) |
---|
| 933 | { |
---|
| 934 | switch(nCommand) |
---|
| 935 | { |
---|
| 936 | case ID_APP_ABOUT: |
---|
| 937 | { |
---|
| 938 | CAboutDialog Dialog; |
---|
| 939 | Dialog.DoModal(m_hWnd); |
---|
| 940 | } |
---|
| 941 | break; |
---|
| 942 | default: |
---|
| 943 | SetMsgHandled(FALSE); |
---|
| 944 | } |
---|
| 945 | return 0; |
---|
| 946 | } |
---|
| 947 | LRESULT OnCommand(UINT, INT nIdentifier, HWND) |
---|
| 948 | { |
---|
| 949 | _W(EndDialog(nIdentifier)); |
---|
| 950 | return 0; |
---|
| 951 | } |
---|
| 952 | LRESULT OnCreateButtonClicked(UINT, INT, HWND) |
---|
| 953 | { |
---|
| 954 | CWaitCursor WaitCursor; |
---|
| 955 | #pragma region Query Controls |
---|
[174] | 956 | SIZE_T nType; |
---|
| 957 | for(INT nIdentifier = IDC_TYPE_VMR7; nIdentifier <= IDC_TYPE_EVR; nIdentifier++) |
---|
| 958 | if(IsDlgButtonChecked(nIdentifier)) |
---|
| 959 | { |
---|
| 960 | nType = nIdentifier - IDC_TYPE_VMR7; |
---|
| 961 | break; |
---|
| 962 | } |
---|
[56] | 963 | SIZE_T nResolution; |
---|
| 964 | for(INT nIdentifier = IDC_RESOLUTION_720576; nIdentifier <= IDC_RESOLUTION_19201080; nIdentifier++) |
---|
| 965 | if(IsDlgButtonChecked(nIdentifier)) |
---|
| 966 | { |
---|
| 967 | nResolution = nIdentifier - IDC_RESOLUTION_720576; |
---|
| 968 | break; |
---|
| 969 | } |
---|
| 970 | SIZE_T nPixelFormat; |
---|
| 971 | for(INT nIdentifier = IDC_PIXELFORMAT_NV12; nIdentifier <= IDC_PIXELFORMAT_RGB32; nIdentifier++) |
---|
| 972 | if(IsDlgButtonChecked(nIdentifier)) |
---|
| 973 | { |
---|
| 974 | nPixelFormat = nIdentifier - IDC_PIXELFORMAT_NV12; |
---|
| 975 | break; |
---|
| 976 | } |
---|
| 977 | SIZE_T nLayout; |
---|
| 978 | for(INT nIdentifier = IDC_LAYOUT_1; nIdentifier <= IDC_LAYOUT_36; nIdentifier++) |
---|
| 979 | if(IsDlgButtonChecked(nIdentifier)) |
---|
| 980 | { |
---|
| 981 | nLayout = nIdentifier - IDC_LAYOUT_1; |
---|
| 982 | break; |
---|
| 983 | } |
---|
| 984 | #pragma endregion |
---|
| 985 | static const SIZE g_pExtents[] = { { 720, 576 }, { 1280, 720 }, { 1920, 1080} }; |
---|
| 986 | static const DWORD g_pnCompressions[] = { MAKEFOURCC('N', 'V', '1', '2'), MAKEFOURCC('Y', 'U', 'Y', '2'), BI_RGB, BI_RGB }; |
---|
| 987 | static const WORD g_pnBitCounts[] = { 12, 16, 24, 32 }; |
---|
| 988 | CMediaType pMediaType; |
---|
| 989 | pMediaType.AllocateVideoInfo(g_pExtents[nResolution], g_pnBitCounts[nPixelFormat], g_pnCompressions[nPixelFormat]); |
---|
[174] | 990 | CBaseVideoDialog* pVideoDialog; |
---|
| 991 | switch(nType) |
---|
| 992 | { |
---|
| 993 | case 0: // IDC_TYPE_VMR7 |
---|
| 994 | pVideoDialog = new CVmr7VideoDialog(pMediaType, nLayout); |
---|
| 995 | break; |
---|
| 996 | case 1: // IDC_TYPE_EVR |
---|
| 997 | pVideoDialog = new CEvrVideoDialog(pMediaType, nLayout); |
---|
| 998 | break; |
---|
| 999 | default: |
---|
| 1000 | __C(E_NOTIMPL); |
---|
| 1001 | } |
---|
[56] | 1002 | _ATLTRY |
---|
| 1003 | { |
---|
| 1004 | pVideoDialog->Create(m_hWnd); |
---|
| 1005 | _ATLTRY |
---|
| 1006 | { |
---|
| 1007 | CRect Position; |
---|
| 1008 | GetWindowRect(Position); |
---|
| 1009 | if(Position == m_DefaultPosition && m_VideoDialogList.IsEmpty()) |
---|
| 1010 | { |
---|
| 1011 | Position.OffsetRect(-Position.Width() / 3, 0); |
---|
| 1012 | _W(MoveWindow(Position)); |
---|
| 1013 | } |
---|
| 1014 | Position.left += Position.Width(); |
---|
| 1015 | const LONG nOffset = GetSystemMetrics(SM_CYCAPTION); |
---|
| 1016 | Position.OffsetRect(nOffset * (INT) m_VideoDialogList.GetCount(), nOffset * (INT) m_VideoDialogList.GetCount()); |
---|
| 1017 | _W(pVideoDialog->MoveWindow(Position)); |
---|
| 1018 | pVideoDialog->ShowWindow(SW_SHOWNORMAL); |
---|
[174] | 1019 | m_VideoDialogList.AddTail(pVideoDialog); |
---|
[56] | 1020 | } |
---|
| 1021 | _ATLCATCHALL() |
---|
| 1022 | { |
---|
| 1023 | _W(pVideoDialog->DestroyWindow()); |
---|
| 1024 | _ATLRETHROW; |
---|
| 1025 | } |
---|
| 1026 | } |
---|
| 1027 | _ATLCATCHALL() |
---|
| 1028 | { |
---|
| 1029 | delete pVideoDialog; |
---|
| 1030 | _ATLRETHROW; |
---|
| 1031 | } |
---|
| 1032 | return 0; |
---|
| 1033 | } |
---|
[174] | 1034 | LRESULT OnCloseVideoDialog(UINT, INT, HWND hWindow) |
---|
| 1035 | { |
---|
| 1036 | CBaseVideoDialog* pBaseVideoDialog = (CBaseVideoDialog*) hWindow; |
---|
| 1037 | POSITION Position; |
---|
| 1038 | if(m_VideoDialogList.FindFirst(pBaseVideoDialog, &Position)) |
---|
| 1039 | m_VideoDialogList.RemoveAt(Position); |
---|
| 1040 | return 0; |
---|
| 1041 | } |
---|
[56] | 1042 | }; |
---|