| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- #include "GdiCapturer.h"
- #include <cassert>
- namespace avrecorder {
- namespace video {
- bool GdiCapturer::open(const CaptureTarget& target, int width, int height) {
- #ifdef PLATFORM_WINDOWS
- close();
- if (target.type != CaptureTargetType::Window) return false;
- m_hwnd = target.hwnd;
- m_width = width;
- m_height = height;
- _srcHdc = GetWindowDC(m_hwnd);
- _dstHdc = CreateCompatibleDC(_srcHdc);
- _bitmap = CreateCompatibleBitmap(_srcHdc, width, height);
- SelectObject(_dstHdc, _bitmap);
- _bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- _bitmapInfo.bmiHeader.biPlanes = 1;
- _bitmapInfo.bmiHeader.biBitCount = 24;
- _bitmapInfo.bmiHeader.biWidth = width;
- _bitmapInfo.bmiHeader.biHeight = height;
- _bitmapInfo.bmiHeader.biCompression = BI_RGB;
- _bitmapInfo.bmiHeader.biSizeImage = width * height;
- _frame = Frame<MediaType::VIDEO>::Alloc(AV_PIX_FMT_BGR24, width, height);
- return true;
- #else
- return false;
- #endif
- }
- void GdiCapturer::close() {
- #ifdef PLATFORM_WINDOWS
- if (_frame) { av_frame_free(&_frame); _frame = nullptr; }
- if (_dstHdc) { DeleteObject(_dstHdc); _dstHdc = nullptr; }
- if (_bitmap) { DeleteObject(_bitmap); _bitmap = nullptr; }
- // _srcHdc 由系统管理,无需手动释放
- #endif
- }
- AVFrame* GdiCapturer::getFrame() {
- #ifdef PLATFORM_WINDOWS
- if (!_srcHdc || !_dstHdc || !_frame) return nullptr;
- BitBlt(_dstHdc, 0, 0, m_width, m_height, _srcHdc, 0, 0, SRCCOPY);
- auto linesize = _frame->linesize[0];
- for (int row = 0; row < m_height; ++row) {
- GetDIBits(_dstHdc, _bitmap, m_height - 1 - row, 1, _frame->data[0] + row * linesize, &_bitmapInfo, DIB_RGB_COLORS);
- }
- if (m_drawCursor) {
- drawCursor(_dstHdc);
- }
- return _frame;
- #else
- return nullptr;
- #endif
- }
- void GdiCapturer::drawCursor(HDC hdc)
- {
- CURSORINFO ci = {sizeof(CURSORINFO)};
- if (!GetCursorInfo(&ci))
- return;
- if (ci.flags != CURSOR_SHOWING)
- return;
- RECT rect;
- GetWindowRect(m_hwnd, &rect);
- POINT pos = {ci.ptScreenPos.x - rect.left, ci.ptScreenPos.y - rect.top};
- DrawIconEx(hdc, pos.x, pos.y, ci.hCursor, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
- }
- } // namespace video
- } // namespace avrecorder
|