Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qffmpegplaybackengine_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 QFFMPEGPLAYBACKENGINE_P_H
4#define QFFMPEGPLAYBACKENGINE_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/* Playback engine design description.
18 *
19 *
20 * PLAYBACK ENGINE OBJECTS
21 *
22 * - Playback engine manages 7 objects inside, each one works in a separate thread.
23 * Each object inherits PlaybackEngineObject. The objects are:
24 * Demuxer
25 * Stream Decoders: audio, video, subtitles
26 * Renderers: audio, video, subtitles
27 *
28 *
29 * THREADS:
30 *
31 * - By default, each object works in a separate thread. It's easy to reconfigure
32 * to using several objects in thread.
33 * - New thread is allocated if a new object is created and the engine doesn't
34 * have free threads. If it does, the thread is to be reused.
35 * - If all objects for some thread are deleted, the thread becomes free and the engine
36 * postpones its termination.
37 *
38 * OBJECTS WEAK CONNECTIVITY
39 *
40 * - The objects know nothing about others and about PlaybackEngine.
41 * For any interactions the objects use slots/signals.
42 *
43 * - PlaybackEngine knows the objects object and is able to create/delete them and
44 * call their public methods.
45 *
46 */
47
53
54#include <QtCore/qpointer.h>
55
56#include <unordered_map>
57
59
60class QAudioSink;
61class QVideoSink;
62class QAudioOutput;
64
65namespace QFFmpeg
66{
67
68class PlaybackEngine : public QObject
69{
71public:
73
74 ~PlaybackEngine() override;
75
76 void setMedia(MediaDataHolder media);
77
79
81
83
85
95
96 void seek(qint64 pos);
97
98 void setLoops(int loopsCount);
99
100 void setPlaybackRate(float rate);
101
102 float playbackRate() const;
103
105
106 qint64 currentPosition(bool topPos = true) const;
107
108 qint64 duration() const;
109
110 bool isSeekable() const;
111
112 const QList<MediaDataHolder::StreamInfo> &
114
115 const QMediaMetaData &metaData() const;
116
118
119signals:
121 void errorOccured(int, const QString &);
123 void buffered();
124
125protected: // objects managing
127 {
128 void operator()(PlaybackEngineObject *) const;
129
131 };
132
133 template<typename T>
134 using ObjectPtr = std::unique_ptr<T, ObjectDeleter>;
135
136 using RendererPtr = ObjectPtr<Renderer>;
137 using StreamPtr = ObjectPtr<StreamDecoder>;
138
139 template<typename T, typename... Args>
140 ObjectPtr<T> createPlaybackEngineObject(Args &&...args);
141
143
145
146 void updateActiveVideoOutput(QVideoSink *sink, bool cleanOutput = false);
147
148private:
149 void createStreamAndRenderer(QPlatformMediaPlayer::TrackType trackType);
150
151 void createDemuxer();
152
153 void registerObject(PlaybackEngineObject &object);
154
155 template<typename C, typename Action>
156 void forEachExistingObject(Action &&action);
157
158 template<typename Action>
159 void forEachExistingObject(Action &&action);
160
161 void forceUpdate();
162
163 void recreateObjects();
164
165 void createObjectsIfNeeded();
166
167 void updateObjectsPausedState();
168
169 void deleteFreeThreads();
170
171 void onRendererSynchronized(quint64 id, std::chrono::steady_clock::time_point time,
172 qint64 trackTime);
173
174 void onRendererFinished();
175
176 void onRendererLoopChanged(quint64 id, qint64 offset, int loopIndex);
177
178 void triggerStepIfNeeded();
179
180 static QString objectThreadName(const PlaybackEngineObject &object);
181
182 std::optional<Codec> codecForTrack(QPlatformMediaPlayer::TrackType trackType);
183
184 bool hasMediaStream() const;
185
186 void finilizeTime(qint64 pos);
187
188 void finalizeOutputs();
189
190 bool hasRenderer(quint64 id) const;
191
192 void updateVideoSinkSize(QVideoSink *prevSink = nullptr);
193
194 qint64 boundPosition(qint64 position) const;
195
196private:
197 MediaDataHolder m_media;
198
199 TimeController m_timeController;
200
201 std::unordered_map<QString, std::unique_ptr<QThread>> m_threads;
202 bool m_threadsDirty = false;
203
204 QPointer<QVideoSink> m_videoSink;
205 QPointer<QAudioOutput> m_audioOutput;
206
208
209 ObjectPtr<Demuxer> m_demuxer;
210 std::array<StreamPtr, QPlatformMediaPlayer::NTrackTypes> m_streams;
211 std::array<RendererPtr, QPlatformMediaPlayer::NTrackTypes> m_renderers;
212
213 std::array<std::optional<Codec>, QPlatformMediaPlayer::NTrackTypes> m_codecs;
214 int m_loops = QMediaPlayer::Once;
215 LoopOffset m_currentLoopOffset;
216};
217
218template<typename T, typename... Args>
220{
221 auto result = ObjectPtr<T>(new T(std::forward<Args>(args)...), { this });
222 registerObject(*result);
223 return result;
224}
225}
226
228
229#endif // QFFMPEGPLAYBACKENGINE_P_H
\qmltype AudioOutput \instantiates QAudioOutput
The QAudioSink class provides an interface for sending audio data to an audio output device.
Definition qaudiosink.h:24
int activeTrack(QPlatformMediaPlayer::TrackType type) const
void setVideoSink(QVideoSink *sink)
void setState(QMediaPlayer::PlaybackState state)
virtual RendererPtr createRenderer(QPlatformMediaPlayer::TrackType trackType)
ObjectPtr< T > createPlaybackEngineObject(Args &&...args)
void setAudioSink(QAudioOutput *output)
qint64 currentPosition(bool topPos=true) const
void errorOccured(int, const QString &)
ObjectPtr< Renderer > RendererPtr
const QList< MediaDataHolder::StreamInfo > & streamInfo(QPlatformMediaPlayer::TrackType trackType) const
std::unique_ptr< T, ObjectDeleter > ObjectPtr
ObjectPtr< StreamDecoder > StreamPtr
void setActiveTrack(QPlatformMediaPlayer::TrackType type, int streamNumber)
void setMedia(MediaDataHolder media)
const QMediaMetaData & metaData() const
void updateActiveAudioOutput(QAudioOutput *output)
void updateActiveVideoOutput(QVideoSink *sink, bool cleanOutput=false)
\inmodule QtMultimedia
PlaybackState
Defines the current state of a media player.
\inmodule QtCore
Definition qobject.h:103
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
The QVideoSink class represents a generic sink for video data.
Definition qvideosink.h:22
else opt state
[0]
Combined button and popup list for selecting options.
GLenum type
GLenum GLuint GLintptr offset
GLuint GLenum * rate
GLsizei GLenum GLboolean sink
GLuint64EXT * result
[6]
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_OBJECT
#define signals
unsigned long long quint64
Definition qtypes.h:61
long long qint64
Definition qtypes.h:60
QT_BEGIN_NAMESPACE typedef uchar * output
QJSValueList args
void operator()(PlaybackEngineObject *) const