Merge "AudioTrack inline short const methods"
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index a010bb6..c5fbbf0 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -32,7 +32,7 @@
CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
OPEN_RECORD,
SAMPLE_RATE,
- CHANNEL_COUNT, // obsolete
+ RESERVED, // obsolete, was CHANNEL_COUNT
FORMAT,
FRAME_COUNT,
LATENCY,
@@ -191,17 +191,6 @@
return reply.readInt32();
}
-#if 0
- virtual int channelCount(audio_io_handle_t output) const
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
- data.writeInt32((int32_t) output);
- remote()->transact(CHANNEL_COUNT, data, &reply);
- return reply.readInt32();
- }
-#endif
-
virtual audio_format_t format(audio_io_handle_t output) const
{
Parcel data, reply;
@@ -768,13 +757,6 @@
reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
return NO_ERROR;
} break;
-#if 0
- case CHANNEL_COUNT: {
- CHECK_INTERFACE(IAudioFlinger, data, reply);
- reply->writeInt32( channelCount((audio_io_handle_t) data.readInt32()) );
- return NO_ERROR;
- } break;
-#endif
case FORMAT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index d3ec122..f363568 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -50,6 +50,49 @@
namespace android {
+struct NuPlayer::Action : public RefBase {
+ Action() {}
+
+ virtual void execute(NuPlayer *player) = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(Action);
+};
+
+struct NuPlayer::SeekAction : public Action {
+ SeekAction(int64_t seekTimeUs)
+ : mSeekTimeUs(seekTimeUs) {
+ }
+
+ virtual void execute(NuPlayer *player) {
+ player->performSeek(mSeekTimeUs);
+ }
+
+private:
+ int64_t mSeekTimeUs;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
+};
+
+// Use this if there's no state necessary to save in order to execute
+// the action.
+struct NuPlayer::SimpleAction : public Action {
+ typedef void (NuPlayer::*ActionFunc)();
+
+ SimpleAction(ActionFunc func)
+ : mFunc(func) {
+ }
+
+ virtual void execute(NuPlayer *player) {
+ (player->*mFunc)();
+ }
+
+private:
+ ActionFunc mFunc;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
+};
+
////////////////////////////////////////////////////////////////////////////////
NuPlayer::NuPlayer()
@@ -63,8 +106,6 @@
mTimeDiscontinuityPending(false),
mFlushingAudio(NONE),
mFlushingVideo(NONE),
- mResetInProgress(false),
- mResetPostponed(false),
mSkipRenderingAudioUntilMediaTimeUs(-1ll),
mSkipRenderingVideoUntilMediaTimeUs(-1ll),
mVideoLateByUs(0ll),
@@ -495,8 +536,15 @@
mRenderer->queueEOS(audio, UNKNOWN_ERROR);
} else if (what == ACodec::kWhatDrainThisBuffer) {
renderBuffer(audio, codecRequest);
- } else {
- ALOGV("Unhandled codec notification %d.", what);
+ } else if (what != ACodec::kWhatComponentAllocated
+ && what != ACodec::kWhatComponentConfigured
+ && what != ACodec::kWhatBuffersAllocated) {
+ ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
+ what,
+ what >> 24,
+ (what >> 16) & 0xff,
+ (what >> 8) & 0xff,
+ what & 0xff);
}
break;
@@ -569,47 +617,13 @@
{
ALOGV("kWhatReset");
- cancelPollDuration();
+ mDeferredActions.push_back(
+ new SimpleAction(&NuPlayer::performDecoderShutdown));
- if (mRenderer != NULL) {
- // There's an edge case where the renderer owns all output
- // buffers and is paused, therefore the decoder will not read
- // more input data and will never encounter the matching
- // discontinuity. To avoid this, we resume the renderer.
+ mDeferredActions.push_back(
+ new SimpleAction(&NuPlayer::performReset));
- if (mFlushingAudio == AWAITING_DISCONTINUITY
- || mFlushingVideo == AWAITING_DISCONTINUITY) {
- mRenderer->resume();
- }
- }
-
- if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
- // We're currently flushing, postpone the reset until that's
- // completed.
-
- ALOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",
- mFlushingAudio, mFlushingVideo);
-
- mResetPostponed = true;
- break;
- }
-
- if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
- finishReset();
- break;
- }
-
- mTimeDiscontinuityPending = true;
-
- if (mAudioDecoder != NULL) {
- flushDecoder(true /* audio */, true /* needShutdown */);
- }
-
- if (mVideoDecoder != NULL) {
- flushDecoder(false /* audio */, true /* needShutdown */);
- }
-
- mResetInProgress = true;
+ processDeferredActions();
break;
}
@@ -618,18 +632,14 @@
int64_t seekTimeUs;
CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
- ALOGV("kWhatSeek seekTimeUs=%lld us (%.2f secs)",
- seekTimeUs, seekTimeUs / 1E6);
+ ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
- mSource->seekTo(seekTimeUs);
+ mDeferredActions.push_back(
+ new SimpleAction(&NuPlayer::performDecoderFlush));
- if (mDriver != NULL) {
- sp<NuPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- driver->notifySeekComplete();
- }
- }
+ mDeferredActions.push_back(new SeekAction(seekTimeUs));
+ processDeferredActions();
break;
}
@@ -680,39 +690,7 @@
mFlushingAudio = NONE;
mFlushingVideo = NONE;
- if (mResetInProgress) {
- ALOGV("reset completed");
-
- mResetInProgress = false;
- finishReset();
- } else if (mResetPostponed) {
- (new AMessage(kWhatReset, id()))->post();
- mResetPostponed = false;
- } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
- postScanSources();
- }
-}
-
-void NuPlayer::finishReset() {
- CHECK(mAudioDecoder == NULL);
- CHECK(mVideoDecoder == NULL);
-
- ++mScanSourcesGeneration;
- mScanSourcesPending = false;
-
- mRenderer.clear();
-
- if (mSource != NULL) {
- mSource->stop();
- mSource.clear();
- }
-
- if (mDriver != NULL) {
- sp<NuPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- driver->notifyResetComplete();
- }
- }
+ processDeferredActions();
}
void NuPlayer::postScanSources() {
@@ -831,6 +809,14 @@
mTimeDiscontinuityPending || timeChange;
if (formatChange || timeChange) {
+ if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
+ // And we'll resume scanning sources once we're done
+ // flushing.
+ mDeferredActions.push_front(
+ new SimpleAction(
+ &NuPlayer::performScanSources));
+ }
+
flushDecoder(audio, formatChange);
} else {
// This stream is unaffected by the discontinuity
@@ -1023,4 +1009,127 @@
++mPollDurationGeneration;
}
+void NuPlayer::processDeferredActions() {
+ while (!mDeferredActions.empty()) {
+ // We won't execute any deferred actions until we're no longer in
+ // an intermediate state, i.e. one more more decoders are currently
+ // flushing or shutting down.
+
+ if (mRenderer != NULL) {
+ // There's an edge case where the renderer owns all output
+ // buffers and is paused, therefore the decoder will not read
+ // more input data and will never encounter the matching
+ // discontinuity. To avoid this, we resume the renderer.
+
+ if (mFlushingAudio == AWAITING_DISCONTINUITY
+ || mFlushingVideo == AWAITING_DISCONTINUITY) {
+ mRenderer->resume();
+ }
+ }
+
+ if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
+ // We're currently flushing, postpone the reset until that's
+ // completed.
+
+ ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
+ mFlushingAudio, mFlushingVideo);
+
+ break;
+ }
+
+ sp<Action> action = *mDeferredActions.begin();
+ mDeferredActions.erase(mDeferredActions.begin());
+
+ action->execute(this);
+ }
+}
+
+void NuPlayer::performSeek(int64_t seekTimeUs) {
+ ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
+ seekTimeUs,
+ seekTimeUs / 1E6);
+
+ mSource->seekTo(seekTimeUs);
+
+ if (mDriver != NULL) {
+ sp<NuPlayerDriver> driver = mDriver.promote();
+ if (driver != NULL) {
+ driver->notifyPosition(seekTimeUs);
+ driver->notifySeekComplete();
+ }
+ }
+
+ // everything's flushed, continue playback.
+}
+
+void NuPlayer::performDecoderFlush() {
+ ALOGV("performDecoderFlush");
+
+ if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
+ return;
+ }
+
+ mTimeDiscontinuityPending = true;
+
+ if (mAudioDecoder != NULL) {
+ flushDecoder(true /* audio */, false /* needShutdown */);
+ }
+
+ if (mVideoDecoder != NULL) {
+ flushDecoder(false /* audio */, false /* needShutdown */);
+ }
+}
+
+void NuPlayer::performDecoderShutdown() {
+ ALOGV("performDecoderShutdown");
+
+ if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
+ return;
+ }
+
+ mTimeDiscontinuityPending = true;
+
+ if (mAudioDecoder != NULL) {
+ flushDecoder(true /* audio */, true /* needShutdown */);
+ }
+
+ if (mVideoDecoder != NULL) {
+ flushDecoder(false /* audio */, true /* needShutdown */);
+ }
+}
+
+void NuPlayer::performReset() {
+ ALOGV("performReset");
+
+ CHECK(mAudioDecoder == NULL);
+ CHECK(mVideoDecoder == NULL);
+
+ cancelPollDuration();
+
+ ++mScanSourcesGeneration;
+ mScanSourcesPending = false;
+
+ mRenderer.clear();
+
+ if (mSource != NULL) {
+ mSource->stop();
+ mSource.clear();
+ }
+
+ if (mDriver != NULL) {
+ sp<NuPlayerDriver> driver = mDriver.promote();
+ if (driver != NULL) {
+ driver->notifyResetComplete();
+ }
+ }
+}
+
+void NuPlayer::performScanSources() {
+ ALOGV("performScanSources");
+
+ if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
+ postScanSources();
+ }
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 31efb2e..6e174e0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -73,6 +73,9 @@
struct Renderer;
struct RTSPSource;
struct StreamingSource;
+ struct Action;
+ struct SeekAction;
+ struct SimpleAction;
enum {
kWhatSetDataSource = '=DaS',
@@ -102,6 +105,8 @@
sp<Decoder> mAudioDecoder;
sp<Renderer> mRenderer;
+ List<sp<Action> > mDeferredActions;
+
bool mAudioEOS;
bool mVideoEOS;
@@ -126,8 +131,6 @@
FlushStatus mFlushingAudio;
FlushStatus mFlushingVideo;
- bool mResetInProgress;
- bool mResetPostponed;
int64_t mSkipRenderingAudioUntilMediaTimeUs;
int64_t mSkipRenderingVideoUntilMediaTimeUs;
@@ -150,12 +153,19 @@
static bool IsFlushingState(FlushStatus state, bool *needShutdown = NULL);
- void finishReset();
void postScanSources();
void schedulePollDuration();
void cancelPollDuration();
+ void processDeferredActions();
+
+ void performSeek(int64_t seekTimeUs);
+ void performDecoderFlush();
+ void performDecoderShutdown();
+ void performReset();
+ void performScanSources();
+
DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
};
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index b2afec7..1a62f9d 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1424,18 +1424,15 @@
if (mFileMetaData != NULL) {
ALOGV("chunk_data_size = %lld and data_offset = %lld",
chunk_data_size, data_offset);
- uint8_t *buffer = new uint8_t[chunk_data_size + 1];
+ sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
if (mDataSource->readAt(
- data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) {
- delete[] buffer;
- buffer = NULL;
-
+ data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
return ERROR_IO;
}
const int kSkipBytesOfDataBox = 16;
mFileMetaData->setData(
kKeyAlbumArt, MetaData::TYPE_NONE,
- buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
+ buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
}
*offset += chunk_size;
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index c4050b8..dc65833 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -66,9 +66,6 @@
LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
-# uncomment for systrace
-# LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_AUDIO
-
# uncomment for dumpsys to write most recent audio output to .wav file
# 47.5 seconds at 44.1 kHz, 8 megabytes
# LOCAL_CFLAGS += -DTEE_SINK_FRAMES=0x200000
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 2160ea3..0366dfe 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -17,6 +17,11 @@
#define LOG_TAG "FastMixer"
//#define LOG_NDEBUG 0
+/** Uncomment for systrace.
+ * ATRACE_TAG will default to ATRACE_TAG_NEVER in the header.
+ */
+//#define ATRACE_TAG ATRACE_TAG_AUDIO
+
#include <sys/atomics.h>
#include <time.h>
#include <utils/Log.h>
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 6cada0a..fd64395 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "AudioFlinger"
//#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_AUDIO
#include <math.h>
#include <fcntl.h>
@@ -25,6 +26,7 @@
#include <cutils/properties.h>
#include <cutils/compiler.h>
#include <utils/Log.h>
+#include <utils/Trace.h>
#include <private/media/AudioTrackShared.h>
#include <hardware/audio.h>
@@ -1652,9 +1654,7 @@
if (mNormalSink != 0) {
#define mBitShift 2 // FIXME
size_t count = mixBufferSize >> mBitShift;
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
ATRACE_BEGIN("write");
-#endif
// update the setpoint when AudioFlinger::mScreenState changes
uint32_t screenState = AudioFlinger::mScreenState;
if (screenState != mScreenState) {
@@ -1666,9 +1666,7 @@
}
}
ssize_t framesWritten = mNormalSink->write(mMixBuffer, count);
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
ATRACE_END();
-#endif
if (framesWritten > 0) {
bytesWritten = framesWritten << mBitShift;
} else {
@@ -2000,9 +1998,7 @@
if (!mStandby && delta > maxPeriod) {
mNumDelayedWrites++;
if ((now - lastWarning) > kWarningThrottleNs) {
-#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
- ScopedTrace st(ATRACE_TAG, "underrun");
-#endif
+ ATRACE_NAME("underrun");
ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
ns2ms(delta), mNumDelayedWrites, this);
lastWarning = now;