Skip to content

Commit 2f7e3dd

Browse files
feat(ext-image-capture): Add multi-screen recording support
- Introduce `MultiScreenCaptureCoordinator` and `MultiScreenFrameCompositor` classes to manage multi-screen capture functionality and composite captured frames. - Enhance `ExtCaptureIntegration` to support starting and stopping multi-screen recordings. - Add new signals to `ExtCaptureIntegration` for handling multi-screen frame readiness and error reporting. - Update relevant header and source files to include the new multi-screen components, significantly improving overall screen recording capabilities. 特性(ext-image-capture): 添加多屏幕录制支持 - 引入 `MultiScreenCaptureCoordinator` 和 `MultiScreenFrameCompositor` 类,用于管理多屏幕捕获功能和进行帧合成。 - 增强 `ExtCaptureIntegration`,以支持多屏幕录制的启动和停止操作。 - 为 `ExtCaptureIntegration` 添加新信号,用于处理多屏幕帧准备就绪和错误报告。 - 更新相关的头文件和源文件,纳入新的多屏幕组件,显著提升了整体屏幕录制能力。
1 parent 1b8c1f6 commit 2f7e3dd

9 files changed

Lines changed: 1463 additions & 8 deletions

src/ext-image-capture/extcaptureintegration.cpp

Lines changed: 122 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,39 @@
77
#include "manager/extcapturemanager.h"
88
#include "session/extcapturesession.h"
99
#include "frame/extcaptureframe.h"
10+
#include "multiscreencapturecoordinator.h"
1011
#include "../utils/log.h"
1112

1213
#include <QDebug>
1314
#include <QTimer>
15+
#include <QGuiApplication>
1416

1517
ExtCaptureIntegration::ExtCaptureIntegration(QObject *parent)
1618
: QObject(parent)
1719
, m_manager(new ExtCaptureManager(this))
1820
, m_session(nullptr)
21+
, m_multiScreenCoordinator(new MultiScreenCaptureCoordinator(this))
1922
, m_recording(false)
23+
, m_multiScreenRecording(false)
2024
{
2125
// 连接管理器信号
2226
connect(m_manager, &ExtCaptureManager::protocolAvailable,
2327
this, &ExtCaptureIntegration::onProtocolAvailable);
2428
connect(m_manager, &ExtCaptureManager::protocolUnavailable,
2529
this, &ExtCaptureIntegration::onProtocolUnavailable);
30+
31+
// 设置多屏协调器的捕获管理器
32+
m_multiScreenCoordinator->setCaptureManager(m_manager);
33+
34+
// 连接多屏协调器信号
35+
connect(m_multiScreenCoordinator, &MultiScreenCaptureCoordinator::compositeFrameReady,
36+
this, &ExtCaptureIntegration::onMultiScreenFrameReady);
37+
connect(m_multiScreenCoordinator, &MultiScreenCaptureCoordinator::captureStarted,
38+
this, &ExtCaptureIntegration::onMultiScreenCaptureStarted);
39+
connect(m_multiScreenCoordinator, &MultiScreenCaptureCoordinator::captureStopped,
40+
this, &ExtCaptureIntegration::onMultiScreenCaptureStopped);
41+
connect(m_multiScreenCoordinator, &MultiScreenCaptureCoordinator::error,
42+
this, &ExtCaptureIntegration::onMultiScreenCaptureError);
2643
}
2744

2845
ExtCaptureIntegration::~ExtCaptureIntegration()
@@ -91,20 +108,33 @@ bool ExtCaptureIntegration::startScreenRecording(QScreen *screen, bool includeCu
91108

92109
void ExtCaptureIntegration::stopRecording()
93110
{
94-
if (!m_recording) {
111+
qCDebug(dsrApp) << "ExtCaptureIntegration::stopRecording: Stopping recording"
112+
<< "single screen:" << m_recording << "multi screen:" << m_multiScreenRecording;
113+
114+
if (!m_recording && !m_multiScreenRecording) {
95115
return;
96116
}
97117

98-
m_recording = false;
118+
// 停止单屏录制
119+
if (m_recording) {
120+
m_recording = false;
99121

100-
if (m_session) {
101-
m_session->stop();
102-
m_session->deleteLater();
103-
m_session = nullptr;
122+
if (m_session) {
123+
m_session->stop();
124+
m_session->deleteLater();
125+
m_session = nullptr;
126+
}
127+
128+
emit recordingStopped();
129+
qCDebug(dsrApp) << "Single screen recording stopped";
104130
}
105131

106-
emit recordingStopped();
107-
qDebug() << "Screen recording stopped";
132+
// 停止多屏录制
133+
if (m_multiScreenRecording) {
134+
m_multiScreenCoordinator->stopMultiScreenCapture();
135+
// m_multiScreenRecording 将在 onMultiScreenCaptureStopped 中设置为 false
136+
qCDebug(dsrApp) << "Multi-screen recording stop requested";
137+
}
108138
}
109139

110140
bool ExtCaptureIntegration::captureFrame()
@@ -241,3 +271,87 @@ void ExtCaptureIntegration::onFrameFailed(const QString &reason)
241271
emit error(QString("Frame capture failed: %1").arg(reason));
242272
}
243273

274+
bool ExtCaptureIntegration::startMultiScreenRecording(const QList<QScreen*>& screens, bool includeCursor)
275+
{
276+
qCWarning(dsrApp) << "ExtCaptureIntegration::startMultiScreenRecording: Starting with"
277+
<< screens.size() << "screens, includeCursor:" << includeCursor;
278+
279+
if (m_recording || m_multiScreenRecording) {
280+
qCWarning(dsrApp) << "ExtCaptureIntegration: Already recording";
281+
return false;
282+
}
283+
284+
if (!isAvailable()) {
285+
qCWarning(dsrApp) << "ExtCaptureIntegration: Protocol not available";
286+
emit error("Protocol not available");
287+
return false;
288+
}
289+
290+
if (screens.isEmpty()) {
291+
qCWarning(dsrApp) << "ExtCaptureIntegration: No screens provided";
292+
emit error("No screens to record");
293+
return false;
294+
}
295+
296+
// 开始多屏捕获
297+
if (!m_multiScreenCoordinator->startMultiScreenCapture(screens, includeCursor)) {
298+
qCWarning(dsrApp) << "ExtCaptureIntegration: Failed to start multi-screen capture";
299+
emit error("Failed to start multi-screen capture");
300+
return false;
301+
}
302+
303+
m_multiScreenRecording = true;
304+
qCWarning(dsrApp) << "ExtCaptureIntegration: Multi-screen recording started";
305+
306+
return true;
307+
}
308+
309+
bool ExtCaptureIntegration::captureMultiScreenFrame()
310+
{
311+
if (!m_multiScreenRecording) {
312+
qCWarning(dsrApp) << "ExtCaptureIntegration: Not in multi-screen recording mode";
313+
return false;
314+
}
315+
316+
return m_multiScreenCoordinator->captureMultiScreenFrame();
317+
}
318+
319+
bool ExtCaptureIntegration::isMultiScreenRecording() const
320+
{
321+
return m_multiScreenRecording;
322+
}
323+
324+
QList<QScreen*> ExtCaptureIntegration::getAvailableScreens() const
325+
{
326+
return QGuiApplication::screens();
327+
}
328+
329+
void ExtCaptureIntegration::onMultiScreenFrameReady(const QByteArray& compositeFrameData,
330+
int width, int height, int stride, uint64_t timestamp)
331+
{
332+
qCDebug(dsrApp) << "ExtCaptureIntegration::onMultiScreenFrameReady: Composite frame ready"
333+
<< "size:" << compositeFrameData.size() << "dimensions:" << width << "x" << height;
334+
335+
emit multiScreenFrameReady(compositeFrameData, width, height, stride, timestamp);
336+
}
337+
338+
void ExtCaptureIntegration::onMultiScreenCaptureStarted()
339+
{
340+
qCDebug(dsrApp) << "ExtCaptureIntegration::onMultiScreenCaptureStarted";
341+
emit recordingStarted();
342+
}
343+
344+
void ExtCaptureIntegration::onMultiScreenCaptureStopped()
345+
{
346+
qCDebug(dsrApp) << "ExtCaptureIntegration::onMultiScreenCaptureStopped";
347+
m_multiScreenRecording = false;
348+
emit recordingStopped();
349+
}
350+
351+
void ExtCaptureIntegration::onMultiScreenCaptureError(const QString& message)
352+
{
353+
qCWarning(dsrApp) << "ExtCaptureIntegration::onMultiScreenCaptureError:" << message;
354+
m_multiScreenRecording = false;
355+
emit error(QString("Multi-screen capture error: %1").arg(message));
356+
}
357+

src/ext-image-capture/extcaptureintegration.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88

99
#include <QObject>
1010
#include <QScreen>
11+
#include <QList>
12+
#include <QRect>
1113

1214
class ExtCaptureManager;
1315
class ExtCaptureSession;
1416
class ExtCaptureFrame;
17+
class MultiScreenCaptureCoordinator;
1518

1619
/**
1720
* @brief ext-image-copy-capture集成接口
@@ -39,6 +42,14 @@ class ExtCaptureIntegration : public QObject
3942
*/
4043
bool startScreenRecording(QScreen *screen, bool includeCursor = false);
4144

45+
/**
46+
* @brief 开始多屏录制
47+
* @param screens 要录制的屏幕列表
48+
* @param includeCursor 是否包含光标
49+
* @return 是否成功开始
50+
*/
51+
bool startMultiScreenRecording(const QList<QScreen*>& screens, bool includeCursor = false);
52+
4253
/**
4354
* @brief 停止录制
4455
*/
@@ -50,11 +61,27 @@ class ExtCaptureIntegration : public QObject
5061
*/
5162
bool captureFrame();
5263

64+
/**
65+
* @brief 捕获多屏帧
66+
* @return 是否成功开始捕获
67+
*/
68+
bool captureMultiScreenFrame();
69+
5370
/**
5471
* @brief 获取当前会话状态
5572
*/
5673
bool isRecording() const;
5774

75+
/**
76+
* @brief 是否正在进行多屏录制
77+
*/
78+
bool isMultiScreenRecording() const;
79+
80+
/**
81+
* @brief 获取支持的屏幕列表
82+
*/
83+
QList<QScreen*> getAvailableScreens() const;
84+
5885
signals:
5986
/**
6087
* @brief 协议变为可用
@@ -99,6 +126,16 @@ class ExtCaptureIntegration : public QObject
99126
*/
100127
void dmaFrameReady(int dmaBufferFd, void *gbmBo, size_t size, int width, int height, int stride, uint64_t timestamp);
101128

129+
/**
130+
* @brief 多屏合成帧就绪
131+
* @param compositeFrameData 合成后的帧数据
132+
* @param width 帧宽度
133+
* @param height 帧高度
134+
* @param stride 行字节数
135+
* @param timestamp 时间戳
136+
*/
137+
void multiScreenFrameReady(const QByteArray& compositeFrameData, int width, int height, int stride, uint64_t timestamp);
138+
102139
/**
103140
* @brief 发生错误
104141
*/
@@ -113,10 +150,18 @@ private slots:
113150
void onFrameReady(ExtCaptureFrame *frame);
114151
void onFrameFailed(const QString &reason);
115152

153+
private slots:
154+
void onMultiScreenFrameReady(const QByteArray& compositeFrameData, int width, int height, int stride, uint64_t timestamp);
155+
void onMultiScreenCaptureStarted();
156+
void onMultiScreenCaptureStopped();
157+
void onMultiScreenCaptureError(const QString& message);
158+
116159
private:
117160
ExtCaptureManager *m_manager;
118161
ExtCaptureSession *m_session;
162+
MultiScreenCaptureCoordinator *m_multiScreenCoordinator;
119163
bool m_recording;
164+
bool m_multiScreenRecording;
120165
};
121166

122167
#endif // EXTCAPTUREINTEGRATION_H

0 commit comments

Comments
 (0)