Merge remote-tracking branch 'origin/5.3' into dev
Change-Id: I38ebcb3da0e4d2acc9e7108c9579ea98323864e0
This commit is contained in:
61
dist/changes-5.3.1
vendored
Normal file
61
dist/changes-5.3.1
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
Qt 5.3.1 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.3.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.3
|
||||
|
||||
The Qt version 5.3 series is binary compatible with the 5.2.x series.
|
||||
Applications compiled for 5.2 will continue to run with 5.3.
|
||||
|
||||
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.
|
||||
|
||||
****************************************************************************
|
||||
* Library *
|
||||
****************************************************************************
|
||||
|
||||
QtMultimedia
|
||||
------------
|
||||
|
||||
- Importing QtMultimedia in QML with the 5.3 version number is now
|
||||
correctly recognized.
|
||||
- [QTBUG-38218][QTBUG-30447] VideoOutput (QML): Fix garbled rendering of
|
||||
video frames when the stride is not equal to the width.
|
||||
- [QTBUG-38755] Fixed parsing PLS playlist files when the system's locale
|
||||
is not English.
|
||||
|
||||
****************************************************************************
|
||||
* Platform Specific Changes *
|
||||
****************************************************************************
|
||||
|
||||
Android
|
||||
-------
|
||||
|
||||
- A media player's volume is now preserved when loading a new media.
|
||||
- QMediaPlayer can now play Qt resource files on Android 4.1 and lower.
|
||||
- [QTBUG-39015] Fixed sound being in rare occasions garbled when playing
|
||||
audio with QAudioOutput and QSoundEffect.
|
||||
- [QTBUG-39346] QMediaPlayer and the corresponding QML types can now play
|
||||
files located in the application private storage, such as temporary
|
||||
files.
|
||||
|
||||
Linux
|
||||
-----
|
||||
|
||||
- [QTBUG-39202] Fixed crash on application startup when using a static
|
||||
version of Qt.
|
||||
- [QTBUG-38465] Fixed media player dropping a lot of frames when playing a
|
||||
live stream.
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
- [QTBUG-39202] Fixed crash on application startup when using a static
|
||||
version of Qt.
|
||||
@@ -66,7 +66,8 @@ Generator::Generator(const QAudioFormat &format,
|
||||
: QIODevice(parent)
|
||||
, m_pos(0)
|
||||
{
|
||||
generateData(format, durationUs, sampleRate);
|
||||
if (format.isValid())
|
||||
generateData(format, durationUs, sampleRate);
|
||||
}
|
||||
|
||||
Generator::~Generator()
|
||||
@@ -133,11 +134,13 @@ void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int
|
||||
qint64 Generator::readData(char *data, qint64 len)
|
||||
{
|
||||
qint64 total = 0;
|
||||
while (len - total > 0) {
|
||||
const qint64 chunk = qMin((m_buffer.size() - m_pos), len - total);
|
||||
memcpy(data + total, m_buffer.constData() + m_pos, chunk);
|
||||
m_pos = (m_pos + chunk) % m_buffer.size();
|
||||
total += chunk;
|
||||
if (!m_buffer.isEmpty()) {
|
||||
while (len - total > 0) {
|
||||
const qint64 chunk = qMin((m_buffer.size() - m_pos), len - total);
|
||||
memcpy(data + total, m_buffer.constData() + m_pos, chunk);
|
||||
m_pos = (m_pos + chunk) % m_buffer.size();
|
||||
total += chunk;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -181,8 +181,7 @@ that the divider should be displayed.
|
||||
|
||||
The main.qml file shows a
|
||||
\l{video/qmlvideofx/qml/qmlvideofx/FileOpen.qml}{FileOpen}, which allows
|
||||
the user to select the input source and an
|
||||
\l{video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml}{EffectSelectionPanel}
|
||||
the user to select the input source and an EffectSelectionPanel
|
||||
item, which lists each of the available shader effects. As described above, a
|
||||
\l{video/qmlvideofx/qml/qmlvideofx/Content.qml}{Content} item is used to load the
|
||||
appropriate input and effect type. A
|
||||
|
||||
@@ -634,13 +634,13 @@ void QDeclarativeCamera::setDigitalZoom(qreal value)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal Camera::stateChanged(state)
|
||||
\qmlsignal Camera::cameraStateChanged(state)
|
||||
|
||||
This signal is emitted when the camera state has changed to \a state. Since the
|
||||
state changes may take some time to occur this signal may arrive sometime
|
||||
after the state change has been requested.
|
||||
|
||||
The corresponding handler is \c onStateChanged.
|
||||
The corresponding handler is \c onCameraStateChanged.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
||||
@@ -71,7 +71,7 @@ classes derived from them.
|
||||
|
||||
Consider a developer creating, for example, a media player class called MyPlayer.
|
||||
It may have special requirements beyond ordinary media players and so may
|
||||
need a custom service and a custom control. We can subclass \l QMediaServiceProvider
|
||||
need a custom service and a custom control. We can subclass QMediaServiceProvider
|
||||
to create our MyServiceProvider class. Also we will create a
|
||||
MyMediaService, and the MyMediaControl to manipulate the media service.
|
||||
|
||||
|
||||
@@ -38,5 +38,5 @@
|
||||
QML alternatives. If your application is serving complex use cases such as
|
||||
decoding media files, accessing video or audio buffers, use the C++
|
||||
alternative. For more details about the complex audio, video, and camera use
|
||||
cases supported by the C++ classes, refer to \l {Qt Multimedia Overview}.
|
||||
cases supported by the C++ classes, refer to \l {Multimedia}{Multimedia Overview}.
|
||||
*/
|
||||
|
||||
@@ -63,7 +63,6 @@ QAlsaAudioInput::QAlsaAudioInput(const QByteArray &device)
|
||||
{
|
||||
bytesAvailable = 0;
|
||||
handle = 0;
|
||||
ahandler = 0;
|
||||
access = SND_PCM_ACCESS_RW_INTERLEAVED;
|
||||
pcmformat = SND_PCM_FORMAT_S16;
|
||||
buffer_size = 0;
|
||||
|
||||
@@ -159,7 +159,6 @@ private:
|
||||
unsigned int period_time;
|
||||
snd_pcm_uframes_t buffer_frames;
|
||||
snd_pcm_uframes_t period_frames;
|
||||
snd_async_handler_t* ahandler;
|
||||
snd_pcm_access_t access;
|
||||
snd_pcm_format_t pcmformat;
|
||||
snd_timestamp_t* timestamp;
|
||||
|
||||
@@ -63,7 +63,6 @@ QAlsaAudioOutput::QAlsaAudioOutput(const QByteArray &device)
|
||||
{
|
||||
bytesAvailable = 0;
|
||||
handle = 0;
|
||||
ahandler = 0;
|
||||
access = SND_PCM_ACCESS_RW_INTERLEAVED;
|
||||
pcmformat = SND_PCM_FORMAT_S16;
|
||||
buffer_frames = 0;
|
||||
@@ -118,17 +117,6 @@ QAudio::State QAlsaAudioOutput::state() const
|
||||
return deviceState;
|
||||
}
|
||||
|
||||
void QAlsaAudioOutput::async_callback(snd_async_handler_t *ahandler)
|
||||
{
|
||||
QAlsaAudioOutput* audioOut;
|
||||
|
||||
audioOut = static_cast<QAlsaAudioOutput*>
|
||||
(snd_async_handler_get_callback_private(ahandler));
|
||||
|
||||
if (audioOut && (audioOut->deviceState == QAudio::ActiveState || audioOut->resuming))
|
||||
audioOut->feedback();
|
||||
}
|
||||
|
||||
int QAlsaAudioOutput::xrun_recovery(int err)
|
||||
{
|
||||
int count = 0;
|
||||
@@ -512,8 +500,7 @@ bool QAlsaAudioOutput::open()
|
||||
snd_pcm_prepare( handle );
|
||||
snd_pcm_start(handle);
|
||||
|
||||
// Step 5: Setup callback and timer fallback
|
||||
snd_async_add_pcm_handler(&ahandler, handle, async_callback, this);
|
||||
// Step 5: Setup timer
|
||||
bytesAvailable = bytesFree();
|
||||
|
||||
// Step 6: Start audio processing
|
||||
@@ -715,21 +702,6 @@ void QAlsaAudioOutput::userFeed()
|
||||
deviceReady();
|
||||
}
|
||||
|
||||
void QAlsaAudioOutput::feedback()
|
||||
{
|
||||
updateAvailable();
|
||||
}
|
||||
|
||||
|
||||
void QAlsaAudioOutput::updateAvailable()
|
||||
{
|
||||
#ifdef DEBUG_AUDIO
|
||||
QTime now(QTime::currentTime());
|
||||
qDebug()<<now.second()<<"s "<<now.msec()<<"ms :updateAvailable()";
|
||||
#endif
|
||||
bytesAvailable = bytesFree();
|
||||
}
|
||||
|
||||
bool QAlsaAudioOutput::deviceReady()
|
||||
{
|
||||
if(pullMode) {
|
||||
|
||||
@@ -107,8 +107,6 @@ public:
|
||||
|
||||
private slots:
|
||||
void userFeed();
|
||||
void feedback();
|
||||
void updateAvailable();
|
||||
bool deviceReady();
|
||||
|
||||
signals:
|
||||
@@ -126,7 +124,6 @@ private:
|
||||
unsigned int period_time;
|
||||
snd_pcm_uframes_t buffer_frames;
|
||||
snd_pcm_uframes_t period_frames;
|
||||
static void async_callback(snd_async_handler_t *ahandler);
|
||||
int xrun_recovery(int err);
|
||||
|
||||
int setFormat();
|
||||
@@ -141,7 +138,6 @@ private:
|
||||
qint64 elapsedTimeOffset;
|
||||
char* audioBuffer;
|
||||
snd_pcm_t* handle;
|
||||
snd_async_handler_t* ahandler;
|
||||
snd_pcm_access_t access;
|
||||
snd_pcm_format_t pcmformat;
|
||||
snd_timestamp_t* timestamp;
|
||||
|
||||
@@ -234,25 +234,24 @@ void QAndroidCameraFocusControl::updateFocusZones(QCameraFocusZone::FocusZoneSta
|
||||
// create a focus zone (50x50 pixel) around the focus point
|
||||
m_focusZones.clear();
|
||||
|
||||
if (m_actualFocusPoint.isNull())
|
||||
return;
|
||||
if (!m_actualFocusPoint.isNull()) {
|
||||
QSize viewportSize = m_session->camera()->previewSize();
|
||||
|
||||
QSize viewportSize = m_session->camera()->previewSize();
|
||||
if (!viewportSize.isValid())
|
||||
return;
|
||||
|
||||
if (!viewportSize.isValid())
|
||||
return;
|
||||
QSizeF focusSize(50.f / viewportSize.width(), 50.f / viewportSize.height());
|
||||
float x = qBound(qreal(0),
|
||||
m_actualFocusPoint.x() - (focusSize.width() / 2),
|
||||
1.f - focusSize.width());
|
||||
float y = qBound(qreal(0),
|
||||
m_actualFocusPoint.y() - (focusSize.height() / 2),
|
||||
1.f - focusSize.height());
|
||||
|
||||
QSizeF focusSize(50.f / viewportSize.width(), 50.f / viewportSize.height());
|
||||
float x = qBound(qreal(0),
|
||||
m_actualFocusPoint.x() - (focusSize.width() / 2),
|
||||
1.f - focusSize.width());
|
||||
float y = qBound(qreal(0),
|
||||
m_actualFocusPoint.y() - (focusSize.height() / 2),
|
||||
1.f - focusSize.height());
|
||||
QRectF area(QPointF(x, y), focusSize);
|
||||
|
||||
QRectF area(QPointF(x, y), focusSize);
|
||||
|
||||
m_focusZones.append(QCameraFocusZone(area, status));
|
||||
m_focusZones.append(QCameraFocusZone(area, status));
|
||||
}
|
||||
|
||||
emit focusZonesChanged();
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ void QAndroidCaptureSession::stop(bool error)
|
||||
delete m_mediaRecorder;
|
||||
m_mediaRecorder = 0;
|
||||
|
||||
if (m_cameraSession) {
|
||||
if (m_cameraSession && m_cameraSession->status() == QCamera::ActiveStatus) {
|
||||
// Viewport needs to be restarted after recording
|
||||
restartViewfinder();
|
||||
}
|
||||
@@ -278,7 +278,7 @@ void QAndroidCaptureSession::stop(bool error)
|
||||
// if the media is saved into the standard media location, register it
|
||||
// with the Android media scanner so it appears immediately in apps
|
||||
// such as the gallery.
|
||||
QString mediaPath = m_actualOutputLocation.toLocalFile();
|
||||
QString mediaPath = m_usedOutputLocation.toLocalFile();
|
||||
QString standardLoc = m_cameraSession ? AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM)
|
||||
: AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::Sounds);
|
||||
if (mediaPath.startsWith(standardLoc))
|
||||
@@ -516,6 +516,7 @@ void QAndroidCaptureSession::updateStatus()
|
||||
if (m_cameraSession->status() == QCamera::StoppingStatus
|
||||
|| !m_cameraSession->captureMode().testFlag(QCamera::CaptureVideo)) {
|
||||
setState(QMediaRecorder::StoppedState);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_state == QMediaRecorder::RecordingState) {
|
||||
|
||||
@@ -487,6 +487,11 @@ QUrl CameraBinSession::outputLocation() const
|
||||
|
||||
bool CameraBinSession::setOutputLocation(const QUrl& sink)
|
||||
{
|
||||
if (!sink.isRelative() && !sink.isLocalFile()) {
|
||||
qWarning("Output location must be a local file");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_sink = m_actualSink = sink;
|
||||
return true;
|
||||
}
|
||||
@@ -1007,8 +1012,9 @@ void CameraBinSession::recordVideo()
|
||||
if (m_actualSink.isEmpty()) {
|
||||
QString ext = m_mediaContainerControl->suggestedFileExtension(m_mediaContainerControl->actualContainerFormat());
|
||||
m_actualSink = QUrl::fromLocalFile(generateFileName("clip_", defaultDir(QCamera::CaptureVideo), ext));
|
||||
} else if (!m_actualSink.isLocalFile()) {
|
||||
m_actualSink = QUrl::fromLocalFile(m_actualSink.toEncoded());
|
||||
} else {
|
||||
// Output location was rejected in setOutputlocation() if not a local file
|
||||
m_actualSink = QUrl::fromLocalFile(QDir::currentPath()).resolved(m_actualSink);
|
||||
}
|
||||
|
||||
QString fileName = m_actualSink.toLocalFile();
|
||||
|
||||
@@ -134,8 +134,10 @@ GstElement *QGstreamerCaptureSession::buildEncodeBin()
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Output location was rejected in setOutputlocation() if not a local file
|
||||
QUrl actualSink = QUrl::fromLocalFile(QDir::currentPath()).resolved(m_sink);
|
||||
GstElement *fileSink = gst_element_factory_make("filesink", "filesink");
|
||||
g_object_set(G_OBJECT(fileSink), "location", m_sink.toString().toLocal8Bit().constData(), NULL);
|
||||
g_object_set(G_OBJECT(fileSink), "location", QFile::encodeName(actualSink.toLocalFile()).constData(), NULL);
|
||||
gst_bin_add_many(GST_BIN(encodeBin), muxer, fileSink, NULL);
|
||||
|
||||
if (!gst_element_link(muxer, fileSink)) {
|
||||
@@ -731,6 +733,11 @@ QUrl QGstreamerCaptureSession::outputLocation() const
|
||||
|
||||
bool QGstreamerCaptureSession::setOutputLocation(const QUrl& sink)
|
||||
{
|
||||
if (!sink.isRelative() && !sink.isLocalFile()) {
|
||||
qWarning("Output location must be a local file");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_sink = sink;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *
|
||||
emit bufferStatusChanged(0);
|
||||
}
|
||||
|
||||
if (m_stream) {
|
||||
if (m_stream && m_stream != stream) {
|
||||
if (m_ownStream)
|
||||
delete m_stream;
|
||||
m_stream = 0;
|
||||
|
||||
Reference in New Issue
Block a user