Merge remote-tracking branch 'origin/stable' into dev

Change-Id: I9c1abddf20e85cc0f29f2da26c398b7180e4f479
This commit is contained in:
Frederik Gladhorn
2013-12-05 18:45:33 +01:00
10 changed files with 144 additions and 50 deletions

86
dist/changes-5.2.0 vendored Normal file
View 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.

View File

@@ -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");

View File

@@ -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
{

View File

@@ -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)

View File

@@ -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"),

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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();
}
}
}
}