Merge "Merge remote-tracking branch 'origin/5.4' into dev" into refs/staging/dev

This commit is contained in:
Frederik Gladhorn
2014-12-29 16:17:38 +01:00
committed by The Qt Project
12 changed files with 223 additions and 25 deletions

111
dist/changes-5.4.0 vendored Normal file
View File

@@ -0,0 +1,111 @@
Qt 5.4 introduces many new features and improvements as well as bugfixes
over the 5.3.x series. For more details, refer to the online documentation
included in this distribution. The documentation is also available online:
http://qt-project.org/doc/qt-5.4
The Qt version 5.4 series is binary compatible with the 5.3.x series.
Applications compiled for 5.3 will continue to run with 5.4.
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
http://bugreports.qt-project.org/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
****************************************************************************
* Important Behavior Changes *
****************************************************************************
- Using QAudioOutput and QSoundEffect with the PulseAudio backend won't
cause the system volume to be automatically changed to the maximum value
anymore. Audio streams will now respect the system-wide volume unless
explicitly set with setVolume().
- On Linux, both Alsa and PulseAudio backends are now present. PulseAudio
is used by default if available on the system and if the server is
running, otherwise Alsa is used instead.
****************************************************************************
* Library *
****************************************************************************
QtMultimedia
------------
- Added new QAbstractPlanarVideoBuffer class.
- Camera (QML):
* Added deviceId, displayName, position, orientation, metadata,
viewfinder.resolution, viewfinder.minimumFrameRate and
viewfinder.maximumFrameRate properties.
* Camera device can be selected by setting the deviceId or position
properties.
*
- QtMultimedia global QML object:
* Added defaultCamera and availableCameras properties.
- QAbstractVideoBuffer:
* Added mapPlanes() function.
- QVideoFrame:
* Added support for planar video formats. New planeCount(),
bytesPerLine(int plane) and bits(int plane) functions.
- [QTBUG-40515] Improved PLS parser. It is now more permissive, allowing
to load virtually any kind of PLS file. It also correctly resolve
relative paths.
****************************************************************************
* Platform Specific Changes *
****************************************************************************
Android
-------
- Changing a media player's position after reaching the end of a media
now correctly works.
- [QTBUG-40314] Fixed playing a QMediaPlaylit with a QMediaPlayer.
Linux
-----
- Added support for QCameraInfo::position() and QCameraInfo::orientation().
- Added support for QCameraFocus::customFocusPoint.
- QMediaRecorder::duration() now returns the correct value when recording
with a camera source.
- QMediaMetaData::ContributingArtist and QMediaMetaData::AlbumArtist
now map to the correct metadata.
- Fixed QMediaPlayer's metaDataAvailableChanged() signal, which was never
emitted.
OS X
----
- OS X 10.6 not being supported anymore, the QuickTime backend has been
removed.
QNX
---
- [QTBUG-40746] Fixed crash when detroying a QML VideoOutput or Video item.
Windows
-------
- [QTBUG-32481] Fixed various memory leaks when using a media player.
- [QTBUG-39980] Fixed crash occasionally happening when playing and
stopping repeatedly a media with QMediaPlayer.
- [QTBUG-40954] Buffers retrieved with QAudioProbe now have a correct
startTime().
- [QTBUG-41158] Fixed crash occasionally happening when destroying a
QML MediaPlayer.
WinRT
-----
- Enabled media player support for WinRT.
- Enabled basic camera support for WinRT (viewfinder, still image capture
and camera device selection).

View File

@@ -616,6 +616,8 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa
} else {
driver = QByteArray((const char*)vcap.driver);
name = QString::fromUtf8((const char*)vcap.card);
if (name.isEmpty())
name = entryInfo.fileName();
}
//qDebug() << "found camera: " << name;

View File

@@ -119,6 +119,7 @@ protected:
private Q_SLOTS:
void _q_updateMediaObject();
void _q_updateCameraInfo();
void _q_updateNativeSize();
void _q_updateGeometry();
void _q_screenOrientationChanged(int);

View File

@@ -35,7 +35,6 @@
#include <QGuiApplication>
#include <QScreen>
#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
@@ -63,9 +62,8 @@ int QVideoOutputOrientationHandler::currentOrientation() const
void QVideoOutputOrientationHandler::screenOrientationChanged(Qt::ScreenOrientation orientation)
{
const QScreen *screen = QGuiApplication::primaryScreen();
const QPlatformScreen *platformScreen = screen->handle();
const int angle = (360 - screen->angleBetween(platformScreen->nativeOrientation(), orientation)) % 360;
const int angle = (360 - screen->angleBetween(screen->nativeOrientation(), orientation)) % 360;
if (angle == m_currentOrientation)
return;

View File

@@ -96,7 +96,9 @@ QVideoSurfaceGenericPainter::QVideoSurfaceGenericPainter()
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_RGB565;
// The raster formats should be a subset of the GL formats.
#ifndef QT_NO_OPENGL
if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES)
#endif
m_imagePixelFormats << QVideoFrame::Format_RGB24;
}
@@ -137,7 +139,9 @@ QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::start(const QVideoSurf
const QAbstractVideoBuffer::HandleType t = format.handleType();
if (t == QAbstractVideoBuffer::NoHandle) {
bool ok = m_imageFormat != QImage::Format_Invalid && !m_imageSize.isEmpty();
#ifndef QT_NO_OPENGL
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES)
#endif
ok &= format.pixelFormat() != QVideoFrame::Format_RGB24;
if (ok)
return QAbstractVideoSurface::NoError;

View File

@@ -35,6 +35,7 @@
#include "qopenslesengine.h"
#include <qbuffer.h>
#include <private/qaudiohelpers_p.h>
#include <qdebug.h>
#ifdef ANDROID
@@ -70,6 +71,7 @@ QOpenSLESAudioInput::QOpenSLESAudioInput(const QByteArray &device)
, m_errorState(QAudio::NoError)
, m_deviceState(QAudio::StoppedState)
, m_lastNotifyTime(0)
, m_volume(1.0)
, m_bufferSize(0)
, m_periodSize(0)
, m_intervalTime(1000)
@@ -395,9 +397,19 @@ void QOpenSLESAudioInput::writeDataToDevice(const char *data, int size)
{
m_processedBytes += size;
QByteArray outData;
// Apply volume
if (m_volume < 1.0f) {
outData.resize(size);
QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, outData.data(), size);
} else {
outData.append(data, size);
}
if (m_pullMode) {
// write buffer to the QIODevice
if (m_audioSource->write(data, size) < 0) {
if (m_audioSource->write(outData) < 0) {
stop();
m_errorState = QAudio::IOError;
Q_EMIT errorChanged(m_errorState);
@@ -405,7 +417,7 @@ void QOpenSLESAudioInput::writeDataToDevice(const char *data, int size)
} else {
// emits readyRead() so user will call read() on QIODevice to get some audio data
if (m_bufferIODevice != 0) {
m_pushBuffer.append(data, size);
m_pushBuffer.append(outData);
Q_EMIT m_bufferIODevice->readyRead();
}
}
@@ -478,13 +490,12 @@ qint64 QOpenSLESAudioInput::elapsedUSecs() const
void QOpenSLESAudioInput::setVolume(qreal vol)
{
// Volume interface is not available for the recorder on Android
Q_UNUSED(vol);
m_volume = vol;
}
qreal QOpenSLESAudioInput::volume() const
{
return qreal(1.0);
return m_volume;
}
void QOpenSLESAudioInput::reset()

View File

@@ -113,6 +113,7 @@ private:
QAudio::State m_deviceState;
QTime m_clockStamp;
qint64 m_lastNotifyTime;
qreal m_volume;
int m_bufferSize;
int m_periodSize;
int m_intervalTime;

View File

@@ -44,6 +44,7 @@
#include <QtCore/qfunctions_winrt.h>
#include <QtCore/QGlobalStatic>
#include <QtCore/QMetaMethod>
#include <QtCore/QPointer>
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLTexture>
#include <QtMultimedia/QAbstractVideoBuffer>
@@ -181,7 +182,7 @@ enum DirtyState {
class QWinRTAbstractVideoRendererControlPrivate
{
public:
QAbstractVideoSurface *surface;
QPointer<QAbstractVideoSurface> surface;
QVideoSurfaceFormat format;
DirtyState dirtyState;
@@ -219,7 +220,6 @@ QWinRTAbstractVideoRendererControl::QWinRTAbstractVideoRendererControl(const QSi
{
Q_D(QWinRTAbstractVideoRendererControl);
d->surface = Q_NULLPTR;
d->format = QVideoSurfaceFormat(size, QVideoFrame::Format_BGRA32,
QAbstractVideoBuffer::GLTextureHandle);
d->dirtyState = TextureDirty;
@@ -310,6 +310,16 @@ void QWinRTAbstractVideoRendererControl::setSize(const QSize &size)
d->dirtyState = TextureDirty;
}
void QWinRTAbstractVideoRendererControl::setScanLineDirection(QVideoSurfaceFormat::Direction scanLineDirection)
{
Q_D(QWinRTAbstractVideoRendererControl);
if (d->format.scanLineDirection() == scanLineDirection)
return;
d->format.setScanLineDirection(scanLineDirection);
}
void QWinRTAbstractVideoRendererControl::setActive(bool active)
{
Q_D(QWinRTAbstractVideoRendererControl);
@@ -330,6 +340,8 @@ void QWinRTAbstractVideoRendererControl::setActive(bool active)
}
d->renderThread.requestInterruption();
if (d->surface && d->surface->isActive())
d->surface->stop();
}
void QWinRTAbstractVideoRendererControl::present()

View File

@@ -43,6 +43,7 @@
#define QWINRTABSTRACTVIDEORENDERERCONTROL_H
#include <QtMultimedia/QVideoRendererControl>
#include <QtMultimedia/QVideoSurfaceFormat>
struct ID3D11Device;
struct ID3D11Texture2D;
@@ -63,6 +64,8 @@ public:
QSize size() const;
void setSize(const QSize &size);
void setScanLineDirection(QVideoSurfaceFormat::Direction direction);
void setActive(bool active);
virtual bool render(ID3D11Texture2D *texture) = 0;

View File

@@ -677,6 +677,9 @@ HRESULT QWinRTCameraControl::initialize()
return E_FAIL;
}
if (d->videoDeviceSelector->cameraPosition(deviceName) == QCamera::FrontFace)
d->videoRenderer->setScanLineDirection(QVideoSurfaceFormat::BottomToTop);
ComPtr<IMediaCaptureInitializationSettings> settings;
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings).Get(),
&settings);
@@ -708,7 +711,20 @@ HRESULT QWinRTCameraControl::initialize()
hr = videoDeviceController.As(&deviceController);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IVectorView<IMediaEncodingProperties *>> encodingPropertiesList;
hr = deviceController->GetAvailableMediaStreamProperties(MediaStreamType_Photo, &encodingPropertiesList);
MediaStreamType mediaStreamType;
switch (d->captureMode) {
default:
case QCamera::CaptureViewfinder:
mediaStreamType = MediaStreamType_VideoPreview;
break;
case QCamera::CaptureStillImage:
mediaStreamType = MediaStreamType_Photo;
break;
case QCamera::CaptureVideo:
mediaStreamType = MediaStreamType_VideoRecord;
break;
}
hr = deviceController->GetAvailableMediaStreamProperties(mediaStreamType, &encodingPropertiesList);
Q_ASSERT_SUCCEEDED(hr);
d->size = QSize();
@@ -721,12 +737,12 @@ HRESULT QWinRTCameraControl::initialize()
hr = encodingPropertiesList->GetAt(i, &properties);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IVideoEncodingProperties> videoProperties;
hr = properties.As(&videoEncodingProperties);
hr = properties.As(&videoProperties);
Q_ASSERT_SUCCEEDED(hr);
UINT32 width, height;
hr = videoEncodingProperties->get_Width(&width);
hr = videoProperties->get_Width(&width);
Q_ASSERT_SUCCEEDED(hr);
hr = videoEncodingProperties->get_Height(&height);
hr = videoProperties->get_Height(&height);
Q_ASSERT_SUCCEEDED(hr);
// Choose the highest-quality format
if (int(width * height) > d->size.width() * d->size.height()) {

View File

@@ -337,7 +337,17 @@ QCamera::Position QWinRTVideoDeviceSelectorControl::cameraPosition(const QString
int QWinRTVideoDeviceSelectorControl::cameraOrientation(const QString &deviceName)
{
#ifdef Q_OS_WINPHONE
switch (cameraPosition(deviceName)) {
case QCamera::FrontFace:
case QCamera::BackFace:
return 270;
default:
break;
}
#else
Q_UNUSED(deviceName);
#endif
return 0;
}

View File

@@ -161,8 +161,10 @@ void QDeclarativeVideoOutput::setSource(QObject *source)
if (source == m_source.data())
return;
if (m_source && m_sourceType == MediaObjectSource)
if (m_source && m_sourceType == MediaObjectSource) {
disconnect(m_source.data(), 0, this, SLOT(_q_updateMediaObject()));
disconnect(m_source.data(), 0, this, SLOT(_q_updateCameraInfo()));
}
if (m_backend)
m_backend->releaseSource();
@@ -183,6 +185,20 @@ void QDeclarativeVideoOutput::setSource(QObject *source)
Qt::DirectConnection, 0);
}
int deviceIdPropertyIndex = metaObject->indexOfProperty("deviceId");
if (deviceIdPropertyIndex != -1) { // Camera source
const QMetaProperty deviceIdProperty = metaObject->property(deviceIdPropertyIndex);
if (deviceIdProperty.hasNotifySignal()) {
QMetaMethod method = deviceIdProperty.notifySignal();
QMetaObject::connect(m_source.data(), method.methodIndex(),
this, this->metaObject()->indexOfSlot("_q_updateCameraInfo()"),
Qt::DirectConnection, 0);
}
}
m_sourceType = MediaObjectSource;
} else if (metaObject->indexOfProperty("videoSurface") != -1) {
// Make sure our backend is a QDeclarativeVideoRendererBackend
@@ -269,25 +285,38 @@ void QDeclarativeVideoOutput::_q_updateMediaObject()
m_mediaObject.clear();
m_service.clear();
m_cameraInfo = QCameraInfo();
if (mediaObject) {
if (QMediaService *service = mediaObject->service()) {
if (createBackend(service)) {
m_service = service;
m_mediaObject = mediaObject;
const QCamera *camera = qobject_cast<const QCamera *>(mediaObject);
if (camera) {
m_cameraInfo = QCameraInfo(*camera);
// The camera position and orientation need to be taken into account for
// the viewport auto orientation
if (m_autoOrientation)
_q_screenOrientationChanged(m_screenOrientationHandler->currentOrientation());
}
}
}
}
_q_updateCameraInfo();
}
void QDeclarativeVideoOutput::_q_updateCameraInfo()
{
if (m_mediaObject) {
const QCamera *camera = qobject_cast<const QCamera *>(m_mediaObject);
if (camera) {
QCameraInfo info(*camera);
if (m_cameraInfo != info) {
m_cameraInfo = info;
// The camera position and orientation need to be taken into account for
// the viewport auto orientation
if (m_autoOrientation)
_q_screenOrientationChanged(m_screenOrientationHandler->currentOrientation());
}
}
} else {
m_cameraInfo = QCameraInfo();
}
}
/*!