10#include "private/qplatformvideoframeinput_p.h"
11#include "private/qplatformaudiobufferinput_p.h"
12#include "private/qplatformaudiobufferinput_p.h"
18EncodingInitializer::EncodingInitializer(RecordingEngine &engine) : m_recordingEngine(engine) { }
20EncodingInitializer::~EncodingInitializer()
22 for (QObject *source : m_pendingSources)
23 setEncoderInterface(source,
nullptr);
26bool EncodingInitializer::start(
const std::vector<QAudioBufferSource *> &audioSources,
27 const std::vector<QPlatformVideoSource *> &videoSources)
29 for (
auto source : audioSources) {
30 if (
auto audioInput = qobject_cast<QFFmpegAudioInput *>(source))
31 m_recordingEngine.addAudioInput(audioInput);
32 else if (
auto audioBufferInput = qobject_cast<QPlatformAudioBufferInput *>(source))
33 addAudioBufferInput(audioBufferInput);
35 Q_ASSERT(!
"Undefined source type");
38 for (
auto source : videoSources)
39 addVideoSource(source);
41 return tryStartRecordingEngine();
44void EncodingInitializer::addAudioBufferInput(QPlatformAudioBufferInput *input)
48 if (input->audioFormat().isValid())
49 m_recordingEngine.addAudioBufferInput(input, {});
51 addPendingAudioBufferInput(input);
54void EncodingInitializer::addPendingAudioBufferInput(QPlatformAudioBufferInput *input)
56 addPendingSource(input);
58 connect(input, &QPlatformAudioBufferInput::destroyed,
this, [
this, input]() {
59 erasePendingSource(input, QStringLiteral(
"Audio source deleted"),
true);
62 connect(input, &QPlatformAudioBufferInput::newAudioBuffer,
this,
63 [
this, input](
const QAudioBuffer &buffer) {
66 input, [&]() { m_recordingEngine.addAudioBufferInput(input, buffer); });
68 erasePendingSource(input,
69 QStringLiteral(
"Audio source has sent the end frame"));
73void EncodingInitializer::addVideoSource(QPlatformVideoSource *source)
76 Q_ASSERT(source->isActive());
78 if (source->frameFormat().isValid())
79 m_recordingEngine.addVideoSource(source, {});
80 else if (source->hasError())
81 emitStreamInitializationError(QStringLiteral(
"Video source error: ")
82 + source->errorString());
84 addPendingVideoSource(source);
87void EncodingInitializer::addPendingVideoSource(QPlatformVideoSource *source)
89 addPendingSource(source);
91 connect(source, &QPlatformVideoSource::errorChanged,
this, [
this, source]() {
92 if (source->hasError())
93 erasePendingSource(source,
94 QStringLiteral(
"Videio source error: ") + source->errorString());
97 connect(source, &QPlatformVideoSource::destroyed,
this, [
this, source]() {
98 erasePendingSource(source, QStringLiteral(
"Source deleted"),
true);
101 connect(source, &QPlatformVideoSource::activeChanged,
this, [
this, source]() {
102 if (!source->isActive())
103 erasePendingSource(source, QStringLiteral(
"Video source deactivated"));
106 connect(source, &QPlatformVideoSource::newVideoFrame,
this,
107 [
this, source](
const QVideoFrame &frame) {
109 erasePendingSource(source,
110 [&]() { m_recordingEngine.addVideoSource(source, frame); });
112 erasePendingSource(source,
113 QStringLiteral(
"Video source has sent the end frame"));
117bool EncodingInitializer::tryStartRecordingEngine()
119 if (m_pendingSources.empty())
120 return m_recordingEngine.startEncoders();
127void EncodingInitializer::emitStreamInitializationError(QString error)
129 emit m_recordingEngine.streamInitializationError(
130 QMediaRecorder::ResourceError,
131 QStringLiteral(
"Video steam initialization error. ") + error);
134void EncodingInitializer::addPendingSource(QObject *source)
136 Q_ASSERT(m_pendingSources.count(source) == 0);
138 setEncoderInterface(source,
this);
139 m_pendingSources.emplace(source);
143void EncodingInitializer::erasePendingSource(QObject *source, F &&functionOrError,
bool destroyed)
145 const auto erasedCount = m_pendingSources.erase(source);
146 if (erasedCount == 0)
150 setEncoderInterface(source,
nullptr);
151 disconnect(source,
nullptr,
this,
nullptr);
154 if constexpr (std::is_invocable_v<F>)
157 emitStreamInitializationError(functionOrError);
159 tryStartRecordingEngine();
162bool EncodingInitializer::canPushFrame()
const