10#include <private/qabstractvideobuffer_p.h>
12#include <QtCore/qabstracteventdispatcher.h>
13#include <QtCore/qcoreapplication.h>
14#include <QtCore/qdir.h>
15#include <QtCore/qfileinfo.h>
16#include <QtCore/quuid.h>
17#include <mm/renderer.h>
31 return std::floor(
rate * 1000);
36 return std::floor(speed / 1000.0);
41 return std::clamp<int>(std::floor(volume * 100.0), 0, 100);
49 const int slashPos =
value.indexOf(
'/');
108 m_windowGrabber = windowGrabber;
119 qWarning(
"QnxRasterBuffer: need to unmap before mapping");
167void QQnxMediaPlayer::openConnection()
169 static int idCounter = 0;
171 m_connection = mmr_connect(
nullptr);
180 m_context = mmr_context_create(m_connection, m_contextName.
toLatin1(),
181 0, S_IRWXU|S_IRWXG|S_IRWXO);
196 switch (
event->state) {
207 m_windowGrabber->
stop();
209 if (m_platformVideoSink)
213 if (
event->speed == 0) {
215 m_windowGrabber->
pause();
217 m_windowGrabber->
resume();
220 m_windowGrabber->
start();
224 if (
event->speed != m_speed) {
225 m_speed =
event->speed;
228 m_configuredSpeed = m_speed;
242 handleMmEventStatusData(
event->data);
245 if (!
event->pos_str || isPendingPositionFlush())
254 qCritical(
"Could not parse position from '%s'", valueBa.constData());
265 const strm_string_t *
value = strm_dict_find_rstr(
data,
key);
274 const QString bufferLevel = getValue(
"bufferlevel");
286 const QString bufferStatus = getValue(
"bufferstatus");
287 const QString suspended = getValue(
"suspended");
307 if (
event->details.error.info.error_code == MMR_ERROR_NONE) {
313void QQnxMediaPlayer::closeConnection()
318 mmr_context_destroy(m_context);
320 m_contextName.
clear();
324 mmr_disconnect(m_connection);
325 m_connection =
nullptr;
336 const QFileInfo fileInfo(relativeFilePath);
345void QQnxMediaPlayer::attach()
348 if (isInputAttached())
351 if (!m_media.
isValid() || !m_context) {
358 if (!(attachVideoOutput() && attachAudioOutput() && attachInput())) {
366bool QQnxMediaPlayer::attachVideoOutput()
368 if (isVideoOutputAttached()) {
369 qWarning() <<
"QQnxMediaPlayer: Video output already attached!";
374 qWarning() <<
"QQnxMediaPlayer: No media player context!";
380 qWarning() <<
"QQnxMediaPlayer: Unable to find window group";
384 static int winIdCounter = 0;
392 if (m_platformVideoSink)
393 m_windowGrabber->
setRhi(m_platformVideoSink->
rhi());
396 const QString videoDeviceUrl =
QStringLiteral(
"screen:?winid=%1&wingrp=%2&initflags=invisible&nodstviewport=1")
399 m_videoId = mmr_output_attach(m_context, videoDeviceUrl.
toLatin1(),
"video");
401 if (m_videoId == -1) {
402 qWarning() <<
"mmr_output_attach() for video failed";
409bool QQnxMediaPlayer::attachAudioOutput()
411 if (isAudioOutputAttached()) {
412 qWarning() <<
"QQnxMediaPlayer: Audio output already attached!";
416 const QByteArray defaultAudioDevice =
qgetenv(
"QQNX_RENDERER_DEFAULT_AUDIO_SINK");
418 m_audioId = mmr_output_attach(m_context,
419 defaultAudioDevice.
isEmpty() ?
"snd:" : defaultAudioDevice.constData(),
"audio");
421 if (m_audioId == -1) {
422 emitMmError(
"mmr_output_attach() for audio failed");
430bool QQnxMediaPlayer::attachInput()
432 if (isInputAttached())
435 const QByteArray resourcePath = resourcePathForUrl(m_media);
440 if (mmr_input_attach(m_context, resourcePath.
constData(),
"track") != 0) {
449 m_inputAttached =
true;
454void QQnxMediaPlayer::detach()
459 if (isVideoOutputAttached())
462 if (isAudioOutputAttached())
465 if (isInputAttached())
471void QQnxMediaPlayer::detachVideoOutput()
473 m_windowGrabber->
stop();
475 if (m_platformVideoSink)
478 if (isVideoOutputAttached())
479 mmr_output_detach(m_context, m_videoId);
484void QQnxMediaPlayer::detachAudioOutput()
486 if (isAudioOutputAttached())
487 mmr_output_detach(m_context, m_audioId);
492void QQnxMediaPlayer::detachInput()
494 if (isInputAttached())
495 mmr_input_detach(m_context);
497 m_inputAttached =
false;
500bool QQnxMediaPlayer::isVideoOutputAttached()
const
502 return m_videoId != -1;
505bool QQnxMediaPlayer::isAudioOutputAttached()
const
507 return m_audioId != -1;
510bool QQnxMediaPlayer::isInputAttached()
const
512 return m_inputAttached;
515void QQnxMediaPlayer::updateScene(
const QSize &
size)
517 if (!m_platformVideoSink)
546 m_flushPositionTimer.
start();
555 emitMmError(
"Seeking failed");
558void QQnxMediaPlayer::flushPosition()
560 setPositionInternal(m_pendingPosition);
563bool QQnxMediaPlayer::isPendingPositionFlush()
const
565 return m_flushPositionTimer.
isActive();
568void QQnxMediaPlayer::setDeferredSpeedEnabled(
bool enabled)
570 m_deferredSpeedEnabled =
enabled;
573bool QQnxMediaPlayer::isDeferredSpeedEnabled()
const
575 return m_deferredSpeedEnabled;
578void QQnxMediaPlayer::setVolume(
float volume)
582 if (m_volume == normalizedVolume)
585 m_volume = normalizedVolume;
591void QQnxMediaPlayer::setMuted(
bool muted)
593 if (m_muted == muted)
601void QQnxMediaPlayer::updateVolume()
603 if (!m_context || m_audioId == -1)
606 const int volume = m_muted ? 0 : m_volume;
609 std::snprintf(
buf,
sizeof buf,
"%d", volume);
612 dict = strm_dict_set(dict,
"volume",
buf);
614 if (mmr_output_parameters(m_context, m_audioId, dict) != 0)
615 emitMmError(
"mmr_output_parameters: Setting volume failed");
621 if (m_audioOutput ==
out)
631 setVolume(
out ?
out->volume() : 1.);
632 setMuted(
out ?
out->isMuted() :
true);
639 return m_bufferLevel/100.0f;
665 return ::speedToRate(m_speed);
675 if (m_speed == speed)
681 m_deferredSpeed = speed;
685 if (mmr_speed_set(m_context, speed) != 0)
686 emitMmError(
"mmr_speed_set failed");
712 updateMetaData(
nullptr);
718 if (!m_media.
isValid() || !m_connection || !m_context || m_audioId == -1) {
726 setDeferredSpeedEnabled(
false);
728 if (m_deferredSpeed) {
730 m_deferredSpeed = {};
735 setDeferredSpeedEnabled(
true);
744 setPositionInternal(0);
749 if (mmr_play(m_context) != 0) {
751 emitMmError(
"mmr_play() failed");
774 setPositionInternal(0);
781 m_platformVideoSink = videoSink
786void QQnxMediaPlayer::startMonitoring()
791 this, &QQnxMediaPlayer::readEvents);
794 m_eventThread->
start();
797void QQnxMediaPlayer::stopMonitoring()
799 delete m_eventThread;
800 m_eventThread =
nullptr;
803void QQnxMediaPlayer::resetMonitoring()
810void QQnxMediaPlayer::handleMmPositionChanged(
qint64 newPosition)
812 m_position = newPosition;
820void QQnxMediaPlayer::updateBufferLevel(
int level,
int capacity)
823 m_bufferLevel =
qBound(0, m_bufferLevel, 100);
827void QQnxMediaPlayer::updateMetaData(
const strm_dict *dict)
837void QQnxMediaPlayer::emitMmError(
const char *msg)
842void QQnxMediaPlayer::emitMmError(
const QString &msg)
844 int errorCode = MMR_ERROR_NONE;
849void QQnxMediaPlayer::emitPError(
const QString &msg)
856void QQnxMediaPlayer::readEvents()
862 switch (
event->type) {
864 handleMmEventStatus(
event);
867 handleMmEventState(
event);
870 updateMetaData(
event->data);
873 handleMmEventError(
event);
894#include "moc_qqnxmediaplayer_p.cpp"
The QAbstractVideoBuffer class is an abstraction for video data. \inmodule QtMultimedia.
\qmltype AudioOutput \instantiates QAudioOutput
void mutedChanged(bool muted)
void volumeChanged(float volume)
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static qint64 applicationPid() Q_DECL_CONST_FUNCTION
\inmodule QtCore \reentrant
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
\inmodule QtCore \reentrant
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
bool isEglImageSupported() const
BufferView getNextBuffer()
void setWindowId(const QByteArray &windowId)
QByteArray windowGroupId() const
void updateScene(const QSize &size)
\macro QT_RESTRICTED_CAST_FROM_ASCII
QByteArray toLatin1() const &
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void clear()
Clears the contents of the string and makes it null.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void start(Priority=InheritPriority)
void setSingleShot(bool singleShot)
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
void setInterval(int msec)
bool isActive() const
Returns true if the timer is running (pending); otherwise returns false.
void timeout(QPrivateSignal)
This signal is emitted when the timer times out.
bool isValid() const
Returns true if the URL is non-empty and valid; otherwise returns false.
QByteArray toEncoded(FormattingOptions options=FullyEncoded) const
Returns the encoded representation of the URL if it's valid; otherwise an empty QByteArray is returne...
QString scheme() const
Returns the scheme of the URL.
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
The QVideoFrame class represents a frame of video data.
MapMode
Enumerates how a video buffer's data is mapped to system memory.
The QVideoSink class represents a generic sink for video data.
QPlatformVideoSink * platformVideoSink() const
MapData map(QVideoFrame::MapMode) override
Independently maps the planes of a video buffer to memory.
QVideoFrame::MapMode mapMode() const override
QnxRasterBuffer(QQnxWindowGrabber *windowGrabber)
void unmap() override
Releases the memory mapped by the map() function.
quint64 textureHandle(int plane) const override
Returns a texture handle to the data buffer.
QVideoFrame::MapMode mapMode() const override
QnxTextureBuffer(QQnxWindowGrabber *QQnxWindowGrabber)
MapData map(QVideoFrame::MapMode) override
Independently maps the planes of a video buffer to memory.
void unmap() override
Releases the memory mapped by the map() function.
const mmr_event_t * mmr_event_get(mmr_context_t *ctxt)
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qBound(const T &min, const T &val, const T &max)
GLenum GLuint GLint level
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define qUtf8Printable(string)
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
unsigned long long quint64
static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &errorSource, qsizetype errorPosition)
QT_BEGIN_NAMESPACE typedef uchar * output
QTextStream out(stdout)
[7]
QUrl url("example.com")
[constructor-url-reference]
myObject disconnect()
[26]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent