summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/AudioTrack.h1
-rw-r--r--media/libavextensions/media/AVMediaExtensions.h4
-rw-r--r--media/libmedia/AudioTrack.cpp15
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp51
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h2
5 files changed, 23 insertions, 50 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 42fa3be..191802d 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -943,6 +943,7 @@ protected:
// a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
audio_port_handle_t mSelectedDeviceId;
bool mPlaybackRateSet;
+ bool mTrackOffloaded;
private:
class DeathNotifier : public IBinder::DeathRecipient {
diff --git a/media/libavextensions/media/AVMediaExtensions.h b/media/libavextensions/media/AVMediaExtensions.h
index ae26143..9161fae 100644
--- a/media/libavextensions/media/AVMediaExtensions.h
+++ b/media/libavextensions/media/AVMediaExtensions.h
@@ -60,6 +60,10 @@ struct AVMediaUtils {
return frameCount;
}
+ virtual bool AudioTrackIsTrackOffloaded(audio_io_handle_t /*output*/) {
+ return false;
+ }
+
virtual sp<MediaRecorder> createMediaRecorder(const String16& opPackageName);
virtual void writeCustomData(
Parcel * /* reply */, void * /* buffer_data */) {}
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 3a8dc07..0541f21 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -858,10 +858,9 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
mProxy->setPlaybackRate(playbackRateTemp);
mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate
- // fallback out of Direct PCM if setPlaybackRate is called on PCM track
- if (property_get_bool("audio.offload.track.enable", false) &&
- (mFormat == AUDIO_FORMAT_PCM_16_BIT) && (mOffloadInfo == NULL) &&
- (mFlags == AUDIO_OUTPUT_FLAG_NONE)) {
+ // fallback out of Direct PCM if setPlaybackRate is called on a track offloaded
+ // session. Do this by setting mPlaybackRateSet to true
+ if (mTrackOffloaded) {
mPlaybackRateSet = true;
android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
}
@@ -1174,6 +1173,7 @@ status_t AudioTrack::createTrack_l()
mSessionId, streamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);
return BAD_VALUE;
}
+ mTrackOffloaded = AVMediaUtils::get()->AudioTrackIsTrackOffloaded(output);
{
// Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
// we must release it ourselves if anything goes wrong.
@@ -2273,8 +2273,8 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp)
}
status_t status = UNKNOWN_ERROR;
- //do not call Timestamp if its PCM offloaded
- if (!AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat)) {
+ //call Timestamp only if its NOT PCM offloaded and NOT Track Offloaded
+ if (!AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat) && !mTrackOffloaded) {
// The presented frame count must always lag behind the consumed frame count.
// To avoid a race, read the presented frames first. This ensures that presented <= consumed.
@@ -2286,7 +2286,8 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp)
}
- if (isOffloadedOrDirect_l() && !AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat)) {
+ if (isOffloadedOrDirect_l() && !AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat)
+ && !mTrackOffloaded) {
if (isOffloaded_l() && (mState == STATE_PAUSED || mState == STATE_PAUSED_STOPPING)) {
// use cached paused position in case another offloaded track is running.
timestamp.mPosition = mPausedPosition;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 8064781..a494e87 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1111,46 +1111,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
int32_t reason;
CHECK(msg->findInt32("reason", &reason));
ALOGV("Tear down audio with reason %d.", reason);
-
- if (ifDecodedPCMOffload()) {
- tearDownPCMOffload(msg);
- break;
- }
-
- mAudioDecoder.clear();
- ++mAudioDecoderGeneration;
- bool needsToCreateAudioDecoder = true;
- if (mFlushingAudio == FLUSHING_DECODER) {
- mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
- mFlushingAudio = FLUSHED;
- finishFlushIfPossible();
- } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
- || mFlushingAudio == SHUTTING_DOWN_DECODER) {
- mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
- mFlushingAudio = SHUT_DOWN;
- finishFlushIfPossible();
- needsToCreateAudioDecoder = false;
- }
- if (mRenderer == NULL) {
- break;
- }
- closeAudioSink();
- mRenderer->flush(
- true /* audio */, false /* notifyComplete */);
- if (mVideoDecoder != NULL) {
- mRenderer->flush(
- false /* audio */, false /* notifyComplete */);
- }
-
- int64_t positionUs;
- if (!msg->findInt64("positionUs", &positionUs)) {
- positionUs = mPreviousSeekTimeUs;
- }
- performSeek(positionUs);
-
- if (reason == Renderer::kDueToError && needsToCreateAudioDecoder) {
- instantiateDecoder(true /* audio */, &mAudioDecoder);
- }
+ performTearDown(msg);
}
break;
}
@@ -2419,7 +2380,12 @@ void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
TRESPASS();
}
-void NuPlayer::tearDownPCMOffload(const sp<AMessage> &msg) {
+//
+// There is a flush from within the decoder's onFlush handling.
+// Without it, it is still possible that a buffer can be queueued
+// after NuPlayer issues a flush on the renderer's audio queue.
+//
+void NuPlayer::performTearDown(const sp<AMessage> &msg) {
int32_t reason;
CHECK(msg->findInt32("reason", &reason));
@@ -2443,13 +2409,14 @@ void NuPlayer::tearDownPCMOffload(const sp<AMessage> &msg) {
mDeferredActions.push_back(new SeekAction(positionUs));
break;
default:
- ALOGW("tearDownPCMOffload while flushing audio in %d", mFlushingAudio);
+ ALOGW("performTearDown while flushing audio in %d", mFlushingAudio);
break;
}
}
if (mRenderer != NULL) {
closeAudioSink();
+ // see comment at beginning of function
mRenderer->flush(
true /* audio */, false /* notifyComplete */);
if (mVideoDecoder != NULL) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 1f4dec8..ee0f3e6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -281,7 +281,7 @@ protected:
void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const;
- void tearDownPCMOffload(const sp<AMessage> &msg);
+ void performTearDown(const sp<AMessage> &msg);
DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
};