summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-08-27 22:44:53 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-08-27 22:44:53 +0200
commitcb1871d06113dbbb8b8ac6fd5541baf09fc33004 (patch)
treead53596a3fd3eb54a9a12cfb45fb367bcd2ae810
parent48a6a8a04394c63c77259fa0c2ced34dfa0ce9fe (diff)
parenta2f078f1088827ec2bc066aaee7ca3199c6cb4eb (diff)
Merge remote-tracking branch 'origin/stable' into dev
-rw-r--r--dist/changes-5.1.145
-rw-r--r--examples/multimedia/video/qmlvideofx/main.cpp14
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml9
-rw-r--r--src/gsttools/qvideosurfacegstsink.cpp5
-rw-r--r--src/multimedia/audio/qsoundeffect_qaudio_p.cpp2
-rw-r--r--src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java2
-rw-r--r--src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp13
-rw-r--r--src/plugins/android/wrappers/jsurfacetexture.cpp4
-rw-r--r--src/plugins/wmf/evrcustompresenter.cpp5
-rw-r--r--src/plugins/wmf/evrd3dpresentengine.cpp18
-rw-r--r--src/plugins/wmf/mftvideo.cpp5
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp14
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.cpp24
13 files changed, 115 insertions, 45 deletions
diff --git a/dist/changes-5.1.1 b/dist/changes-5.1.1
new file mode 100644
index 000000000..45fc4ded5
--- /dev/null
+++ b/dist/changes-5.1.1
@@ -0,0 +1,45 @@
+Qt 5.1.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.1.0.
+
+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.1/
+
+The Qt version 5.1 series is binary compatible with the 5.0.x series.
+Applications compiled for 5.0 will continue to run with 5.1.
+
+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.
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+Qt for Windows
+--------------
+
+ - Use correct default audio output and input devices on Windows.
+ - [QTBUG-29206] DirectShow: avoid unnecessary RGB32 -> BGR32 conversion.
+ - [QTBUG-32282] DirectShow: Don't create the widget and renderer controls
+ until requested.
+ - [QTBUG-23822] Fix resource leak in directshow plugin.
+ - WMF: fixed MediaPlayer buffering logic.
+
+Qt for Android
+--------------
+
+ - Fixed potential memory leak when destroying a media player.
+ - Fixed media player showing black frames on some hardware.
+ - [QTBUG-31422] Make it possible for the media player to play assets.
+ - Fixed Java exception being thrown at app startup when using multimedia.
+
+Qt for BlackBerry
+-----------------
+
+ - [QTBUG-31534] Fix frame size of video playback.
diff --git a/examples/multimedia/video/qmlvideofx/main.cpp b/examples/multimedia/video/qmlvideofx/main.cpp
index b0698e236..7465deab8 100644
--- a/examples/multimedia/video/qmlvideofx/main.cpp
+++ b/examples/multimedia/video/qmlvideofx/main.cpp
@@ -116,21 +116,13 @@ int main(int argc, char *argv[])
FileReader fileReader;
viewer.rootContext()->setContextProperty("fileReader", &fileReader);
- QUrl appPath(QString("file://%1").arg(app.applicationDirPath()));
- QUrl imagePath;
+ const QUrl appPath(QUrl::fromLocalFile(app.applicationDirPath()));
const QStringList picturesLocation = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
- if (picturesLocation.isEmpty())
- imagePath = appPath.resolved(QUrl("images"));
- else
- imagePath = QString("file://%1").arg(picturesLocation.first());
+ const QUrl imagePath = picturesLocation.isEmpty() ? appPath : QUrl::fromLocalFile(picturesLocation.first());
viewer.rootContext()->setContextProperty("imagePath", imagePath);
- QUrl videoPath;
const QStringList moviesLocation = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation);
- if (moviesLocation.isEmpty())
- videoPath = appPath.resolved(QUrl("./"));
- else
- videoPath = QString("file://%1").arg(moviesLocation.first());
+ const QUrl videoPath = moviesLocation.isEmpty() ? appPath : QUrl::fromLocalFile(moviesLocation.first());
viewer.rootContext()->setContextProperty("videoPath", videoPath);
viewer.setTitle("qmlvideofx");
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml
index 3d4343c25..7c8610361 100644
--- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml
@@ -102,7 +102,10 @@ Rectangle {
Rectangle {
id: wrapper
function launch() {
- var path = "file://" + filePath
+ var path = "file://";
+ if (filePath.length > 2 && filePath[1] === ':') // Windows drive logic, see QUrl::fromLocalFile()
+ path += '/';
+ path += filePath;
if (folders.isFolder(index))
down(path);
else
@@ -307,7 +310,7 @@ Rectangle {
MouseArea { id: upRegion; anchors.centerIn: parent
width: 56
height: 56
- onClicked: if (folders.parentFolder != "") up()
+ onClicked: up()
}
states: [
State {
@@ -353,6 +356,8 @@ Rectangle {
function up() {
var path = folders.parentFolder;
+ if (path.toString().length === 0 || path.toString() === 'file:')
+ return;
if (folders == folders1) {
view = view2
folders = folders2;
diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
index 94aa1262e..f91c1192d 100644
--- a/src/gsttools/qvideosurfacegstsink.cpp
+++ b/src/gsttools/qvideosurfacegstsink.cpp
@@ -713,13 +713,14 @@ QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *byte
void QVideoSurfaceGstSink::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer)
{
+ // GStreamer uses nanoseconds, Qt uses microseconds
qint64 startTime = GST_BUFFER_TIMESTAMP(buffer);
if (startTime >= 0) {
- frame->setStartTime(startTime/G_GINT64_CONSTANT (1000000));
+ frame->setStartTime(startTime/G_GINT64_CONSTANT (1000));
qint64 duration = GST_BUFFER_DURATION(buffer);
if (duration >= 0)
- frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000000));
+ frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000));
}
}
diff --git a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
index 835f60b45..524c856a2 100644
--- a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
+++ b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
@@ -369,7 +369,7 @@ void PrivateSoundSource::stateChanged(QAudio::State state)
qint64 PrivateSoundSource::readData( char* data, qint64 len)
{
- if (m_runningCount > 0 && m_playing) {
+ if ((m_runningCount > 0 || m_runningCount == QSoundEffect::Infinite) && m_playing) {
if (m_sample->state() != QSample::Ready)
return 0;
diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
index d1abf658e..2ca07a63e 100644
--- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
+++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
@@ -191,8 +191,8 @@ public class QtAndroidMediaPlayer extends MediaPlayer
@Override
public void onPrepared(final MediaPlayer mp)
{
- onMediaPlayerInfoNative(MEDIA_PLAYER_DURATION, getDuration(), mID);
onMediaPlayerInfoNative(MEDIA_PLAYER_READY, 0, mID);
+ onMediaPlayerInfoNative(MEDIA_PLAYER_DURATION, getDuration(), mID);
mPreparing = false;
}
diff --git a/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp
index a70f4e130..4dc56ebd9 100644
--- a/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp
+++ b/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp
@@ -98,8 +98,9 @@ QMediaPlayer::MediaStatus QAndroidMediaPlayerControl::mediaStatus() const
qint64 QAndroidMediaPlayerControl::duration() const
{
return (mCurrentMediaStatus == QMediaPlayer::InvalidMedia
- || mCurrentMediaStatus == QMediaPlayer::NoMedia) ? 0
- : mMediaPlayer->getDuration();
+ || mCurrentMediaStatus == QMediaPlayer::NoMedia
+ || !mMediaPlayerReady) ? 0
+ : mMediaPlayer->getDuration();
}
qint64 QAndroidMediaPlayerControl::position() const
@@ -330,14 +331,12 @@ void QAndroidMediaPlayerControl::onMediaPlayerInfo(qint32 what, qint32 extra)
setState(QMediaPlayer::StoppedState);
break;
case JMediaPlayer::MEDIA_PLAYER_READY:
+ setMediaStatus(QMediaPlayer::LoadedMedia);
if (mBuffering) {
setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia
: QMediaPlayer::BufferingMedia);
} else {
- setMediaStatus(QMediaPlayer::LoadedMedia);
- mBufferPercent = 100;
- Q_EMIT bufferStatusChanged(mBufferPercent);
- updateAvailablePlaybackRanges();
+ onBufferChanged(100);
}
setAudioAvailable(true);
mMediaPlayerReady = true;
@@ -402,7 +401,7 @@ void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onBufferChanged(qint32 percent)
{
- mBuffering = true;
+ mBuffering = percent != 100;
mBufferPercent = percent;
Q_EMIT bufferStatusChanged(mBufferPercent);
diff --git a/src/plugins/android/wrappers/jsurfacetexture.cpp b/src/plugins/android/wrappers/jsurfacetexture.cpp
index 107f7be39..34edf1b66 100644
--- a/src/plugins/android/wrappers/jsurfacetexture.cpp
+++ b/src/plugins/android/wrappers/jsurfacetexture.cpp
@@ -60,13 +60,13 @@ JSurfaceTexture::JSurfaceTexture(unsigned int texName)
, QJNIObject(g_qtSurfaceTextureClass, "(I)V", jint(texName))
, m_texID(int(texName))
{
- if (m_jobject)
+ if (isValid())
g_objectMap.insert(int(texName), this);
}
JSurfaceTexture::~JSurfaceTexture()
{
- if (m_jobject)
+ if (isValid())
g_objectMap.remove(m_texID);
}
diff --git a/src/plugins/wmf/evrcustompresenter.cpp b/src/plugins/wmf/evrcustompresenter.cpp
index eb73e6720..70acbddba 100644
--- a/src/plugins/wmf/evrcustompresenter.cpp
+++ b/src/plugins/wmf/evrcustompresenter.cpp
@@ -50,6 +50,7 @@
#include <qabstractvideosurface.h>
#include <qthread.h>
#include <qcoreapplication.h>
+#include <qmath.h>
#include <QtCore/qdebug.h>
#include <d3d9.h>
#include <dshow.h>
@@ -325,7 +326,7 @@ HRESULT Scheduler::processSample(IMFSample *sample, LONG *pNextSleep)
// Adjust the sleep time for the clock rate. (The presentation clock runs
// at m_fRate, but sleeping uses the system clock.)
if (m_playbackRate != 0)
- nextSleep = (LONG)(nextSleep / fabsf(m_playbackRate));
+ nextSleep = (LONG)(nextSleep / qFabs(m_playbackRate));
// Don't present yet.
presentNow = false;
@@ -987,7 +988,7 @@ HRESULT EVRCustomPresenter::IsRateSupported(BOOL thin, float rate, float *neares
// Note: We have no minimum rate (that is, we support anything down to 0).
maxRate = getMaxRate(thin);
- if (fabsf(rate) > maxRate) {
+ if (qFabs(rate) > maxRate) {
// The (absolute) requested rate exceeds the maximum rate.
hr = MF_E_UNSUPPORTED_RATE;
diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/wmf/evrd3dpresentengine.cpp
index c67b5d448..01a5c3341 100644
--- a/src/plugins/wmf/evrd3dpresentengine.cpp
+++ b/src/plugins/wmf/evrd3dpresentengine.cpp
@@ -288,9 +288,21 @@ void D3DPresentEngine::presentSample(void *opaque, qint64)
}
if (surface && updateTexture(surface)) {
- m_surface->present(QVideoFrame(new TextureVideoBuffer(m_glTexture),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat()));
+ QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture),
+ m_surfaceFormat.frameSize(),
+ m_surfaceFormat.pixelFormat());
+
+ // WMF uses 100-nanosecond units, Qt uses microseconds
+ LONGLONG startTime = -1;
+ if (SUCCEEDED(sample->GetSampleTime(&startTime))) {
+ frame.setStartTime(startTime * 0.1);
+
+ LONGLONG duration = -1;
+ if (SUCCEEDED(sample->GetSampleDuration(&duration)))
+ frame.setEndTime((startTime + duration) * 0.1);
+ }
+
+ m_surface->present(frame);
}
done:
diff --git a/src/plugins/wmf/mftvideo.cpp b/src/plugins/wmf/mftvideo.cpp
index acec88d6b..8e7ce0693 100644
--- a/src/plugins/wmf/mftvideo.cpp
+++ b/src/plugins/wmf/mftvideo.cpp
@@ -632,13 +632,14 @@ QVideoFrame MFTransform::makeVideoFrame()
// That is why we copy data from IMFMediaBuffer here.
frame = QVideoFrame(new QMemoryVideoBuffer(array, m_bytesPerLine), m_format.frameSize(), m_format.pixelFormat());
+ // WMF uses 100-nanosecond units, Qt uses microseconds
LONGLONG startTime = -1;
if (SUCCEEDED(m_sample->GetSampleTime(&startTime))) {
- frame.setStartTime(startTime);
+ frame.setStartTime(startTime * 0.1);
LONGLONG duration = -1;
if (SUCCEEDED(m_sample->GetSampleDuration(&duration)))
- frame.setEndTime(startTime + duration);
+ frame.setEndTime((startTime + duration) * 0.1);
}
} while (false);
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index fb150c3e9..4e4b56589 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -1918,19 +1918,17 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
changeStatus(QMediaPlayer::BufferedMedia);
emit bufferStatusChanged(bufferStatus());
break;
- case MEEndOfPresentation:
- stop();
- changeStatus(QMediaPlayer::EndOfMedia);
- m_varStart.vt = VT_I8;
- //keep reporting the final position after end of media
- m_varStart.hVal.QuadPart = m_duration;
- break;
case MESessionEnded:
m_pendingState = NoPending;
m_state.command = CmdStop;
m_state.prevCmd = CmdNone;
m_request.command = CmdNone;
m_request.prevCmd = CmdNone;
+
+ changeStatus(QMediaPlayer::EndOfMedia);
+ m_varStart.vt = VT_I8;
+ //keep reporting the final position after end of media
+ m_varStart.hVal.QuadPart = m_duration;
break;
case MEEndOfPresentationSegment:
break;
@@ -1993,6 +1991,8 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
}
}
break;
+ default:
+ break;
}
sessionEvent->Release();
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
index 8f73244c0..83768c8e2 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
@@ -254,6 +254,8 @@ namespace
, m_workQueueCB(this, &MediaStream::onDispatchWorkItem)
, m_finalizeResult(0)
, m_scheduledBuffer(0)
+ , m_bufferStartTime(-1)
+ , m_bufferDuration(-1)
, m_presentationClock(0)
, m_currentMediaType(0)
, m_prerolling(false)
@@ -839,10 +841,13 @@ namespace
QMutexLocker locker(&m_mutex);
if (!m_scheduledBuffer)
return;
- m_surface->present(QVideoFrame(
- new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat()));
+ QVideoFrame frame = QVideoFrame(
+ new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine),
+ m_surfaceFormat.frameSize(),
+ m_surfaceFormat.pixelFormat());
+ frame.setStartTime(m_bufferStartTime * 0.1);
+ frame.setEndTime((m_bufferStartTime + m_bufferDuration) * 0.1);
+ m_surface->present(frame);
m_scheduledBuffer->Release();
m_scheduledBuffer = NULL;
if (m_rate != 0)
@@ -1309,8 +1314,10 @@ namespace
HRESULT processSampleData(IMFSample *pSample)
{
- LONGLONG time;
+ LONGLONG time, duration = -1;
HRESULT hr = pSample->GetSampleTime(&time);
+ if (SUCCEEDED(hr))
+ pSample->GetSampleDuration(&duration);
if (m_prerolling) {
if (SUCCEEDED(hr) && time >= m_prerollTargetTime) {
@@ -1320,6 +1327,7 @@ namespace
SampleBuffer sb;
sb.m_buffer = pBuffer;
sb.m_time = time;
+ sb.m_duration = duration;
m_bufferCache.push_back(sb);
endPreroll(S_OK);
}
@@ -1336,6 +1344,7 @@ namespace
SampleBuffer sb;
sb.m_buffer = pBuffer;
sb.m_time = time;
+ sb.m_duration = duration;
m_bufferCache.push_back(sb);
}
if (m_rate == 0)
@@ -1351,6 +1360,7 @@ namespace
public:
IMFMediaBuffer *m_buffer;
LONGLONG m_time;
+ LONGLONG m_duration;
};
QList<SampleBuffer> m_bufferCache;
static const int BUFFER_CACHE_SIZE = 2;
@@ -1383,6 +1393,8 @@ namespace
continue;
}
m_scheduledBuffer = sb.m_buffer;
+ m_bufferStartTime = sb.m_time;
+ m_bufferDuration = sb.m_duration;
QCoreApplication::postEvent(m_rendererControl, new PresentEvent(sb.m_time));
if (m_rate == 0)
queueEvent(MEStreamSinkScrubSampleComplete, GUID_NULL, S_OK, NULL);
@@ -1393,6 +1405,8 @@ namespace
queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL);
}
IMFMediaBuffer *m_scheduledBuffer;
+ MFTIME m_bufferStartTime;
+ MFTIME m_bufferDuration;
IMFPresentationClock *m_presentationClock;
float m_rate;
};