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

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

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