Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I9c1abddf20e85cc0f29f2da26c398b7180e4f479
This commit is contained in:
86
dist/changes-5.2.0
vendored
Normal file
86
dist/changes-5.2.0
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
Qt 5.2 introduces many new features and improvements as well as bugfixes
|
||||
over the 5.1.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.2
|
||||
|
||||
The Qt version 5.2 series is binary compatible with the 5.1.x series.
|
||||
Applications compiled for 5.1 will continue to run with 5.2.
|
||||
|
||||
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.
|
||||
|
||||
****************************************************************************
|
||||
* General *
|
||||
****************************************************************************
|
||||
|
||||
- Improved ALSA implementation of the audio APIs.
|
||||
- Improved WAV support in QSoundEffect.
|
||||
- New resource policy plugin based on libresourceqt.
|
||||
- Fix QVideoSurfaceArbFpPainter mistakenly failing to start in some cases.
|
||||
- Improved QAudioRecorder implementation on Windows and Mac OS.
|
||||
- Various documentation fixes.
|
||||
- Improved audiorecorder example.
|
||||
- [QTBUG-32487] Make PulseAudio implementation of QSoundEffect more robust.
|
||||
- [QTBUG-32882] Enable QSoundEffect with loopCount of Infinite to play.
|
||||
- [QTBUG-31731] WMF and GStreamer: fixed incorrect frame startTime and endTime.
|
||||
- [QTBUG-30442] VideoOutput: take the video format's scanLineDirection into account.
|
||||
- [QTBUG-34125] Correctly clear the current media in Audio and MediaPlayer qml elements.
|
||||
|
||||
Qt for Android
|
||||
--------------
|
||||
|
||||
- New OpenSL ES plugin for low-latency audio support on Android.
|
||||
- New camera support on Android.
|
||||
- Improved video renderering with Qt Quick.
|
||||
- Camera and recording permissions are now automatically added when using QtMultimedia on Android.
|
||||
- [QTBUG-32635] Fixed media player buffering logic.
|
||||
- [QTBUG-34558] Fix two race conditions in the media player.
|
||||
|
||||
Qt for iOS
|
||||
----------
|
||||
|
||||
- New media player and basic camera support on iOS.
|
||||
|
||||
Qt for BlackBerry
|
||||
-----------------
|
||||
|
||||
- Fix setting a URL containing reserved characters on a media player.
|
||||
- Enable camera on the Playbook.
|
||||
- New QAudioRecorder support.
|
||||
- Fix video recording with BB 10.2.
|
||||
- Improve camera focus handling.
|
||||
- Fixed pixel aspect ratio for video windows.
|
||||
- [QTBUG-33739] Fix camera viewfinder.
|
||||
|
||||
Qt for Windows
|
||||
--------------
|
||||
|
||||
- WMF: emit positionChanged() signal when reaching the end of a media.
|
||||
- [QTBUG-30776] DirectShow: improve metadata support.
|
||||
- [QTBUG-33631][QTBUG-33518] WMF: allow to load media whose content doesn't match its file extension.
|
||||
- [QTBUG-33518] WMF: allow to load QRC files with QAudioDecoder.
|
||||
- [QTBUG-30435] WMF: fixed the media player failing to play some media formats.
|
||||
- [QTBUG-32360] WMF: fixed compilation with Visual Studio 2008.
|
||||
- [QTBUG-34479] DirectShow: fixed compilation with Visual Studio 2008.
|
||||
- [QTBUG-32864] WMF: fixed compilation on Windows Vista.
|
||||
- [QTBUG-30825] WMF: fixed QMediaPlayer changing to EndOfMedia status too early.
|
||||
- [QTBUG-33160] Fix QAudioOutput::setVolume() limited to 50% on 32-bit Windows.
|
||||
|
||||
Qt for QNX
|
||||
----------
|
||||
|
||||
- New camera and media player support when mmrenderer is available.
|
||||
|
||||
****************************************************************************
|
||||
* Plugins *
|
||||
****************************************************************************
|
||||
|
||||
- New QML import version QtMultimedia 5.2 adds a new autoOrientation
|
||||
property to the VideoOutput type, which allows the video output to
|
||||
always match the screen orientation.
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
qmlRegisterType<QDeclarativeAudio>(uri, 5, 0, "Audio");
|
||||
qmlRegisterType<QDeclarativeAudio>(uri, 5, 0, "MediaPlayer");
|
||||
qmlRegisterType<QDeclarativeVideoOutput>(uri, 5, 0, "VideoOutput");
|
||||
qmlRegisterType<QDeclarativeVideoOutput, 1>(uri, 5, 1, "VideoOutput");
|
||||
qmlRegisterType<QDeclarativeVideoOutput, 2>(uri, 5, 2, "VideoOutput");
|
||||
qmlRegisterType<QDeclarativeRadio>(uri, 5, 0, "Radio");
|
||||
qmlRegisterType<QDeclarativeRadioData>(uri, 5, 0, "RadioData");
|
||||
qmlRegisterType<QDeclarativeCamera>(uri, 5, 0, "Camera");
|
||||
|
||||
@@ -429,7 +429,7 @@ void QDeclarativeVideoOutput::setOrientation(int orientation)
|
||||
|
||||
By default \c autoOrientation is disabled.
|
||||
|
||||
\since QtMultimedia 5.1
|
||||
\since QtMultimedia 5.2
|
||||
*/
|
||||
bool QDeclarativeVideoOutput::autoOrientation() const
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@ class QDeclarativeVideoOutput : public QQuickItem
|
||||
Q_PROPERTY(QObject* source READ source WRITE setSource NOTIFY sourceChanged)
|
||||
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
|
||||
Q_PROPERTY(int orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
|
||||
Q_PROPERTY(bool autoOrientation READ autoOrientation WRITE setAutoOrientation NOTIFY autoOrientationChanged REVISION 1)
|
||||
Q_PROPERTY(bool autoOrientation READ autoOrientation WRITE setAutoOrientation NOTIFY autoOrientationChanged REVISION 2)
|
||||
Q_PROPERTY(QRectF sourceRect READ sourceRect NOTIFY sourceRectChanged)
|
||||
Q_PROPERTY(QRectF contentRect READ contentRect NOTIFY contentRectChanged)
|
||||
Q_ENUMS(FillMode)
|
||||
|
||||
@@ -54,7 +54,7 @@ static QMap<int, JCamera*> g_objectMap;
|
||||
static QRect areaToRect(jobject areaObj)
|
||||
{
|
||||
QJNIObjectPrivate area(areaObj);
|
||||
QJNIObjectPrivate rect = area.getObjectField("rect", "android/graphics/Rect");
|
||||
QJNIObjectPrivate rect = area.getObjectField("rect", "Landroid/graphics/Rect;");
|
||||
|
||||
return QRect(rect.getField<jint>("left"),
|
||||
rect.getField<jint>("top"),
|
||||
|
||||
@@ -62,6 +62,8 @@ JSurfaceTexture::JSurfaceTexture(unsigned int texName)
|
||||
{
|
||||
if (isValid())
|
||||
g_objectMap.insert(int(texName), this);
|
||||
else // If the class is not available, it means the Android version is < 3.0
|
||||
qWarning("Camera preview and video playback require Android 3.0 (API level 11) or later.");
|
||||
}
|
||||
|
||||
JSurfaceTexture::~JSurfaceTexture()
|
||||
@@ -94,6 +96,13 @@ static JNINativeMethod methods[] = {
|
||||
|
||||
bool JSurfaceTexture::initJNI(JNIEnv *env)
|
||||
{
|
||||
// SurfaceTexture is available since API 11, try to find it first before loading
|
||||
// our custom class
|
||||
jclass surfaceTextureClass = env->FindClass("android/graphics/SurfaceTexture");
|
||||
if (env->ExceptionCheck())
|
||||
env->ExceptionClear();
|
||||
|
||||
if (surfaceTextureClass) {
|
||||
jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTexture");
|
||||
if (env->ExceptionCheck())
|
||||
env->ExceptionClear();
|
||||
@@ -106,6 +115,7 @@ bool JSurfaceTexture::initJNI(JNIEnv *env)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -188,11 +188,11 @@ QList<int> CoreAudioDeviceInfo::supportedSampleRates()
|
||||
|
||||
QList<int> CoreAudioDeviceInfo::supportedChannelCounts()
|
||||
{
|
||||
QSet<int> supportedChannels;
|
||||
QList<int> supportedChannels;
|
||||
int maxChannels = 0;
|
||||
|
||||
#if defined(Q_OS_OSX)
|
||||
UInt32 propSize = 0;
|
||||
int channels = 0;
|
||||
AudioObjectPropertyScope scope = m_mode == QAudio::AudioInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
|
||||
AudioObjectPropertyAddress streamConfigurationPropertyAddress = { kAudioDevicePropertyStreamConfiguration,
|
||||
scope,
|
||||
@@ -203,24 +203,25 @@ QList<int> CoreAudioDeviceInfo::supportedChannelCounts()
|
||||
|
||||
if (audioBufferList != 0) {
|
||||
if (AudioObjectGetPropertyData(m_deviceId, &streamConfigurationPropertyAddress, 0, NULL, &propSize, audioBufferList) == noErr) {
|
||||
for (int i = 0; i < int(audioBufferList->mNumberBuffers); ++i) {
|
||||
channels += audioBufferList->mBuffers[i].mNumberChannels;
|
||||
supportedChannels << channels;
|
||||
}
|
||||
for (int i = 0; i < int(audioBufferList->mNumberBuffers); ++i)
|
||||
maxChannels += audioBufferList->mBuffers[i].mNumberChannels;
|
||||
}
|
||||
|
||||
free(audioBufferList);
|
||||
}
|
||||
}
|
||||
#else //iOS
|
||||
if (m_mode == QAudio::AudioInput) {
|
||||
supportedChannels << CoreAudioSessionManager::instance().inputChannelCount();
|
||||
} else if (m_mode == QAudio::AudioOutput) {
|
||||
supportedChannels << CoreAudioSessionManager::instance().outputChannelCount();
|
||||
}
|
||||
if (m_mode == QAudio::AudioInput)
|
||||
maxChannels = CoreAudioSessionManager::instance().inputChannelCount();
|
||||
else if (m_mode == QAudio::AudioOutput)
|
||||
maxChannels = CoreAudioSessionManager::instance().outputChannelCount();
|
||||
#endif
|
||||
|
||||
return supportedChannels.toList();
|
||||
// Assume all channel configurations are supported up to the maximum number of channels
|
||||
for (int i = 1; i <= maxChannels; ++i)
|
||||
supportedChannels.append(i);
|
||||
|
||||
return supportedChannels;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
#define BUFFER_COUNT 2
|
||||
#define DEFAULT_PERIOD_TIME_MS 50
|
||||
#define MINIMUM_PERIOD_TIME_MS 5
|
||||
#define EBASE 2.302585093
|
||||
#define LOG10(x) qLn(x)/qreal(EBASE)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@@ -622,7 +624,7 @@ inline SLmillibel QOpenSLESAudioOutput::adjustVolume(qreal vol)
|
||||
if (qFuzzyCompare(vol, qreal(1.0)))
|
||||
return 0;
|
||||
|
||||
return SL_MILLIBEL_MIN + ((1 - (qLn(10 - (vol * 10)) / qLn(10))) * SL_MILLIBEL_MAX);
|
||||
return 20 * LOG10(vol) * 100; // I.e., 20 * LOG10(SL_MILLIBEL_MAX * vol / SL_MILLIBEL_MAX)
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@@ -57,7 +57,7 @@ PpsMediaPlayerControl::PpsMediaPlayerControl(QObject *parent)
|
||||
m_ppsStatusFd(-1),
|
||||
m_ppsStateNotifier(0),
|
||||
m_ppsStateFd(-1)
|
||||
, m_previouslySeenState("STOPPED")
|
||||
, m_previouslySeenState("stopped")
|
||||
{
|
||||
openConnection();
|
||||
}
|
||||
@@ -177,7 +177,7 @@ void PpsMediaPlayerControl::ppsReadyRead(int fd)
|
||||
|
||||
if (pps_decoder_get_string(&decoder, "state", &value) == PPS_DECODER_OK) {
|
||||
const QByteArray state = value;
|
||||
if (state != m_previouslySeenState && state == "STOPPED")
|
||||
if (state != m_previouslySeenState && state == "stopped")
|
||||
handleMmStopped();
|
||||
m_previouslySeenState = state;
|
||||
}
|
||||
|
||||
@@ -1323,12 +1323,8 @@ void MFPlayerSession::stop(bool immediate)
|
||||
|
||||
void MFPlayerSession::start()
|
||||
{
|
||||
switch (m_status) {
|
||||
case QMediaPlayer::EndOfMedia:
|
||||
m_varStart.hVal.QuadPart = 0;
|
||||
changeStatus(QMediaPlayer::BufferedMedia);
|
||||
return;
|
||||
}
|
||||
if (m_status == QMediaPlayer::EndOfMedia)
|
||||
m_varStart.hVal.QuadPart = 0; // restart from the beginning
|
||||
|
||||
#ifdef DEBUG_MEDIAFOUNDATION
|
||||
qDebug() << "start";
|
||||
@@ -1462,6 +1458,9 @@ void MFPlayerSession::setPositionInternal(qint64 position, Command requestCmd)
|
||||
if (m_state.command == CmdStop && requestCmd != CmdSeekResume) {
|
||||
m_varStart.vt = VT_I8;
|
||||
m_varStart.hVal.QuadPart = LONGLONG(position * 10000);
|
||||
// Even though the position is not actually set on the session yet,
|
||||
// report it to have changed anyway for UI controls to be updated
|
||||
emit positionChanged(this->position());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1561,6 +1560,8 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
|
||||
m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
|
||||
Q_ASSERT(hnsSystemTime != 0);
|
||||
|
||||
m_request.setCommand(rate < 0 || m_state.rate < 0 ? CmdSeekResume : CmdStart);
|
||||
|
||||
// We need to stop only when dealing with negative rates
|
||||
if (rate >= 0 && m_state.rate >= 0)
|
||||
pause();
|
||||
@@ -1569,7 +1570,6 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
|
||||
|
||||
// If we deal with negative rates, we stopped the session and consequently
|
||||
// reset the position to zero. We then need to resume to the current position.
|
||||
m_request.setCommand(rate < 0 || m_state.rate < 0 ? CmdSeekResume : CmdStart);
|
||||
m_request.start = hnsClockTime / 10000;
|
||||
} else if (cmdNow == CmdPause) {
|
||||
if (rate < 0 || m_state.rate < 0) {
|
||||
@@ -1604,10 +1604,11 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
|
||||
// Changing rate from negative to zero requires to stop the session
|
||||
m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
|
||||
|
||||
m_request.setCommand(CmdSeekResume);
|
||||
|
||||
stop();
|
||||
|
||||
// Resumte to the current position (stop() will reset the position to 0)
|
||||
m_request.setCommand(CmdSeekResume);
|
||||
// Resume to the current position (stop() will reset the position to 0)
|
||||
m_request.start = hnsClockTime / 10000;
|
||||
}
|
||||
|
||||
@@ -1835,6 +1836,12 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
|
||||
updatePendingCommands(CmdStart);
|
||||
break;
|
||||
case MESessionStarted:
|
||||
if (m_status == QMediaPlayer::EndOfMedia
|
||||
|| m_status == QMediaPlayer::LoadedMedia) {
|
||||
// If the session started, then enough data is buffered to play
|
||||
changeStatus(QMediaPlayer::BufferedMedia);
|
||||
}
|
||||
|
||||
updatePendingCommands(CmdStart);
|
||||
#ifndef Q_WS_SIMULATOR
|
||||
// playback started, we can now set again the procAmpValues if they have been
|
||||
@@ -1850,8 +1857,8 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
|
||||
m_varStart.hVal.QuadPart = 0;
|
||||
|
||||
// Reset to Loaded status unless we are loading a new media
|
||||
// or if the media is buffered (to avoid restarting the video surface)
|
||||
if (m_status != QMediaPlayer::LoadingMedia && m_status != QMediaPlayer::BufferedMedia)
|
||||
// or changing the playback rate to negative values (stop required)
|
||||
if (m_status != QMediaPlayer::LoadingMedia && m_request.command != CmdSeekResume)
|
||||
changeStatus(QMediaPlayer::LoadedMedia);
|
||||
}
|
||||
updatePendingCommands(CmdStop);
|
||||
@@ -1920,12 +1927,10 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
|
||||
|
||||
switch (meType) {
|
||||
case MEBufferingStarted:
|
||||
changeStatus(m_status == QMediaPlayer::LoadedMedia ? QMediaPlayer::BufferingMedia : QMediaPlayer::StalledMedia);
|
||||
changeStatus(QMediaPlayer::StalledMedia);
|
||||
emit bufferStatusChanged(bufferStatus());
|
||||
break;
|
||||
case MEBufferingStopped:
|
||||
if (m_status == QMediaPlayer::BufferingMedia)
|
||||
stop(true);
|
||||
changeStatus(QMediaPlayer::BufferedMedia);
|
||||
emit bufferStatusChanged(bufferStatus());
|
||||
break;
|
||||
@@ -1990,16 +1995,6 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
|
||||
}
|
||||
}
|
||||
MFGetService(m_session, MFNETSOURCE_STATISTICS_SERVICE, IID_PPV_ARGS(&m_netsourceStatistics));
|
||||
|
||||
if (!m_netsourceStatistics || bufferStatus() == 100) {
|
||||
// If the source reader doesn't implement the statistics service, just set the status
|
||||
// to buffered, since there is no way to query the buffering progress...
|
||||
changeStatus(QMediaPlayer::BufferedMedia);
|
||||
} else {
|
||||
// Start to trigger buffering. Once enough buffering is done, the session will
|
||||
// be automatically stopped unless the user has explicitly started playback.
|
||||
start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user