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

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