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
qffmpegrecordingengine_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#ifndef QFFMPEGENCODER_P_H
4#define QFFMPEGENCODER_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <QtFFmpegMediaPluginImpl/private/qffmpegthread_p.h>
18#include <QtFFmpegMediaPluginImpl/private/qffmpegencodingformatcontext_p.h>
19
20#include <QtCore/qfuture.h>
21#include <QtCore/qpromise.h>
22#include <QtMultimedia/qmediarecorder.h>
23#include <QtMultimedia/private/qplatformmediarecorder_p.h>
24
26
27class QAudioBuffer;
28class QAudioFormat;
30class QPlatformAudioBufferInput;
31class QAudioBufferSource;
32class QPlatformVideoSource;
33class QVideoFrame;
34
35namespace QFFmpeg
36{
37
38class RecordingEngine;
39class Muxer;
40class AudioEncoder;
41class VideoEncoder;
44
46{
48public:
51
52 /** Initializes the recording engine immediately or
53 * postpones it if no source formats provided.
54 * Returns true if no session errors have occurred during the immediate run or
55 * the engine is to be initialized postponly.
56 * If any session error has occurred, it emits the signal sessionError and returns false.
57 */
58 bool initialize(const std::vector<QAudioBufferSource *> &audioSources,
59 const std::vector<QPlatformVideoSource *> &videoSources);
60 void finalize();
61
62 void setPaused(bool p);
63
64 void setAutoStop(bool autoStop);
65
66 bool autoStop() const { return m_autoStop; }
67
68 void setMetaData(const QMediaMetaData &metaData);
69 AVFormatContext *avFormatContext() { return m_formatContext->avFormatContext(); }
70 Muxer *getMuxer() { return m_muxer.get(); }
71
72 bool isEndOfSourceStreams() const;
73
74 bool waitForEncodingStart() const { return m_startEncodingPromise.future().result(); }
75
76public Q_SLOTS:
78
81 void sessionError(QMediaRecorder::Error code, const QString &description);
82 void streamInitializationError(QMediaRecorder::Error code, const QString &description);
85
86private:
87 // Normal states transition, Stop is called upon Encoding,
88 // header, content, and trailer are written:
89 // None -> FormatsInitializing -> EncodersInitializing -> Encoding -> Finalizing
90 //
91 // Stop is called upon FormatsInitializing (before any encoder was even created),
92 // nothing is written to the output:
93 // None -> FormatsInitializing -> Finalizing
94 //
95 // Stop is called upon EncodersInitializing, encoders are still resolving (each
96 // one either succeeds or fails to initialize its codec). finalize() spawns the
97 // EncodingFinalizer thread right away, but it blocks on its own
98 // m_encodersResolvedSemaphore. handleEncoderResolved() writes the header (if
99 // every encoder succeeded), calls startEncoding() for all of them, and only
100 // then releases that semaphore (via m_finalizer):
101 // None -> FormatsInitializing -> EncodersInitializing -> Encoding -> Finalizing
102 // -> Finalizing (if any encoder failed)
103 enum class State {
104 None,
105 FormatsInitializing,
106 EncodersInitializing,
107 Encoding, // header written
108 Finalizing
109 };
110
111 class EncodingFinalizer : public QThread
112 {
113 public:
114 explicit EncodingFinalizer(RecordingEngine &recordingEngine);
115
116 void run() override;
117
118 private:
119 RecordingEngine &m_recordingEngine;
120 };
121
123 void addAudioInput(QFFmpegAudioInput *input);
124 void addAudioBufferInput(QPlatformAudioBufferInput *input, const QAudioBuffer &firstBuffer);
125 AudioEncoder *createAudioEncoder(const QAudioFormat &format);
126
127 void addVideoSource(QPlatformVideoSource *source, const QVideoFrame &firstFrame);
128 void handleSourceEndOfStream();
129
130 void handleEncodersResolved(const QList<QFuture<bool>> &resolutions);
131
132 bool startEncoders();
133
134 size_t encodersCount() const { return m_audioEncoders.size() + m_videoEncoders.size(); }
135
136 void stopAndDeleteThreads();
137
138 template <typename F, typename... Args>
139 void forEachEncoder(F &&f, Args &&...args);
140
141 template <typename F>
142 bool allOfEncoders(F &&f) const;
143
144 void markEncodingStart(bool startOk);
145
146private:
147 QMediaEncoderSettings m_settings;
148 QMediaMetaData m_metaData;
149 std::unique_ptr<EncodingFormatContext> m_formatContext;
150 ConsumerThreadUPtr<Muxer> m_muxer;
151
152 std::vector<ConsumerThreadUPtr<AudioEncoder>> m_audioEncoders;
153 std::vector<ConsumerThreadUPtr<VideoEncoder>> m_videoEncoders;
154 std::unique_ptr<EncodingInitializer> m_formatsInitializer;
155
156 QMutex m_timeMutex;
157 qint64 m_timeRecorded = 0;
158
159 bool m_autoStop = false;
160 State m_state = State::None;
161
162 QPromise<bool> m_startEncodingPromise;
163 EncodingFinalizer *m_finalizer = nullptr;
164};
165
166} // namespace QFFmpeg
167
168QT_END_NAMESPACE
169
170#endif
The QAudioFormat class stores audio stream parameter information.
void setCaptureSession(QFFmpegMediaCaptureSession *session)
void record(QMediaEncoderSettings &settings) override
bool isLocationWritable(const QUrl &sink) const override
~QFFmpegMediaRecorder() override
QMediaMetaData metaData() const override
void setMetaData(const QMediaMetaData &) override
bool initialize(const std::vector< QAudioBufferSource * > &audioSources, const std::vector< QPlatformVideoSource * > &videoSources)
void setMetaData(const QMediaMetaData &metaData)
void sessionError(QMediaRecorder::Error code, const QString &description)
void streamInitializationError(QMediaRecorder::Error code, const QString &description)
QT_MANGLE_NAMESPACE(QMacScreenCaptureStreamDelegate) QMacScreenCaptureStreamDelegate
Combined button and popup list for selecting options.
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)