mf_display_watcher.cxx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* Copyright (C) 2013 Mamadou DIOP
  2. * Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
  3. *
  4. * This file is part of Open Source Doubango Framework.
  5. *
  6. * DOUBANGO is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * DOUBANGO is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with DOUBANGO.
  18. */
  19. #include "mf_display_watcher.h"
  20. #include "mf_utils.h"
  21. #include "tsk_debug.h"
  22. #include <assert.h>
  23. DisplayWatcher::DisplayWatcher(HWND hWnd, IMFMediaSink* pMediaSink, HRESULT &hr)
  24. : m_pDisplayControl(NULL)
  25. , m_hWnd(hWnd)
  26. , m_pWndProc(NULL)
  27. , m_bStarted(FALSE)
  28. , m_bFullScreen(FALSE)
  29. {
  30. IMFGetService *pService = NULL;
  31. CHECK_HR(hr = pMediaSink->QueryInterface(__uuidof(IMFGetService), (void**)&pService));
  32. CHECK_HR(hr = pService->GetService(MR_VIDEO_RENDER_SERVICE, __uuidof(IMFVideoDisplayControl), (void**)&m_pDisplayControl));
  33. CHECK_HR(hr = m_pDisplayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture));
  34. bail:
  35. SafeRelease(&pService);
  36. }
  37. DisplayWatcher::~DisplayWatcher()
  38. {
  39. Stop();
  40. SafeRelease(&m_pDisplayControl);
  41. }
  42. HRESULT DisplayWatcher::Start()
  43. {
  44. HRESULT hr = S_OK;
  45. HWND hWnd = m_hWnd; // save()
  46. CHECK_HR(hr = Stop());
  47. if((m_hWnd = hWnd) && m_pDisplayControl) {
  48. CHECK_HR(hr = m_pDisplayControl->SetVideoWindow(hWnd));
  49. BOOL ret = SetPropA(m_hWnd, "This", this);
  50. assert(ret);
  51. #if _M_X64
  52. m_pWndProc = (WNDPROC)SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)DisplayWatcher::WndProc);
  53. #else
  54. m_pWndProc = (WNDPROC)SetWindowLongPtr(m_hWnd, GWL_WNDPROC, (LONG)DisplayWatcher::WndProc);
  55. #endif
  56. UpdatePosition(); // black screen if attached later
  57. }
  58. m_bStarted = TRUE;
  59. bail:
  60. return hr;
  61. }
  62. HRESULT DisplayWatcher::SetFullscreen(BOOL bEnabled)
  63. {
  64. if(m_pDisplayControl) {
  65. HRESULT hr = m_pDisplayControl->SetFullscreen(bEnabled);
  66. m_bFullScreen = SUCCEEDED(hr);
  67. return hr;
  68. }
  69. return E_FAIL;
  70. }
  71. HRESULT DisplayWatcher::SetHwnd(HWND hWnd)
  72. {
  73. BOOL bWasStarted = m_bStarted;
  74. Stop();
  75. m_hWnd = hWnd;
  76. if(bWasStarted) {
  77. return Start();
  78. }
  79. return S_OK;
  80. }
  81. HRESULT DisplayWatcher::Stop()
  82. {
  83. if(m_hWnd && m_pWndProc) {
  84. // Restore
  85. #if _M_X64
  86. SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pWndProc);
  87. #else
  88. SetWindowLongPtr(m_hWnd, GWL_WNDPROC, (LONG)m_pWndProc);
  89. #endif
  90. }
  91. m_hWnd = NULL;
  92. m_pWndProc = NULL;
  93. m_bStarted = FALSE;
  94. return S_OK;
  95. }
  96. void DisplayWatcher::UpdatePosition()
  97. {
  98. if(m_pDisplayControl && m_hWnd) {
  99. RECT rcDst = { 0, 0, 0, 0 };
  100. GetClientRect(m_hWnd, &rcDst);
  101. m_pDisplayControl->SetVideoPosition(NULL, &rcDst);
  102. }
  103. }
  104. LRESULT CALLBACK DisplayWatcher::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  105. {
  106. switch(uMsg) {
  107. case WM_CREATE:
  108. case WM_SIZE:
  109. case WM_MOVE: {
  110. DisplayWatcher* This = dynamic_cast<DisplayWatcher*>((DisplayWatcher*)GetPropA(hWnd, "This"));
  111. if(This) {
  112. This->UpdatePosition();
  113. }
  114. break;
  115. }
  116. case WM_CHAR:
  117. case WM_KEYUP: {
  118. DisplayWatcher* This = dynamic_cast<DisplayWatcher*>((DisplayWatcher*)GetPropA(hWnd, "This"));
  119. if(This) {
  120. if(This->m_bFullScreen && (wParam == 0x1B || wParam == VK_ESCAPE)) {
  121. This->SetFullscreen(FALSE);
  122. }
  123. }
  124. break;
  125. }
  126. }
  127. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  128. }