summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.cpp31
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.h1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp15
3 files changed, 38 insertions, 9 deletions
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 7dc9be7..b3eb5fd 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -467,9 +467,17 @@ void NuPlayer::GenericSource::finishPrepareAsync() {
void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
if (err != OK) {
- mDataSource.clear();
- mCachedSource.clear();
- mHttpSource.clear();
+ {
+ sp<DataSource> dataSource = mDataSource;
+ sp<NuCachedSource2> cachedSource = mCachedSource;
+ sp<DataSource> httpSource = mHttpSource;
+ {
+ Mutex::Autolock _l(mDisconnectLock);
+ mDataSource.clear();
+ mCachedSource.clear();
+ mHttpSource.clear();
+ }
+ }
mBitrate = -1;
cancelPollBuffering();
@@ -522,13 +530,20 @@ void NuPlayer::GenericSource::resume() {
}
void NuPlayer::GenericSource::disconnect() {
- if (mDataSource != NULL) {
+ sp<DataSource> dataSource, httpSource;
+ {
+ Mutex::Autolock _l(mDisconnectLock);
+ dataSource = mDataSource;
+ httpSource = mHttpSource;
+ }
+
+ if (dataSource != NULL) {
// disconnect data source
- if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
- static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect();
+ if (dataSource->flags() & DataSource::kIsCachingDataSource) {
+ static_cast<NuCachedSource2 *>(dataSource.get())->disconnect();
}
- } else if (mHttpSource != NULL) {
- static_cast<HTTPBase *>(mHttpSource.get())->disconnect();
+ } else if (httpSource != NULL) {
+ static_cast<HTTPBase *>(httpSource.get())->disconnect();
}
}
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index dc85d2d..ac980ef 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -153,6 +153,7 @@ private:
int32_t mPrevBufferPercentage;
mutable Mutex mReadBufferLock;
+ mutable Mutex mDisconnectLock;
sp<ALooper> mLooper;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index de7f5e7..bca2888 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -886,6 +886,8 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
ALOGV("AudioSink write would block when writing %zu bytes", copy);
} else {
ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
+ // This can only happen when AudioSink was opened with doNotReconnect flag set to
+ // true, in which case the NuPlayer will handle the reconnect.
notifyAudioTearDown();
}
break;
@@ -952,6 +954,10 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
int64_t NuPlayer::Renderer::getDurationUsIfPlayedAtSampleRate(uint32_t numFrames) {
int32_t sampleRate = offloadingAudio() ?
mCurrentOffloadInfo.sample_rate : mCurrentPcmInfo.mSampleRate;
+ if (sampleRate == 0) {
+ ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload");
+ return 0;
+ }
// TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours.
return (int64_t)((int32_t)numFrames * 1000000LL / sampleRate);
}
@@ -1781,6 +1787,12 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
const uint32_t frameCount =
(unsigned long long)sampleRate * getAudioSinkPcmMsSetting() / 1000;
+ // The doNotReconnect means AudioSink will signal back and let NuPlayer to re-construct
+ // AudioSink. We don't want this when there's video because it will cause a video seek to
+ // the previous I frame. But we do want this when there's only audio because it will give
+ // NuPlayer a chance to switch from non-offload mode to offload mode.
+ // So we only set doNotReconnect when there's no video.
+ const bool doNotReconnect = !hasVideo;
status_t err = mAudioSink->open(
sampleRate,
numChannels,
@@ -1791,13 +1803,14 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
mUseAudioCallback ? this : NULL,
(audio_output_flags_t)pcmFlags,
NULL,
- true /* doNotReconnect */,
+ doNotReconnect,
frameCount);
if (err == OK) {
err = mAudioSink->setPlaybackRate(mPlaybackSettings);
}
if (err != OK) {
ALOGW("openAudioSink: non offloaded open failed status: %d", err);
+ mAudioSink->close();
mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
return err;
}