summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-11-21 16:12:44 +0100
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-11-21 16:12:44 +0100
commiteddc8e1e58c0377ae392409d9afccea91ba1cd22 (patch)
tree652a9c8229ce8b5137093e2ee82e2a83c6975b91 /src
parentc3f5a15f24f4421e0a096b2272273d9a85f70851 (diff)
parent2020b032e83d1b61736a80a6815635aa7451deed (diff)
Merge remote-tracking branch 'origin/5.4' into dev
Diffstat (limited to 'src')
-rw-r--r--src/gsttools/qgstutils.cpp25
-rw-r--r--src/multimedia/gsttools_headers/qgstutils_p.h2
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.cpp36
-rw-r--r--src/plugins/opensles/qopenslesaudioinput.cpp5
-rw-r--r--src/plugins/opensles/qopenslesaudioinput.h1
-rw-r--r--src/plugins/opensles/qopenslesaudiooutput.cpp34
-rw-r--r--src/plugins/opensles/qopenslesaudiooutput.h1
-rw-r--r--src/plugins/wmf/evrd3dpresentengine.cpp8
-rw-r--r--src/plugins/wmf/player/mfplayercontrol.cpp1
-rw-r--r--src/qtmultimediaquicktools/qsgvideonode_i420.cpp8
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()