GdiCapturer.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "GdiCapturer.h"
  2. #include <cassert>
  3. namespace avrecorder {
  4. namespace video {
  5. bool GdiCapturer::open(const CaptureTarget& target, int width, int height) {
  6. #ifdef PLATFORM_WINDOWS
  7. close();
  8. if (target.type != CaptureTargetType::Window) return false;
  9. m_hwnd = target.hwnd;
  10. m_width = width;
  11. m_height = height;
  12. _srcHdc = GetWindowDC(m_hwnd);
  13. _dstHdc = CreateCompatibleDC(_srcHdc);
  14. _bitmap = CreateCompatibleBitmap(_srcHdc, width, height);
  15. SelectObject(_dstHdc, _bitmap);
  16. _bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  17. _bitmapInfo.bmiHeader.biPlanes = 1;
  18. _bitmapInfo.bmiHeader.biBitCount = 24;
  19. _bitmapInfo.bmiHeader.biWidth = width;
  20. _bitmapInfo.bmiHeader.biHeight = height;
  21. _bitmapInfo.bmiHeader.biCompression = BI_RGB;
  22. _bitmapInfo.bmiHeader.biSizeImage = width * height;
  23. _frame = Frame<MediaType::VIDEO>::Alloc(AV_PIX_FMT_BGR24, width, height);
  24. return true;
  25. #else
  26. return false;
  27. #endif
  28. }
  29. void GdiCapturer::close() {
  30. #ifdef PLATFORM_WINDOWS
  31. if (_frame) { av_frame_free(&_frame); _frame = nullptr; }
  32. if (_dstHdc) { DeleteObject(_dstHdc); _dstHdc = nullptr; }
  33. if (_bitmap) { DeleteObject(_bitmap); _bitmap = nullptr; }
  34. // _srcHdc 由系统管理,无需手动释放
  35. #endif
  36. }
  37. AVFrame* GdiCapturer::getFrame() {
  38. #ifdef PLATFORM_WINDOWS
  39. if (!_srcHdc || !_dstHdc || !_frame) return nullptr;
  40. BitBlt(_dstHdc, 0, 0, m_width, m_height, _srcHdc, 0, 0, SRCCOPY);
  41. auto linesize = _frame->linesize[0];
  42. for (int row = 0; row < m_height; ++row) {
  43. GetDIBits(_dstHdc, _bitmap, m_height - 1 - row, 1, _frame->data[0] + row * linesize, &_bitmapInfo, DIB_RGB_COLORS);
  44. }
  45. // 可选:绘制鼠标
  46. // ...
  47. return _frame;
  48. #else
  49. return nullptr;
  50. #endif
  51. }
  52. } // namespace video
  53. } // namespace avrecorder