|
|
@@ -0,0 +1,60 @@
|
|
|
+#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);
|
|
|
+ }
|
|
|
+ // 可选:绘制鼠标
|
|
|
+ // ...
|
|
|
+ return _frame;
|
|
|
+#else
|
|
|
+ return nullptr;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+} // namespace video
|
|
|
+} // namespace avrecorder
|