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 <QtMultimedia/private/qplatformmediarecorder_p.h>
21#include <qmediarecorder.h>
22
23QT_BEGIN_NAMESPACE
24
25class QAudioBuffer;
26class QAudioFormat;
27class QFFmpegAudioInput;
28class QPlatformAudioBufferInput;
29class QAudioBufferSource;
30class QPlatformVideoSource;
31class QVideoFrame;
32
33namespace QFFmpeg
34{
35
36class RecordingEngine;
37class Muxer;
38class AudioEncoder;
39class VideoEncoder;
40class VideoFrameEncoder;
41class EncodingInitializer;
42
43class RecordingEngine : public QObject
44{
45 Q_OBJECT
46public:
47 RecordingEngine(const QMediaEncoderSettings &settings, std::unique_ptr<EncodingFormatContext> context);
48 ~RecordingEngine() override;
49
50 /** Initializes the recording engine immediately or
51 * postpones it if no source formats provided.
52 * Returns true if no session errors have occurred during the immediate run or
53 * the engine is to be initialized postponly.
54 * If any session error has occurred, it emits the signal sessionError and returns false.
55 */
56 bool initialize(const std::vector<QAudioBufferSource *> &audioSources,
57 const std::vector<QPlatformVideoSource *> &videoSources);
58 void finalize();
59
60 void setPaused(bool p);
61
62 void setAutoStop(bool autoStop);
63
64 bool autoStop() const { return m_autoStop; }
65
66 void setMetaData(const QMediaMetaData &metaData);
67 AVFormatContext *avFormatContext() { return m_formatContext->avFormatContext(); }
68 Muxer *getMuxer() { return m_muxer.get(); }
69
70 bool isEndOfSourceStreams() const;
71
72public Q_SLOTS:
73 void newTimeStamp(qint64 time);
74
75Q_SIGNALS:
76 void durationChanged(qint64 duration);
77 void sessionError(QMediaRecorder::Error code, const QString &description);
78 void streamInitializationError(QMediaRecorder::Error code, const QString &description);
79 void finalizationDone();
80 void autoStopped();
81
82private:
83 // Normal states transition, Stop is called upon Encoding,
84 // header, content, and trailer are written:
85 // None -> FormatsInitializing -> EncodersInitializing -> Encoding -> Finalizing
86 //
87 // Stop is called upon FormatsInitializing, nothing is written to the output:
88 // None -> FormatsInitializing -> Finalizing
89 //
90 // Stop is called upon EncodersInitializing, nothing is written to the output:
91 // None -> FormatsInitializing -> EncodersInitializing -> Finalizing
92 enum class State {
93 None,
94 FormatsInitializing,
95 EncodersInitializing,
96 Encoding, // header written
97 Finalizing
98 };
99
100 class EncodingFinalizer : public QThread
101 {
102 public:
103 EncodingFinalizer(RecordingEngine &recordingEngine, bool writeTrailer);
104
105 void run() override;
106
107 private:
108 RecordingEngine &m_recordingEngine;
109 bool m_writeTrailer;
110 };
111
112 friend class EncodingInitializer;
113 void addAudioInput(QFFmpegAudioInput *input);
114 void addAudioBufferInput(QPlatformAudioBufferInput *input, const QAudioBuffer &firstBuffer);
115 AudioEncoder *createAudioEncoder(const QAudioFormat &format);
116
117 void addVideoSource(QPlatformVideoSource *source, const QVideoFrame &firstFrame);
118 void handleSourceEndOfStream();
119 void handleEncoderInitialization();
120
121 bool startEncoders();
122
123 size_t encodersCount() const { return m_audioEncoders.size() + m_videoEncoders.size(); }
124
125 void stopAndDeleteThreads();
126
127 template <typename F, typename... Args>
128 void forEachEncoder(F &&f, Args &&...args);
129
130 template <typename F>
131 bool allOfEncoders(F &&f) const;
132
133private:
134 QMediaEncoderSettings m_settings;
135 QMediaMetaData m_metaData;
136 std::unique_ptr<EncodingFormatContext> m_formatContext;
137 ConsumerThreadUPtr<Muxer> m_muxer;
138
139 std::vector<ConsumerThreadUPtr<AudioEncoder>> m_audioEncoders;
140 std::vector<ConsumerThreadUPtr<VideoEncoder>> m_videoEncoders;
141 std::unique_ptr<EncodingInitializer> m_formatsInitializer;
142
143 QMutex m_timeMutex;
144 qint64 m_timeRecorded = 0;
145
146 bool m_autoStop = false;
147 size_t m_initializedEncodersCount = 0;
148 State m_state = State::None;
149};
150
151} // namespace QFFmpeg
152
153QT_END_NAMESPACE
154
155#endif
156

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtmultimedia/src/plugins/multimedia/ffmpeg/recordingengine/qffmpegrecordingengine_p.h