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
4#ifndef QSAMPLECACHE_P_H
5#define QSAMPLECACHE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qmap.h>
19#include <QtCore/qmutex.h>
20#include <QtCore/qobject.h>
21#include <QtCore/qpointer.h>
22#include <QtCore/qset.h>
23#include <QtCore/qthread.h>
24#include <QtCore/qurl.h>
25#include <QtCore/private/qglobal_p.h>
26#include <QtMultimedia/qaudioformat.h>
27
28QT_BEGIN_NAMESPACE
29
30class QIODevice;
31class QNetworkAccessManager;
32class QSampleCache;
33class QWaveDecoder;
34
35class Q_MULTIMEDIA_EXPORT QSample : public QObject
36{
37 Q_OBJECT
38public:
39 friend class QSampleCache;
40 enum State
41 {
42 Creating,
43 Loading,
44 Error,
45 Ready,
46 };
47
48 State state() const;
49 // These are not (currently) locked because they are only meant to be called after these
50 // variables are updated to their final states
51 const QByteArray& data() const { Q_ASSERT(state() == Ready); return m_soundData; }
52 const QAudioFormat& format() const { Q_ASSERT(state() == Ready); return m_audioFormat; }
53 void release();
54
55Q_SIGNALS:
56 void error(QPointer<QSample> self);
57 void ready(QPointer<QSample> self);
58
59protected:
60 QSample(const QUrl& url, QSampleCache *parent);
61
62private Q_SLOTS:
63 void load();
64 void handleLoadingError(int errorCode = -1);
65 void decoderError();
66 void readSample();
67 void decoderReady();
68
69private:
70 void onReady();
71 void cleanup();
72 void addRef();
73 void loadIfNecessary();
74 QSample();
75 ~QSample() override;
76
77 mutable QMutex m_mutex;
78 QSampleCache *m_parent;
79 QByteArray m_soundData;
80 QAudioFormat m_audioFormat;
81 std::unique_ptr<QIODevice> m_stream;
82 std::unique_ptr<QWaveDecoder> m_waveDecoder;
83 QUrl m_url;
84 qint64 m_sampleReadLength;
85 State m_state;
86 int m_ref;
87};
88
89class Q_MULTIMEDIA_EXPORT QSampleCache : public QObject
90{
91 Q_OBJECT
92public:
93 friend class QSample;
94
95 enum class SampleSourceType {
96 File,
97 NetworkManager,
98 };
99
100 QSampleCache(QObject *parent = nullptr);
101 ~QSampleCache() override;
102
103 QSample* requestSample(const QUrl& url);
104 void setCapacity(qint64 capacity);
105
106 bool isLoading() const;
107 bool isCached(const QUrl& url) const;
108
109 SampleSourceType sampleSourceType() const { return m_sampleSourceType; }
110
111 // For tests only
112 void setSampleSourceType(SampleSourceType sampleSourceType)
113 {
114 m_sampleSourceType = sampleSourceType;
115 }
116
117private:
118 std::unique_ptr<QIODevice> createStreamForSample(QSample &sample);
119
120private:
121 QMap<QUrl, QSample*> m_samples;
122 QSet<QSample*> m_staleSamples;
123
124#if QT_CONFIG(network)
125 std::unique_ptr<QNetworkAccessManager> m_networkAccessManager;
126 SampleSourceType m_sampleSourceType = SampleSourceType::NetworkManager;
127#else
128 SampleSourceType m_sampleSourceType = SampleSourceType::File;
129#endif
130
131 mutable QRecursiveMutex m_mutex;
132 qint64 m_capacity;
133 qint64 m_usage;
134 QThread m_loadingThread;
135
136 void refresh(qint64 usageChange);
137 bool notifyUnreferencedSample(QSample* sample);
138 void removeUnreferencedSample(QSample* sample);
139 void unloadSample(QSample* sample);
140
141 void loadingRelease();
142 int m_loadingRefCount;
143 QMutex m_loadingMutex;
144};
145
146QT_END_NAMESPACE
147
148#endif // QSAMPLECACHE_P_H
149

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtmultimedia/src/multimedia/audio/qsamplecache_p.h