Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I9c1abddf20e85cc0f29f2da26c398b7180e4f479
This commit is contained in:
@@ -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,16 +96,24 @@ static JNINativeMethod methods[] = {
|
||||
|
||||
bool JSurfaceTexture::initJNI(JNIEnv *env)
|
||||
{
|
||||
jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTexture");
|
||||
// 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 (clazz) {
|
||||
g_qtSurfaceTextureClass = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
if (env->RegisterNatives(g_qtSurfaceTextureClass,
|
||||
methods,
|
||||
sizeof(methods) / sizeof(methods[0])) < 0) {
|
||||
return false;
|
||||
if (surfaceTextureClass) {
|
||||
jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTexture");
|
||||
if (env->ExceptionCheck())
|
||||
env->ExceptionClear();
|
||||
|
||||
if (clazz) {
|
||||
g_qtSurfaceTextureClass = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
if (env->RegisterNatives(g_qtSurfaceTextureClass,
|
||||
methods,
|
||||
sizeof(methods) / sizeof(methods[0])) < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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