Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
capturesessionfixture.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5#include <QtTest/qtest.h>
6
8
9using namespace std::chrono;
10
11CaptureSessionFixture::CaptureSessionFixture(StreamType streamType) : m_streamType{ streamType } { }
12
14{
15 if (!m_recorder.actualLocation().isEmpty())
16 QFile::remove(m_recorder.actualLocation().toLocalFile());
17}
18
19void CaptureSessionFixture::setVideoSink(QVideoSink *videoSink)
20{
21 m_videoSink = videoSink;
22}
23
25 std::optional<QIODevice *> outputDevice)
26{
27 if (hasVideo()) {
28 m_session.setVideoFrameInput(&m_videoInput);
29
30 QObject::connect(&m_videoGenerator, &VideoGenerator::frameCreated, //
31 &m_videoInput, &QVideoFrameInput::sendVideoFrame);
32
33 if (autoStop == AutoStop::EmitEmpty) {
34 m_recorder.setAutoStop(true);
35 m_videoGenerator.emitEmptyFrameOnStop();
36 }
37 }
38
39 if (hasAudio()) {
40 m_session.setAudioBufferInput(&m_audioInput);
41
42 QObject::connect(&m_audioGenerator, &AudioGenerator::audioBufferCreated, //
43 &m_audioInput, &QAudioBufferInput::sendAudioBuffer);
44
45 if (autoStop == AutoStop::EmitEmpty) {
46 m_recorder.setAutoStop(true);
47 m_audioGenerator.emitEmptyBufferOnStop();
48 }
49 }
50
51 if (mode == RunMode::Pull) {
52 if (hasVideo())
53 QObject::connect(&m_videoInput, &QVideoFrameInput::readyToSendVideoFrame, //
54 &m_videoGenerator, &VideoGenerator::nextFrame);
55
56 if (hasAudio())
57 QObject::connect(&m_audioInput, &QAudioBufferInput::readyToSendAudioBuffer, //
58 &m_audioGenerator, &AudioGenerator::nextBuffer);
59 }
60
61 m_session.setRecorder(&m_recorder);
62 m_recorder.setQuality(QMediaRecorder::VeryHighQuality);
63
64 if (outputDevice)
65 m_recorder.setOutputDevice(*outputDevice);
66
67 if (!outputDevice && m_recorder.outputLocation().isEmpty()) {
68 // Create a temporary file.
69 // The file name is not available without opening.
70 if (!m_tempFile.open()) {
71 qWarning("Failed to open file: %s (%s)",
72 qPrintable(m_tempFile.fileName()), qPrintable(m_tempFile.errorString()));
73 } else {
74 m_tempFile.close();
75
76 m_recorder.setOutputLocation(QUrl::fromLocalFile(m_tempFile.fileName()));
77 }
78 }
79 // else: outputLocation has been already set
80
81 m_recorder.record();
82
83 // HACK: Add sink after starting recording because setting the video sink will
84 // emit ready signals and start the processing chain. TODO: Fix this
85 if (m_videoSink)
86 m_session.setVideoSink(m_videoSink);
87}
88
89bool CaptureSessionFixture::waitForRecorderStopped(std::chrono::milliseconds duration)
90{
91 // StoppedState is emitted when media is finalized.
92 const bool stopped = QTest::qWaitFor(
93 [&] { //
94 return recorderStateChanged.contains(
95 QList<QVariant>{ QMediaRecorder::RecorderState::StoppedState });
96 },
97 duration);
98
99 if (!stopped)
100 return false;
101
102 return m_recorder.recorderState() == QMediaRecorder::StoppedState;
103}
104
106{
107 return m_streamType == StreamType::Audio || m_streamType == StreamType::AudioAndVideo;
108}
109
111{
112 return m_streamType == StreamType::Video || m_streamType == StreamType::AudioAndVideo;
113}
114
115QT_END_NAMESPACE
Combined button and popup list for selecting options.
void setVideoSink(QVideoSink *videoSink)
bool waitForRecorderStopped(std::chrono::milliseconds duration)
void start(RunMode mode, AutoStop autoStop, std::optional< QIODevice * > outputDevice=std::nullopt)
CaptureSessionFixture(StreamType streamType)