11#include <gst/gstvalue.h>
12#include <gst/base/gstbasesrc.h>
14#include <QtCore/qdatetime.h>
15#include <QtCore/qdebug.h>
16#include <QtCore/qsize.h>
17#include <QtCore/qtimer.h>
18#include <QtCore/qdebug.h>
19#include <QtCore/qdir.h>
20#include <QtCore/qstandardpaths.h>
21#include <QtCore/qurl.h>
22#include <QtCore/qloggingcategory.h>
24#define MAX_BUFFERS_IN_QUEUE 4
60 m_playbin(
std::move(playbin)),
61 m_audioConvert(
std::move(audioconvert))
70 m_outputBin.
add(m_audioConvert);
75 g_object_set(m_playbin.
object(),
"audio-sink", m_outputBin.
element(), NULL);
77 m_deepNotifySourceConnection = m_playbin.
connect(
78 "deep-notify::source", (GCallback)&configureAppSrcElement, (gpointer)
this);
82 m_playbin.
set(
"volume", volume);
91#if QT_CONFIG(gstreamer_app)
96#if QT_CONFIG(gstreamer_app)
97void QGstreamerAudioDecoder::configureAppSrcElement([[maybe_unused]] GObject *
object, GObject *orig,
98 [[maybe_unused]] GParamSpec *pspec,
106 g_object_get(orig,
"source", &appsrc, NULL);
108 auto *qAppSrc = self->m_appSrc;
109 qAppSrc->setExternalAppSrc(QGstAppSrc{
110 qGstSafeCast<GstAppSrc>(appsrc.get()),
111 QGstAppSrc::NeedsRef,
113 qAppSrc->setup(
self->mDevice);
119 qCDebug(qLcGstreamerAudioDecoder) <<
"received bus message:" <<
message;
121 GstMessage *gm =
message.message();
124 case GST_MESSAGE_DURATION: {
129 case GST_MESSAGE_ERROR: {
134 gst_message_parse_error(gm, &err, &
debug);
136 if (
message.source() == m_playbin) {
137 if (err.
get()->domain == GST_STREAM_ERROR
138 && err.
get()->code == GST_STREAM_ERROR_CODEC_NOT_FOUND)
140 tr(
"Cannot play stream of type: <unknown>"));
146 if (err.
get()->domain == GST_STREAM_ERROR) {
147 switch (err.
get()->code) {
148 case GST_STREAM_ERROR_DECRYPT:
149 case GST_STREAM_ERROR_DECRYPT_NOKEY:
152 case GST_STREAM_ERROR_FORMAT:
153 case GST_STREAM_ERROR_DEMUX:
154 case GST_STREAM_ERROR_DECODE:
155 case GST_STREAM_ERROR_WRONG_TYPE:
156 case GST_STREAM_ERROR_TYPE_NOT_FOUND:
157 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
163 }
else if (err.
get()->domain == GST_CORE_ERROR) {
164 switch (err.
get()->code) {
165 case GST_CORE_ERROR_MISSING_PLUGIN:
179 if (
message.source() == m_playbin)
180 return handlePlaybinMessage(
message);
188 GstMessage *gm =
message.message();
190 switch (GST_MESSAGE_TYPE(gm)) {
191 case GST_MESSAGE_STATE_CHANGED: {
200 case GST_STATE_VOID_PENDING:
202 case GST_STATE_READY:
204 case GST_STATE_PLAYING:
207 case GST_STATE_PAUSED:
213 m_durationQueries = 5;
222 case GST_MESSAGE_EOS:
227 case GST_MESSAGE_ERROR:
228 Q_UNREACHABLE_RETURN(
false);
230 case GST_MESSAGE_WARNING:
234 case GST_MESSAGE_INFO: {
235 if (qLcGstreamerAudioDecoder().isDebugEnabled())
258 bool isSignalRequired = (mSource !=
fileName);
260 if (isSignalRequired)
273 bool isSignalRequired = (mDevice !=
device);
275 if (isSignalRequired)
285 }
else if (mDevice) {
295 m_appSrc = maybeAppSrc.value();
302 m_playbin.
set(
"uri",
"appsrc://");
310 setAudioFlags(
false);
312 m_appSink.setCaps(caps);
316 m_appSink.setCaps({});
320 if (m_playbin.
setState(GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
321 qWarning() <<
"GStreamer; Unable to start decoding process";
330 m_currentSessionId += 1;
334 if (m_buffersAvailable != 0) {
335 m_buffersAvailable = 0;
339 if (m_position != -1) {
344 if (m_duration != -1) {
369 if (m_buffersAvailable == 0)
372 m_buffersAvailable -= 1;
374 if (m_buffersAvailable == 0)
378 GstBuffer *
buffer = gst_sample_get_buffer(sample.
get());
380 gst_buffer_map(
buffer, &mapInfo, GST_MAP_READ);
381 const char *bufferData = (
const char *)mapInfo.data;
382 int bufferSize = mapInfo.size;
396 gst_buffer_unmap(
buffer, &mapInfo);
417GstFlowReturn QGstreamerAudioDecoder::newSample(GstAppSink *)
423 if (sessionId != m_currentSessionId)
426 m_buffersAvailable += 1;
434GstFlowReturn QGstreamerAudioDecoder::new_sample(GstAppSink *
sink, gpointer
user_data)
437 qCDebug(qLcGstreamerAudioDecoder) <<
"QGstreamerAudioDecoder::new_sample";
438 return decoder->newSample(
sink);
441void QGstreamerAudioDecoder::setAudioFlags(
bool wantNativeAudio)
453void QGstreamerAudioDecoder::addAppSink()
458 qCDebug(qLcGstreamerAudioDecoder) <<
"QGstreamerAudioDecoder::addAppSink";
459 m_appSink = QGstAppSink::create(
"decoderAppSink");
462 m_appSink.setCallbacks(
callbacks,
this,
nullptr);
464 gst_base_sink_set_sync(m_appSink.baseSink(), FALSE);
467 m_outputBin.add(m_appSink);
468 qLinkGstElements(m_audioConvert, m_appSink);
472void QGstreamerAudioDecoder::removeAppSink()
477 qCDebug(qLcGstreamerAudioDecoder) <<
"QGstreamerAudioDecoder::removeAppSink";
480 qUnlinkGstElements(m_audioConvert, m_appSink);
481 m_outputBin.stopAndRemoveElements(m_appSink);
486void QGstreamerAudioDecoder::updateDuration()
496 m_durationQueries = 0;
498 if (m_durationQueries > 0) {
500 int delay = 25 << (5 - m_durationQueries);
506qint64 QGstreamerAudioDecoder::getPositionFromBuffer(GstBuffer*
buffer)
518#include "moc_qgstreameraudiodecoder_p.cpp"
IOBluetoothDevice * device
The QAudioDecoder class implements decoding audio.
Error
Defines a media player error condition.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QMaybe< QGstAppSource * > create(QObject *parent=nullptr)
std::enable_if_t<(std::is_base_of_v< QGstElement, Ts > &&...), void add)(const Ts &...ts)
static QGstBin create(const char *name)
void addGhostPad(const QGstElement &child, const char *name)
GstElement * element() const
static QGstElement createFromFactory(const char *factory, const char *name=nullptr)
QGstPipeline getPipeline() const
QGObjectHandlerConnection connect(const char *name, GCallback callback, gpointer userData)
int getInt(const char *property) const
void set(const char *property, const char *str)
GstObject * object() const
GstStateChangeReturn setState(GstState state)
void installMessageFilter(QGstreamerSyncMessageFilter *filter)
void dumpGraph(const char *fileName)
void removeMessageFilter(QGstreamerSyncMessageFilter *filter)
void modifyPipelineWhileNotRunning(Functor &&fn)
static QGstPipeline adopt(GstPipeline *)
void setSourceDevice(QIODevice *device) override
QAudioFormat audioFormat() const override
virtual ~QGstreamerAudioDecoder()
QIODevice * sourceDevice() const override
void setSource(const QUrl &fileName) override
qint64 duration() const override
QUrl source() const override
void setAudioFormat(const QAudioFormat &format) override
static QMaybe< QPlatformAudioDecoder * > create(QAudioDecoder *parent)
QAudioBuffer read() override
qint64 position() const override
bool processBusMessage(const QGstreamerMessage &message) override
\inmodule QtCore \reentrant
bool isOpen() const
Returns true if the device is open; otherwise returns false.
bool isReadable() const
Returns true if data can be read from the device; otherwise returns false.
QObject * parent() const
Returns a pointer to the parent object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool singleShot
whether the timer is a single-shot timer
Type get() const noexcept
QByteArray toEncoded(FormattingOptions options=FullyEncoded) const
Returns the encoded representation of the URL if it's valid; otherwise an empty QByteArray is returne...
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
void clear()
Resets the content of the QUrl.
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
QGstCaps capsForAudioFormat(const QAudioFormat &format)
QAudioFormat audioFormatForSample(GstSample *sample)
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void * user_data
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall * pending
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
QString errorMessageCannotFindElement(std::string_view element)
@ GST_PLAY_FLAG_NATIVE_AUDIO
@ GST_PLAY_FLAG_BUFFERING
@ GST_PLAY_FLAG_NATIVE_VIDEO
@ GST_PLAY_FLAG_SOFT_VOLUME
#define MAX_BUFFERS_IN_QUEUE
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLuint GLsizei const GLchar * message
GLint GLsizei GLsizei GLenum format
GLsizei GLenum GLboolean sink
PromiseCallbacks callbacks
QLatin1StringView QLatin1String
Type get() const noexcept