Merge "GenericSource: support track (de)selection" into lmp-dev
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 142cb90..2aa8a72 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -61,6 +61,9 @@
OUTPUT_FORMAT_AAC_ADIF = 5,
OUTPUT_FORMAT_AAC_ADTS = 6,
+ OUTPUT_FORMAT_AUDIO_ONLY_END = 7, // Used in validating the output format. Should be the
+ // at the end of the audio only output formats.
+
/* Stream over a socket, limited to a single stream */
OUTPUT_FORMAT_RTP_AVP = 7,
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 3ef6b9a..26ce5f9 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -63,8 +63,8 @@
int32_t getTimeScale() const { return mTimeScale; }
status_t setGeoData(int latitudex10000, int longitudex10000);
- void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
- int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
+ virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
+ virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
protected:
virtual ~MPEG4Writer();
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 3f7508b..26a0963 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -30,6 +30,7 @@
struct AString;
struct CodecBase;
struct ICrypto;
+struct IBatteryStats;
struct SoftwareRenderer;
struct Surface;
@@ -51,6 +52,8 @@
CB_OUTPUT_FORMAT_CHANGED = 4,
};
+ struct BatteryNotifier;
+
static sp<MediaCodec> CreateByType(
const sp<ALooper> &looper, const char *mime, bool encoder);
@@ -225,6 +228,9 @@
sp<AMessage> mInputFormat;
sp<AMessage> mCallback;
+ bool mBatteryStatNotified;
+ bool mIsVideo;
+
// initial create parameters
AString mInitName;
bool mInitNameIsType;
@@ -294,6 +300,7 @@
status_t onSetParameters(const sp<AMessage> ¶ms);
status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &buffer);
+ void updateBatteryStat();
DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};
diff --git a/include/media/stagefright/MediaWriter.h b/include/media/stagefright/MediaWriter.h
index 5cc8dcf..e27ea1d 100644
--- a/include/media/stagefright/MediaWriter.h
+++ b/include/media/stagefright/MediaWriter.h
@@ -48,6 +48,9 @@
return OK;
}
+ virtual void setStartTimeOffsetMs(int ms) {}
+ virtual int32_t getStartTimeOffsetMs() const { return 0; }
+
protected:
virtual ~MediaWriter() {}
int64_t mMaxFileSizeLimitBytes;
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index c8192e9..1952b86 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -186,8 +186,11 @@
ALOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
return INVALID_OPERATION;
}
- if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START && of != OUTPUT_FORMAT_RTP_AVP && of != OUTPUT_FORMAT_MPEG2TS) { //first non-video output format
- ALOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of);
+ if (mIsVideoSourceSet
+ && of >= OUTPUT_FORMAT_AUDIO_ONLY_START //first non-video output format
+ && of < OUTPUT_FORMAT_AUDIO_ONLY_END) {
+ ALOGE("output format (%d) is meant for audio recording only"
+ " and incompatible with video recording", of);
return INVALID_OPERATION;
}
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 48d44c1..0c7e590c 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -49,6 +49,7 @@
$(TOP)/frameworks/av/media/libstagefright/include \
$(TOP)/frameworks/av/media/libstagefright/rtsp \
$(TOP)/frameworks/av/media/libstagefright/wifi-display \
+ $(TOP)/frameworks/av/media/libstagefright/webm \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/external/tremolo/Tremolo \
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index bfc075c..217b248 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -19,6 +19,7 @@
#include <inttypes.h>
#include <utils/Log.h>
+#include "WebmWriter.h"
#include "StagefrightRecorder.h"
#include <binder/IPCThreadState.h>
@@ -764,7 +765,8 @@
case OUTPUT_FORMAT_DEFAULT:
case OUTPUT_FORMAT_THREE_GPP:
case OUTPUT_FORMAT_MPEG_4:
- status = setupMPEG4Recording();
+ case OUTPUT_FORMAT_WEBM:
+ status = setupMPEG4orWEBMRecording();
break;
case OUTPUT_FORMAT_AMR_NB:
@@ -826,9 +828,14 @@
case OUTPUT_FORMAT_DEFAULT:
case OUTPUT_FORMAT_THREE_GPP:
case OUTPUT_FORMAT_MPEG_4:
+ case OUTPUT_FORMAT_WEBM:
{
+ bool isMPEG4 = true;
+ if (mOutputFormat == OUTPUT_FORMAT_WEBM) {
+ isMPEG4 = false;
+ }
sp<MetaData> meta = new MetaData;
- setupMPEG4MetaData(&meta);
+ setupMPEG4orWEBMMetaData(&meta);
status = mWriter->start(meta.get());
break;
}
@@ -1538,12 +1545,17 @@
return OK;
}
-status_t StagefrightRecorder::setupMPEG4Recording() {
+status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {
mWriter.clear();
mTotalBitRate = 0;
status_t err = OK;
- sp<MediaWriter> writer = new MPEG4Writer(mOutputFd);
+ sp<MediaWriter> writer;
+ if (mOutputFormat == OUTPUT_FORMAT_MPEG_4) {
+ writer = new MPEG4Writer(mOutputFd);
+ } else {
+ writer = new WebmWriter(mOutputFd);
+ }
if (mVideoSource < VIDEO_SOURCE_LIST_END) {
@@ -1563,22 +1575,25 @@
mTotalBitRate += mVideoBitRate;
}
- // Audio source is added at the end if it exists.
- // This help make sure that the "recoding" sound is suppressed for
- // camcorder applications in the recorded files.
- if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_CNT)) {
- err = setupAudioEncoder(writer);
- if (err != OK) return err;
- mTotalBitRate += mAudioBitRate;
- }
+ if (mOutputFormat == OUTPUT_FORMAT_MPEG_4) {
+ // Audio source is added at the end if it exists.
+ // This help make sure that the "recoding" sound is suppressed for
+ // camcorder applications in the recorded files.
+ // TODO Audio source is currently unsupported for webm output; vorbis encoder needed.
+ if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_CNT)) {
+ err = setupAudioEncoder(writer);
+ if (err != OK) return err;
+ mTotalBitRate += mAudioBitRate;
+ }
- if (mInterleaveDurationUs > 0) {
- reinterpret_cast<MPEG4Writer *>(writer.get())->
- setInterleaveDuration(mInterleaveDurationUs);
- }
- if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) {
- reinterpret_cast<MPEG4Writer *>(writer.get())->
- setGeoData(mLatitudex10000, mLongitudex10000);
+ if (mInterleaveDurationUs > 0) {
+ reinterpret_cast<MPEG4Writer *>(writer.get())->
+ setInterleaveDuration(mInterleaveDurationUs);
+ }
+ if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) {
+ reinterpret_cast<MPEG4Writer *>(writer.get())->
+ setGeoData(mLatitudex10000, mLongitudex10000);
+ }
}
if (mMaxFileDurationUs != 0) {
writer->setMaxFileDuration(mMaxFileDurationUs);
@@ -1586,7 +1601,6 @@
if (mMaxFileSizeBytes != 0) {
writer->setMaxFileSize(mMaxFileSizeBytes);
}
-
if (mVideoSource == VIDEO_SOURCE_DEFAULT
|| mVideoSource == VIDEO_SOURCE_CAMERA) {
mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId);
@@ -1595,8 +1609,7 @@
mStartTimeOffsetMs = 200;
}
if (mStartTimeOffsetMs > 0) {
- reinterpret_cast<MPEG4Writer *>(writer.get())->
- setStartTimeOffsetMs(mStartTimeOffsetMs);
+ writer->setStartTimeOffsetMs(mStartTimeOffsetMs);
}
writer->setListener(mListener);
@@ -1604,20 +1617,22 @@
return OK;
}
-void StagefrightRecorder::setupMPEG4MetaData(sp<MetaData> *meta) {
+void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) {
int64_t startTimeUs = systemTime() / 1000;
(*meta)->setInt64(kKeyTime, startTimeUs);
(*meta)->setInt32(kKeyFileType, mOutputFormat);
(*meta)->setInt32(kKeyBitRate, mTotalBitRate);
- (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
if (mMovieTimeScale > 0) {
(*meta)->setInt32(kKeyTimeScale, mMovieTimeScale);
}
- if (mTrackEveryTimeDurationUs > 0) {
- (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
- }
- if (mRotationDegrees != 0) {
- (*meta)->setInt32(kKeyRotation, mRotationDegrees);
+ if (mOutputFormat == OUTPUT_FORMAT_MPEG_4) {
+ (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
+ if (mTrackEveryTimeDurationUs > 0) {
+ (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
+ }
+ if (mRotationDegrees != 0) {
+ (*meta)->setInt32(kKeyRotation, mRotationDegrees);
+ }
}
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 377d168..9062f30 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -128,8 +128,8 @@
sp<ALooper> mLooper;
status_t prepareInternal();
- status_t setupMPEG4Recording();
- void setupMPEG4MetaData(sp<MetaData> *meta);
+ status_t setupMPEG4orWEBMRecording();
+ void setupMPEG4orWEBMMetaData(sp<MetaData> *meta);
status_t setupAMRRecording();
status_t setupAACRecording();
status_t setupRawAudioRecording();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 6ccd27a..fa6b1e5 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -754,6 +754,7 @@
offloadInfo.has_video = (mVideoDecoder != NULL);
offloadInfo.is_streaming = true;
+ ALOGV("try to open AudioSink in offload mode");
err = mAudioSink->open(
sampleRate,
numChannels,
@@ -793,6 +794,7 @@
if (!mOffloadAudio) {
flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+ ALOGV("open AudioSink in NON-offload mode");
CHECK_EQ(mAudioSink->open(
sampleRate,
numChannels,
@@ -940,6 +942,21 @@
} else if (what == Renderer::kWhatMediaRenderingStart) {
ALOGV("media rendering started");
notifyListener(MEDIA_STARTED, 0, 0);
+ } else if (what == Renderer::kWhatAudioOffloadTearDown) {
+ ALOGV("Tear down audio offload, fall back to s/w path");
+ int64_t positionUs;
+ CHECK(msg->findInt64("positionUs", &positionUs));
+ mAudioSink->close();
+ mAudioDecoder.clear();
+ mRenderer->flush(true /* audio */);
+ if (mVideoDecoder != NULL) {
+ mRenderer->flush(false /* audio */);
+ }
+ mRenderer->signalDisableOffloadAudio();
+ mOffloadAudio = false;
+
+ performSeek(positionUs);
+ instantiateDecoder(true /* audio */, &mAudioDecoder);
}
break;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 8592ec2..3640038 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -223,6 +223,12 @@
break;
}
+ case kWhatAudioOffloadTearDown:
+ {
+ onAudioOffloadTearDown();
+ break;
+ }
+
default:
TRESPASS();
break;
@@ -294,7 +300,7 @@
case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:
{
- // TODO: send this to player.
+ me->notifyAudioOffloadTearDown();
break;
}
}
@@ -582,6 +588,10 @@
notify->post();
}
+void NuPlayer::Renderer::notifyAudioOffloadTearDown() {
+ (new AMessage(kWhatAudioOffloadTearDown, id()))->post();
+}
+
void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
int32_t audio;
CHECK(msg->findInt32("audio", &audio));
@@ -814,6 +824,7 @@
void NuPlayer::Renderer::onDisableOffloadAudio() {
Mutex::Autolock autoLock(mLock);
mFlags &= ~FLAG_OFFLOAD_AUDIO;
+ ++mAudioQueueGeneration;
}
void NuPlayer::Renderer::notifyPosition() {
@@ -880,5 +891,21 @@
}
}
+void NuPlayer::Renderer::onAudioOffloadTearDown() {
+ uint32_t numFramesPlayed;
+ CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
+
+ int64_t currentPositionUs = mFirstAudioTimeUs
+ + (numFramesPlayed * mAudioSink->msecsPerFrame()) * 1000ll;
+
+ mAudioSink->stop();
+ mAudioSink->flush();
+
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatAudioOffloadTearDown);
+ notify->setInt64("positionUs", currentPositionUs);
+ notify->post();
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 6e86a8f..1cba1a0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -62,6 +62,7 @@
kWhatPosition = 'posi',
kWhatVideoRenderingStart = 'vdrd',
kWhatMediaRenderingStart = 'mdrd',
+ kWhatAudioOffloadTearDown = 'aOTD',
};
protected:
@@ -143,12 +144,14 @@
void onDisableOffloadAudio();
void onPause();
void onResume();
+ void onAudioOffloadTearDown();
void notifyEOS(bool audio, status_t finalResult);
void notifyFlushComplete(bool audio);
void notifyPosition();
void notifyVideoLateBy(int64_t lateByUs);
void notifyVideoRenderingStart();
+ void notifyAudioOffloadTearDown();
void flushQueue(List<QueueEntry> *queue);
bool dropBufferWhileFlushing(bool audio, const sp<AMessage> &msg);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 7a9cb0b..15e062e 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -16,13 +16,13 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaCodec"
-#include <utils/Log.h>
#include <inttypes.h>
-#include <media/stagefright/MediaCodec.h>
-
+#include "include/avc_utils.h"
#include "include/SoftwareRenderer.h"
+#include <binder/IBatteryStats.h>
+#include <binder/IServiceManager.h>
#include <gui/Surface.h>
#include <media/ICrypto.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -32,16 +32,85 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/ACodec.h>
#include <media/stagefright/BufferProducerWrapper.h>
+#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/NativeWindowWrapper.h>
-
-#include "include/avc_utils.h"
+#include <private/android_filesystem_config.h>
+#include <utils/Log.h>
+#include <utils/Singleton.h>
namespace android {
+struct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
+ BatteryNotifier();
+
+ void noteStartVideo();
+ void noteStopVideo();
+ void noteStartAudio();
+ void noteStopAudio();
+
+private:
+ int32_t mVideoRefCount;
+ int32_t mAudioRefCount;
+ sp<IBatteryStats> mBatteryStatService;
+};
+
+ANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
+
+MediaCodec::BatteryNotifier::BatteryNotifier() :
+ mVideoRefCount(0),
+ mAudioRefCount(0) {
+ // get battery service
+ const sp<IServiceManager> sm(defaultServiceManager());
+ if (sm != NULL) {
+ const String16 name("batterystats");
+ mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
+ if (mBatteryStatService == NULL) {
+ ALOGE("batterystats service unavailable!");
+ }
+ }
+}
+
+void MediaCodec::BatteryNotifier::noteStartVideo() {
+ if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
+ mBatteryStatService->noteStartVideo(AID_MEDIA);
+ }
+ mVideoRefCount++;
+}
+
+void MediaCodec::BatteryNotifier::noteStopVideo() {
+ if (mVideoRefCount == 0) {
+ ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
+ return;
+ }
+
+ mVideoRefCount--;
+ if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
+ mBatteryStatService->noteStopVideo(AID_MEDIA);
+ }
+}
+
+void MediaCodec::BatteryNotifier::noteStartAudio() {
+ if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
+ mBatteryStatService->noteStartAudio(AID_MEDIA);
+ }
+ mAudioRefCount++;
+}
+
+void MediaCodec::BatteryNotifier::noteStopAudio() {
+ if (mAudioRefCount == 0) {
+ ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
+ return;
+ }
+
+ mAudioRefCount--;
+ if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
+ mBatteryStatService->noteStopAudio(AID_MEDIA);
+ }
+}
// static
sp<MediaCodec> MediaCodec::CreateByType(
const sp<ALooper> &looper, const char *mime, bool encoder) {
@@ -71,6 +140,8 @@
mReplyID(0),
mFlags(0),
mSoftRenderer(NULL),
+ mBatteryStatNotified(false),
+ mIsVideo(false),
mDequeueInputTimeoutGeneration(0),
mDequeueInputReplyID(0),
mDequeueOutputTimeoutGeneration(0),
@@ -756,7 +827,6 @@
case CodecBase::kWhatComponentConfigured:
{
CHECK_EQ(mState, CONFIGURING);
- setState(CONFIGURED);
// reset input surface flag
mHaveInputSurface = false;
@@ -764,6 +834,7 @@
CHECK(msg->findMessage("input-format", &mInputFormat));
CHECK(msg->findMessage("output-format", &mOutputFormat));
+ setState(CONFIGURED);
(new AMessage)->postReply(mReplyID);
break;
}
@@ -1620,6 +1691,8 @@
mState = newState;
cancelPendingDequeueOperations();
+
+ updateBatteryStat();
}
void MediaCodec::returnBuffersToCodec() {
@@ -2054,4 +2127,34 @@
return OK;
}
+void MediaCodec::updateBatteryStat() {
+ if (mState == CONFIGURED && !mBatteryStatNotified) {
+ AString mime;
+ CHECK(mOutputFormat != NULL &&
+ mOutputFormat->findString("mime", &mime));
+
+ mIsVideo = mime.startsWithIgnoreCase("video/");
+
+ BatteryNotifier& notifier(BatteryNotifier::getInstance());
+
+ if (mIsVideo) {
+ notifier.noteStartVideo();
+ } else {
+ notifier.noteStartAudio();
+ }
+
+ mBatteryStatNotified = true;
+ } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
+ BatteryNotifier& notifier(BatteryNotifier::getInstance());
+
+ if (mIsVideo) {
+ notifier.noteStopVideo();
+ } else {
+ notifier.noteStopAudio();
+ }
+
+ mBatteryStatNotified = false;
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/webm/WebmWriter.h b/media/libstagefright/webm/WebmWriter.h
index 529dec8..36b6965 100644
--- a/media/libstagefright/webm/WebmWriter.h
+++ b/media/libstagefright/webm/WebmWriter.h
@@ -41,14 +41,14 @@
~WebmWriter() { reset(); }
- status_t addSource(const sp<MediaSource> &source);
- status_t start(MetaData *param = NULL);
- status_t stop();
- status_t pause();
- bool reachedEOS();
+ virtual status_t addSource(const sp<MediaSource> &source);
+ virtual status_t start(MetaData *param = NULL);
+ virtual status_t stop();
+ virtual status_t pause();
+ virtual bool reachedEOS();
- void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
- int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
+ virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
+ virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
private:
int mFd;
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index cca1b34..8783ec9 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -3833,6 +3833,11 @@
if (!deviceList.isEmpty()) {
struct audio_patch patch;
inputDesc->toAudioPortConfig(&patch.sinks[0]);
+ // AUDIO_SOURCE_HOTWORD is for internal use only:
+ // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
+ if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD) {
+ patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
+ }
patch.num_sinks = 1;
//only one input device for now
deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
@@ -5316,7 +5321,9 @@
const audio_format_t AudioPolicyManager::AudioPort::sPcmFormatCompareTable[] = {
AUDIO_FORMAT_DEFAULT,
AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_FORMAT_PCM_8_24_BIT,
AUDIO_FORMAT_PCM_24_BIT_PACKED,
+ AUDIO_FORMAT_PCM_32_BIT,
};
int AudioPolicyManager::AudioPort::compareFormats(audio_format_t format1,
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 1642896..8075515 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -825,6 +825,7 @@
}
outputStreams.push(getZslStreamId());
} else {
+ mZslProcessor->clearZslQueue();
mZslProcessor->deleteStream();
}
@@ -906,6 +907,13 @@
ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
}
+ // Clean up recording stream
+ res = mStreamingProcessor->deleteRecordingStream();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Unable to delete recording stream before "
+ "stop preview: %s (%d)",
+ __FUNCTION__, mCameraId, strerror(-res), res);
+ }
// no break
case Parameters::WAITING_FOR_PREVIEW_WINDOW: {
SharedParameters::Lock l(mParameters);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 3004d3e..9d36bfa 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1794,8 +1794,9 @@
return;
}
isPartialResult = (result->partial_result < mNumPartialResults);
- request.partialResult.collectedResult.append(
- result->result);
+ if (isPartialResult) {
+ request.partialResult.collectedResult.append(result->result);
+ }
} else {
camera_metadata_ro_entry_t partialResultEntry;
res = find_camera_metadata_ro_entry(result->result,