diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2014-11-21 16:12:44 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2014-11-21 16:12:44 +0100 |
commit | eddc8e1e58c0377ae392409d9afccea91ba1cd22 (patch) | |
tree | 652a9c8229ce8b5137093e2ee82e2a83c6975b91 /src | |
parent | c3f5a15f24f4421e0a096b2272273d9a85f70851 (diff) | |
parent | 2020b032e83d1b61736a80a6815635aa7451deed (diff) |
Merge remote-tracking branch 'origin/5.4' into dev
Change-Id: Id87e56ccfc9f33f98c3d06991f6fe9c14d38fbac
Diffstat (limited to 'src')
-rw-r--r-- | src/gsttools/qgstutils.cpp | 25 | ||||
-rw-r--r-- | src/multimedia/gsttools_headers/qgstutils_p.h | 2 | ||||
-rw-r--r-- | src/plugins/gstreamer/camerabin/camerabinsession.cpp | 36 | ||||
-rw-r--r-- | src/plugins/opensles/qopenslesaudioinput.cpp | 5 | ||||
-rw-r--r-- | src/plugins/opensles/qopenslesaudioinput.h | 1 | ||||
-rw-r--r-- | src/plugins/opensles/qopenslesaudiooutput.cpp | 34 | ||||
-rw-r--r-- | src/plugins/opensles/qopenslesaudiooutput.h | 1 | ||||
-rw-r--r-- | src/plugins/wmf/evrd3dpresentengine.cpp | 8 | ||||
-rw-r--r-- | src/plugins/wmf/player/mfplayercontrol.cpp | 1 | ||||
-rw-r--r-- | src/qtmultimediaquicktools/qsgvideonode_i420.cpp | 8 |
10 files changed, 98 insertions, 23 deletions
diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp index 8d484aa6d..556fc03cc 100644 --- a/src/gsttools/qgstutils.cpp +++ b/src/gsttools/qgstutils.cpp @@ -430,13 +430,15 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa QStringLiteral("primary"), QGstreamerVideoInputDeviceControl::primaryCamera(), 0, - QCamera::BackFace + QCamera::BackFace, + QByteArray() }; const CameraInfo secondary = { QStringLiteral("secondary"), QGstreamerVideoInputDeviceControl::secondaryCamera(), 0, - QCamera::FrontFace + QCamera::FrontFace, + QByteArray() }; devices.append(primary); @@ -498,14 +500,17 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa if (isCamera) { // find out its driver "name" + QByteArray driver; QString name; struct v4l2_capability vcap; memset(&vcap, 0, sizeof(struct v4l2_capability)); - if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0) + if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0) { name = entryInfo.fileName(); - else + } else { + driver = QByteArray((const char*)vcap.driver); name = QString::fromUtf8((const char*)vcap.card); + } //qDebug() << "found camera: " << name; @@ -513,7 +518,8 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa entryInfo.absoluteFilePath(), name, 0, - QCamera::UnspecifiedPosition + QCamera::UnspecifiedPosition, + driver }; devices.append(device); } @@ -561,6 +567,15 @@ int QGstUtils::cameraOrientation(const QString &device, GstElementFactory * fact return 0; } +QByteArray QGstUtils::cameraDriver(const QString &device, GstElementFactory *factory) +{ + foreach (const CameraInfo &camera, enumerateCameras(factory)) { + if (camera.name == device) + return camera.driver; + } + return QByteArray(); +} + void qt_gst_object_ref_sink(gpointer object) { diff --git a/src/multimedia/gsttools_headers/qgstutils_p.h b/src/multimedia/gsttools_headers/qgstutils_p.h index 48434b2f7..65ff759aa 100644 --- a/src/multimedia/gsttools_headers/qgstutils_p.h +++ b/src/multimedia/gsttools_headers/qgstutils_p.h @@ -65,6 +65,7 @@ namespace QGstUtils { QString description; int orientation; QCamera::Position position; + QByteArray driver; }; QMap<QByteArray, QVariant> gstTagListToMap(const GstTagList *list); @@ -84,6 +85,7 @@ namespace QGstUtils { QString cameraDescription(const QString &device, GstElementFactory * factory = 0); QCamera::Position cameraPosition(const QString &device, GstElementFactory * factory = 0); int cameraOrientation(const QString &device, GstElementFactory * factory = 0); + QByteArray cameraDriver(const QString &device, GstElementFactory * factory = 0); } void qt_gst_object_ref_sink(gpointer object); diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index 019783971..a4038c589 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -412,9 +412,41 @@ GstElement *CameraBinSession::buildCameraSource() if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "video-source")) { GstElement *src = 0; - if (m_videoInputFactory) + /* QT_GSTREAMER_CAMERABIN_VIDEOSRC can be used to set the video source element. + + --- Usage + + QT_GSTREAMER_CAMERABIN_VIDEOSRC=[drivername=elementname[,drivername2=elementname2 ...],][elementname] + + --- Examples + + Always use 'somevideosrc': + QT_GSTREAMER_CAMERABIN_VIDEOSRC="somevideosrc" + + Use 'somevideosrc' when the device driver is 'somedriver', otherwise use default: + QT_GSTREAMER_CAMERABIN_VIDEOSRC="somedriver=somevideosrc" + + Use 'somevideosrc' when the device driver is 'somedriver', otherwise use 'somevideosrc2' + QT_GSTREAMER_CAMERABIN_VIDEOSRC="somedriver=somevideosrc,somevideosrc2" + */ + const QByteArray envVideoSource = qgetenv("QT_GSTREAMER_CAMERABIN_VIDEOSRC"); + if (!envVideoSource.isEmpty()) { + QList<QByteArray> sources = envVideoSource.split(','); + foreach (const QByteArray &source, sources) { + QList<QByteArray> keyValue = source.split('='); + if (keyValue.count() == 1) { + src = gst_element_factory_make(keyValue.at(0), "camera_source"); + break; + } else if (keyValue.at(0) == QGstUtils::cameraDriver(m_inputDevice, m_sourceFactory)) { + src = gst_element_factory_make(keyValue.at(1), "camera_source"); + break; + } + } + } else if (m_videoInputFactory) { src = m_videoInputFactory->buildElement(); - else + } + + if (!src) src = gst_element_factory_make("v4l2src", "camera_source"); if (src) { diff --git a/src/plugins/opensles/qopenslesaudioinput.cpp b/src/plugins/opensles/qopenslesaudioinput.cpp index cd592a7d6..181649ae0 100644 --- a/src/plugins/opensles/qopenslesaudioinput.cpp +++ b/src/plugins/opensles/qopenslesaudioinput.cpp @@ -70,7 +70,6 @@ QOpenSLESAudioInput::QOpenSLESAudioInput(const QByteArray &device) , m_errorState(QAudio::NoError) , m_deviceState(QAudio::StoppedState) , m_lastNotifyTime(0) - , m_volume(1) , m_bufferSize(0) , m_periodSize(0) , m_intervalTime(1000) @@ -480,12 +479,12 @@ qint64 QOpenSLESAudioInput::elapsedUSecs() const void QOpenSLESAudioInput::setVolume(qreal vol) { // Volume interface is not available for the recorder on Android - m_volume = vol; + Q_UNUSED(vol); } qreal QOpenSLESAudioInput::volume() const { - return m_volume; + return qreal(1.0); } void QOpenSLESAudioInput::reset() diff --git a/src/plugins/opensles/qopenslesaudioinput.h b/src/plugins/opensles/qopenslesaudioinput.h index 7ffff0470..481ff371a 100644 --- a/src/plugins/opensles/qopenslesaudioinput.h +++ b/src/plugins/opensles/qopenslesaudioinput.h @@ -113,7 +113,6 @@ private: QAudio::State m_deviceState; QTime m_clockStamp; qint64 m_lastNotifyTime; - qreal m_volume; int m_bufferSize; int m_periodSize; int m_intervalTime; diff --git a/src/plugins/opensles/qopenslesaudiooutput.cpp b/src/plugins/opensles/qopenslesaudiooutput.cpp index c45fbd3c5..b89d8b93c 100644 --- a/src/plugins/opensles/qopenslesaudiooutput.cpp +++ b/src/plugins/opensles/qopenslesaudiooutput.cpp @@ -157,7 +157,7 @@ int QOpenSLESAudioOutput::bytesFree() const if (m_state != QAudio::ActiveState && m_state != QAudio::IdleState) return 0; - return m_availableBuffers.load() ? m_bufferSize : 0; + return m_availableBuffers.loadAcquire() ? m_bufferSize : 0; } int QOpenSLESAudioOutput::periodSize() const @@ -343,6 +343,11 @@ void QOpenSLESAudioOutput::onEOSEvent() setError(QAudio::UnderrunError); } +void QOpenSLESAudioOutput::onBytesProcessed(qint64 bytes) +{ + m_processedBytes += bytes; +} + void QOpenSLESAudioOutput::bufferAvailable(quint32 count, quint32 playIndex) { Q_UNUSED(count); @@ -351,11 +356,13 @@ void QOpenSLESAudioOutput::bufferAvailable(quint32 count, quint32 playIndex) if (m_state == QAudio::StoppedState) return; - if (!m_pullMode) { - m_availableBuffers.fetchAndAddRelaxed(1); + if (!m_pullMode) { // We're in push mode. + // Signal that there is a new open slot in the buffer and return + m_availableBuffers.fetchAndAddRelease(1); return; } + // We're in pull mode. const int index = m_nextBuffer * m_bufferSize; const qint64 readSize = m_audioSource->read(m_buffers + index, m_bufferSize); @@ -370,8 +377,8 @@ void QOpenSLESAudioOutput::bufferAvailable(quint32 count, quint32 playIndex) return; } - m_processedBytes += readSize; m_nextBuffer = (m_nextBuffer + 1) % BUFFER_COUNT; + QMetaObject::invokeMethod(this, "onBytesProcessed", Qt::QueuedConnection, Q_ARG(qint64, readSize)); } void QOpenSLESAudioOutput::playCallback(SLPlayItf player, void *ctx, SLuint32 event) @@ -570,7 +577,7 @@ void QOpenSLESAudioOutput::destroyPlayer() m_buffers = Q_NULLPTR; m_processedBytes = 0; m_nextBuffer = 0; - m_availableBuffers = BUFFER_COUNT; + m_availableBuffers.storeRelease(BUFFER_COUNT); m_playItf = Q_NULLPTR; m_volumeItf = Q_NULLPTR; m_bufferQueueItf = Q_NULLPTR; @@ -599,20 +606,32 @@ void QOpenSLESAudioOutput::startPlayer() qint64 QOpenSLESAudioOutput::writeData(const char *data, qint64 len) { - if (!len || !m_availableBuffers.load()) + if (!len) return 0; if (len > m_bufferSize) len = m_bufferSize; + // Acquire one slot in the buffer + const int before = m_availableBuffers.fetchAndAddAcquire(-1); + + // If there where no vacant slots, then we just overdrew the buffer account... + if (before < 1) { + m_availableBuffers.fetchAndAddRelease(1); + return 0; + } + const int index = m_nextBuffer * m_bufferSize; ::memcpy(m_buffers + index, data, len); const SLuint32 res = (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf, m_buffers + index, len); - if (res == SL_RESULT_BUFFER_INSUFFICIENT) + // If we where unable to enqueue a new buffer, give back the acquired slot. + if (res == SL_RESULT_BUFFER_INSUFFICIENT) { + m_availableBuffers.fetchAndAddRelease(1); return 0; + } if (res != SL_RESULT_SUCCESS) { setError(QAudio::FatalError); @@ -621,7 +640,6 @@ qint64 QOpenSLESAudioOutput::writeData(const char *data, qint64 len) } m_processedBytes += len; - m_availableBuffers.fetchAndAddRelaxed(-1); setState(QAudio::ActiveState); setError(QAudio::NoError); m_nextBuffer = (m_nextBuffer + 1) % BUFFER_COUNT; diff --git a/src/plugins/opensles/qopenslesaudiooutput.h b/src/plugins/opensles/qopenslesaudiooutput.h index 200b4a3cc..f36a5bf04 100644 --- a/src/plugins/opensles/qopenslesaudiooutput.h +++ b/src/plugins/opensles/qopenslesaudiooutput.h @@ -79,6 +79,7 @@ private: friend class SLIODevicePrivate; Q_INVOKABLE void onEOSEvent(); + Q_INVOKABLE void onBytesProcessed(qint64 bytes); void bufferAvailable(quint32 count, quint32 playIndex); static void playCallback(SLPlayItf playItf, void *ctx, SLuint32 event); diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/wmf/evrd3dpresentengine.cpp index 42d0dea4e..9a508520e 100644 --- a/src/plugins/wmf/evrd3dpresentengine.cpp +++ b/src/plugins/wmf/evrd3dpresentengine.cpp @@ -184,8 +184,12 @@ D3DPresentEngine::~D3DPresentEngine() m_egl->destroySurface(m_eglDisplay, m_eglSurface); m_eglSurface = NULL; } - if (m_glTexture) - QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_glTexture); + if (m_glTexture) { + if (QOpenGLContext *current = QOpenGLContext::currentContext()) + current->functions()->glDeleteTextures(1, &m_glTexture); + else + qWarning() << "D3DPresentEngine: Cannot obtain GL context, unable to delete textures"; + } delete m_glContext; delete m_offscreenSurface; diff --git a/src/plugins/wmf/player/mfplayercontrol.cpp b/src/plugins/wmf/player/mfplayercontrol.cpp index 33754831d..02bd902e0 100644 --- a/src/plugins/wmf/player/mfplayercontrol.cpp +++ b/src/plugins/wmf/player/mfplayercontrol.cpp @@ -39,6 +39,7 @@ MFPlayerControl::MFPlayerControl(MFPlayerSession *session) : QMediaPlayerControl(session) , m_state(QMediaPlayer::StoppedState) +, m_stateDirty(false) , m_videoAvailable(false) , m_audioAvailable(false) , m_duration(-1) diff --git a/src/qtmultimediaquicktools/qsgvideonode_i420.cpp b/src/qtmultimediaquicktools/qsgvideonode_i420.cpp index 5b8b7ce8a..17b4924d0 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_i420.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_i420.cpp @@ -227,8 +227,12 @@ QSGVideoMaterial_YUV420::QSGVideoMaterial_YUV420(const QVideoSurfaceFormat &form QSGVideoMaterial_YUV420::~QSGVideoMaterial_YUV420() { - if (!m_textureSize.isEmpty()) - QOpenGLContext::currentContext()->functions()->glDeleteTextures(Num_Texture_IDs, m_textureIds); + if (!m_textureSize.isEmpty()) { + if (QOpenGLContext *current = QOpenGLContext::currentContext()) + current->functions()->glDeleteTextures(Num_Texture_IDs, m_textureIds); + else + qWarning() << "QSGVideoMaterial_YUV420: Cannot obtain GL context, unable to delete textures"; + } } void QSGVideoMaterial_YUV420::bind() |