Merge "audio policy: fix build with USE_LEGACY_AUDIO_POLICY" into lmp-dev
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 28e5c56..d77ddaf 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -217,6 +217,8 @@
bool mCreateInputBuffersSuspended;
+ bool mTunneled;
+
status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
status_t allocateBuffersOnPort(OMX_U32 portIndex);
status_t freeBuffersOnPort(OMX_U32 portIndex);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 17190fb..cadd691 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1172,6 +1172,7 @@
client.interface(),
(mVideoEncoder == VIDEO_ENCODER_H263 ? MEDIA_MIMETYPE_VIDEO_H263 :
mVideoEncoder == VIDEO_ENCODER_MPEG_4_SP ? MEDIA_MIMETYPE_VIDEO_MPEG4 :
+ mVideoEncoder == VIDEO_ENCODER_VP8 ? MEDIA_MIMETYPE_VIDEO_VP8 :
mVideoEncoder == VIDEO_ENCODER_H264 ? MEDIA_MIMETYPE_VIDEO_AVC : ""),
false /* decoder */, true /* hwCodec */, &codecs);
*supportsCameraSourceMetaDataMode = codecs.size() > 0;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 5270efc..1c73995 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -174,6 +174,7 @@
mNumFramesDropped(0ll),
mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
mStarted(false) {
+ clearFlushComplete();
}
NuPlayer::~NuPlayer() {
@@ -333,25 +334,6 @@
msg->post();
}
-// static
-bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
- switch (state) {
- case FLUSHING_DECODER:
- if (needShutdown != NULL) {
- *needShutdown = false;
- }
- return true;
-
- case FLUSHING_DECODER_SHUTDOWN:
- if (needShutdown != NULL) {
- *needShutdown = true;
- }
- return true;
-
- default:
- return false;
- }
-}
void NuPlayer::writeTrackInfo(
Parcel* reply, const sp<AMessage> format) const {
@@ -773,38 +755,9 @@
mRenderer->queueEOS(audio, err);
} else if (what == Decoder::kWhatFlushCompleted) {
- bool needShutdown;
-
- if (audio) {
- CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
- mFlushingAudio = FLUSHED;
- } else {
- CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
- mFlushingVideo = FLUSHED;
-
- mVideoLateByUs = 0;
- }
-
ALOGV("decoder %s flush completed", audio ? "audio" : "video");
- if (needShutdown) {
- ALOGV("initiating %s decoder shutdown",
- audio ? "audio" : "video");
-
- // Widevine source reads must stop before releasing the video decoder.
- if (!audio && mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
- mSource->stop();
- }
-
- getDecoder(audio)->initiateShutdown();
-
- if (audio) {
- mFlushingAudio = SHUTTING_DOWN_DECODER;
- } else {
- mFlushingVideo = SHUTTING_DOWN_DECODER;
- }
- }
-
+ handleFlushComplete(audio, true /* isDecoder */);
finishFlushIfPossible();
} else if (what == Decoder::kWhatOutputFormatChanged) {
sp<AMessage> format;
@@ -957,6 +910,8 @@
CHECK(msg->findInt32("audio", &audio));
ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
+ handleFlushComplete(audio, false /* isDecoder */);
+ finishFlushIfPossible();
} else if (what == Renderer::kWhatVideoRenderingStart) {
notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
} else if (what == Renderer::kWhatMediaRenderingStart) {
@@ -1048,9 +1003,9 @@
} else {
ALOGW("resume called when source is gone or not set");
}
- // |mAudioDecoder| may have been released due to the pause timeout, so try to re-create
- // it if needed.
- if (mFlushingAudio != SHUT_DOWN) {
+ // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
+ // needed.
+ if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
instantiateDecoder(true /* audio */, &mAudioDecoder);
}
if (mRenderer != NULL) {
@@ -1079,6 +1034,55 @@
}
}
+bool NuPlayer::audioDecoderStillNeeded() {
+ // Audio decoder is no longer needed if it's in shut/shutting down status.
+ return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
+}
+
+void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
+ // We wait for both the decoder flush and the renderer flush to complete
+ // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
+
+ mFlushComplete[audio][isDecoder] = true;
+ if (!mFlushComplete[audio][!isDecoder]) {
+ return;
+ }
+
+ FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
+ switch (*state) {
+ case FLUSHING_DECODER:
+ {
+ *state = FLUSHED;
+
+ if (!audio) {
+ mVideoLateByUs = 0;
+ }
+ break;
+ }
+
+ case FLUSHING_DECODER_SHUTDOWN:
+ {
+ *state = SHUTTING_DOWN_DECODER;
+
+ ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
+ if (!audio) {
+ mVideoLateByUs = 0;
+ // Widevine source reads must stop before releasing the video decoder.
+ if (mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
+ mSource->stop();
+ }
+ }
+ getDecoder(audio)->initiateShutdown();
+ break;
+ }
+
+ default:
+ // decoder flush completes only occur in a flushing state.
+ LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
+ break;
+ }
+}
+
void NuPlayer::finishFlushIfPossible() {
if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
&& mFlushingAudio != SHUT_DOWN) {
@@ -1111,6 +1115,8 @@
mFlushingAudio = NONE;
mFlushingVideo = NONE;
+ clearFlushComplete();
+
processDeferredActions();
}
@@ -1715,6 +1721,8 @@
FlushStatus newStatus =
needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
+ mFlushComplete[audio][false /* isDecoder */] = false;
+ mFlushComplete[audio][true /* isDecoder */] = false;
if (audio) {
ALOGE_IF(mFlushingAudio != NONE,
"audio flushDecoder() is called in state %d", mFlushingAudio);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 8fa7269..1b9a756 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -164,6 +164,9 @@
// notion of time has changed.
bool mTimeDiscontinuityPending;
+ // Status of flush responses from the decoder and renderer.
+ bool mFlushComplete[2][2];
+
// Used by feedDecoderInputData to aggregate small buffers into
// one large buffer.
sp<ABuffer> mPendingAudioAccessUnit;
@@ -187,6 +190,13 @@
return audio ? mAudioDecoder : mVideoDecoder;
}
+ inline void clearFlushComplete() {
+ mFlushComplete[0][0] = false;
+ mFlushComplete[0][1] = false;
+ mFlushComplete[1][0] = false;
+ mFlushComplete[1][1] = false;
+ }
+
void openAudioSink(const sp<AMessage> &format, bool offloadOnly);
void closeAudioSink();
@@ -201,14 +211,15 @@
void notifyListener(int msg, int ext1, int ext2, const Parcel *in = NULL);
+ void handleFlushComplete(bool audio, bool isDecoder);
void finishFlushIfPossible();
+ bool audioDecoderStillNeeded();
+
void flushDecoder(
bool audio, bool needShutdown, const sp<AMessage> &newFormat = NULL);
void updateDecoderFormatWithoutFlush(bool audio, const sp<AMessage> &format);
- static bool IsFlushingState(FlushStatus state, bool *needShutdown = NULL);
-
void postScanSources();
void schedulePollDuration();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 1a01d52..c57955d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -582,7 +582,7 @@
}
void NuPlayerDriver::notifyResetComplete() {
- ALOGI("notifyResetComplete(%p)", this);
+ ALOGD("notifyResetComplete(%p)", this);
Mutex::Autolock autoLock(mLock);
CHECK_EQ(mState, STATE_RESET_IN_PROGRESS);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index b6ac2a0..b693625 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -421,7 +421,8 @@
mMaxPtsGapUs(-1ll),
mTimePerFrameUs(-1ll),
mTimePerCaptureUs(-1ll),
- mCreateInputBuffersSuspended(false) {
+ mCreateInputBuffersSuspended(false),
+ mTunneled(false) {
mUninitializedState = new UninitializedState(this);
mLoadedState = new LoadedState(this);
mLoadedToIdleState = new LoadedToIdleState(this);
@@ -697,6 +698,21 @@
return err;
}
+ // Exits here for tunneled video playback codecs -- i.e. skips native window
+ // buffer allocation step as this is managed by the tunneled OMX omponent
+ // itself and explicitly sets def.nBufferCountActual to 0.
+ if (mTunneled) {
+ ALOGV("Tunneled Playback: skipping native window buffer allocation.");
+ def.nBufferCountActual = 0;
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
+ *minUndequeuedBuffers = 0;
+ *bufferCount = 0;
+ *bufferSize = 0;
+ return err;
+ }
+
*minUndequeuedBuffers = 0;
err = mNativeWindow->query(
mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
@@ -904,6 +920,13 @@
ANativeWindowBuffer *buf;
int fenceFd = -1;
CHECK(mNativeWindow.get() != NULL);
+
+ if (mTunneled) {
+ ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
+ " video playback mode mode!");
+ return NULL;
+ }
+
if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
ALOGE("dequeueBuffer failed.");
return NULL;
@@ -1245,6 +1268,7 @@
if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
tunneled != 0) {
ALOGI("Configuring TUNNELED video playback.");
+ mTunneled = true;
int32_t audioHwSync = 0;
if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
@@ -1259,6 +1283,9 @@
inputFormat->setInt32("adaptive-playback", true);
} else {
+ ALOGV("Configuring CPU controlled video playback.");
+ mTunneled = false;
+
// Always try to enable dynamic output buffers on native surface
err = mOMX->storeMetaDataInBuffers(
mNode, kPortIndexOutput, OMX_TRUE);
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 1b6eac4..40925fd 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -654,6 +654,7 @@
inHeader->nOffset += inBufferUsedLength;
AAC_DECODER_ERROR decoderErr;
+ int numLoops = 0;
do {
if (outputDelayRingBufferSpaceLeft() <
(mStreamInfo->frameSize * mStreamInfo->numChannels)) {
@@ -661,20 +662,19 @@
break;
}
- int numconsumed = mStreamInfo->numTotalBytes + mStreamInfo->numBadBytes;
+ int numConsumed = mStreamInfo->numTotalBytes;
decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
tmpOutBuffer,
2048 * MAX_CHANNEL_COUNT,
0 /* flags */);
- numconsumed = (mStreamInfo->numTotalBytes + mStreamInfo->numBadBytes) - numconsumed;
- if (numconsumed != 0) {
- mDecodedSizes.add(numconsumed);
- }
+ numConsumed = mStreamInfo->numTotalBytes - numConsumed;
+ numLoops++;
if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
break;
}
+ mDecodedSizes.add(numConsumed);
if (decoderErr != AAC_DEC_OK) {
ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
@@ -716,6 +716,15 @@
aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
+ // After an error, replace the last entry in mBufferSizes with the sum of the
+ // last <numLoops> entries from mDecodedSizes to resynchronize the in/out lists.
+ mBufferSizes.pop();
+ int n = 0;
+ for (int i = 0; i < numLoops; i++) {
+ n += mDecodedSizes.itemAt(mDecodedSizes.size() - numLoops + i);
+ }
+ mBufferSizes.add(n);
+
// fall through
}