VideoRenderer.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "stdafx.h"
  2. #include <memory>
  3. #include <mutex>
  4. #include "VideoRenderer.h"
  5. #include "VideoRenderer.h"
  6. CVideoRenderer::CVideoRenderer()
  7. {
  8. start_ = false;
  9. }
  10. void CVideoRenderer::SetRenderWindow(HWND wnd, int32_t width, int32_t height)
  11. {
  12. if (!IsWindow(wnd)) return;
  13. wnd_ = wnd;
  14. ZeroMemory(&bmi_, sizeof(bmi_));
  15. bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  16. bmi_.bmiHeader.biPlanes = 1;
  17. bmi_.bmiHeader.biBitCount = 32;
  18. bmi_.bmiHeader.biCompression = BI_RGB;
  19. bmi_.bmiHeader.biWidth = width;
  20. bmi_.bmiHeader.biHeight = -height;
  21. bmi_.bmiHeader.biSizeImage =
  22. width * height * (bmi_.bmiHeader.biBitCount >> 3);
  23. }
  24. void CVideoRenderer::StartRender(bool bStart)
  25. {
  26. start_ = bStart;
  27. }
  28. LRESULT CVideoRenderer::PaintProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lparam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
  29. {
  30. CVideoRenderer* lhs = reinterpret_cast<CVideoRenderer*>(dwRefData);
  31. return lhs->OnPaintProc(hWnd, msg, wParam, lparam, uIdSubclass);
  32. }
  33. LRESULT CVideoRenderer::OnPaintProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lparam, UINT_PTR uIdSubclass)
  34. {
  35. if (start_ == false) return ::DefWindowProc(wnd_, msg, wParam, lparam);
  36. if (start_ && msg == WM_PAINT)
  37. {
  38. PAINTSTRUCT ps;
  39. ::BeginPaint(hWnd, &ps);
  40. RECT rc;
  41. ::GetClientRect(hWnd, &rc);
  42. //const uint8_t* image =
  43. //AutoLock<VideoRenderer> local_lock(renderer);
  44. //const BITMAPINFO& bmi = renderer->bmi();
  45. std::lock_guard < std::mutex> l(buffer_lock_);
  46. int height = abs(bmi_.bmiHeader.biHeight);
  47. int width = bmi_.bmiHeader.biWidth;
  48. HDC dc_mem = ::CreateCompatibleDC(ps.hdc);
  49. ::SetStretchBltMode(dc_mem, HALFTONE);
  50. HDC all_dc[] = { ps.hdc, dc_mem };
  51. for (size_t i = 0; i < _countof(all_dc); ++i) {
  52. SetMapMode(all_dc[i], MM_ISOTROPIC);
  53. SetWindowExtEx(all_dc[i], width, height, NULL);
  54. SetViewportExtEx(all_dc[i], rc.right, rc.bottom, NULL);
  55. }
  56. HBITMAP bmp_mem = ::CreateCompatibleBitmap(ps.hdc, rc.right, rc.bottom);
  57. HGDIOBJ bmp_old = ::SelectObject(dc_mem, bmp_mem);
  58. POINT logical_area = { rc.right, rc.bottom };
  59. DPtoLP(ps.hdc, &logical_area, 1);
  60. HBRUSH brush = ::CreateSolidBrush(RGB(0, 0, 0));
  61. RECT logical_rect = { 0, 0, logical_area.x, logical_area.y };
  62. ::FillRect(dc_mem, &logical_rect, brush);
  63. ::DeleteObject(brush);
  64. int x = (logical_area.x / 2) - (width / 2);
  65. int y = (logical_area.y / 2) - (height / 2);
  66. StretchDIBits(dc_mem, x, y, width, height, 0, 0, width, height, image_.get(),
  67. &bmi_, DIB_RGB_COLORS, SRCCOPY);
  68. BitBlt(ps.hdc, 0, 0, logical_area.x, logical_area.y, dc_mem, 0, 0,
  69. SRCCOPY);
  70. // Cleanup.
  71. ::SelectObject(dc_mem, bmp_old);
  72. ::DeleteObject(bmp_mem);
  73. ::DeleteDC(dc_mem);
  74. ::EndPaint(hWnd, &ps);
  75. }
  76. return ::DefWindowProc(wnd_, msg, wParam, lparam);
  77. }
  78. void CVideoRenderer::SetSize(int32_t width, int32_t height)
  79. {
  80. if (width == bmi_.bmiHeader.biWidth && height == bmi_.bmiHeader.biHeight) {
  81. return;
  82. }
  83. bmi_.bmiHeader.biWidth = width;
  84. bmi_.bmiHeader.biHeight = -height;
  85. bmi_.bmiHeader.biSizeImage =
  86. width * height * (bmi_.bmiHeader.biBitCount >> 3);
  87. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  88. }
  89. void CVideoRenderer::OnArgb32FrameReady(const void* data, const int stride, const int frame_width, const int frame_height)
  90. {
  91. SetSize(frame_width, frame_height);
  92. memcpy(image_.get(), data, bmi_.bmiHeader.biSizeImage);
  93. ::InvalidateRect(wnd_, NULL, FALSE);
  94. }
  95. void CVideoRenderer::FrameCallback(void* user_data, void* data, const int stride, const int frame_width, const int frame_height)
  96. {
  97. auto ptr = static_cast<CVideoRenderer*>(user_data);
  98. ptr->OnArgb32FrameReady(data, stride, frame_width, frame_height);
  99. }