summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/Threads.cpp19
-rw-r--r--services/audioflinger/Threads.h5
-rw-r--r--services/audioflinger/Tracks.cpp4
-rw-r--r--services/audiopolicy/AudioPolicyManager.cpp4
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.cpp114
-rw-r--r--services/camera/libcameraservice/api1/client2/JpegProcessor.cpp15
-rw-r--r--services/camera/libcameraservice/api1/client2/ZslProcessor.cpp2
7 files changed, 107 insertions, 56 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index fe258ae..66edf45 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2804,6 +2804,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
// create a MonoPipe to connect our submix to FastMixer
NBAIO_Format format = mOutputSink->format();
+ NBAIO_Format origformat = format;
// adjust format to match that of the Fast Mixer
format.mFormat = fastMixerFormat;
format.mFrameSize = audio_bytes_per_sample(format.mFormat) * format.mChannelCount;
@@ -2823,14 +2824,15 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
#ifdef TEE_SINK
if (mTeeSinkOutputEnabled) {
// create a Pipe to archive a copy of FastMixer's output for dumpsys
- Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, format);
+ Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, origformat);
+ const NBAIO_Format offers2[1] = {origformat};
numCounterOffers = 0;
- index = teeSink->negotiate(offers, 1, NULL, numCounterOffers);
+ index = teeSink->negotiate(offers2, 1, NULL, numCounterOffers);
ALOG_ASSERT(index == 0);
mTeeSink = teeSink;
PipeReader *teeSource = new PipeReader(*teeSink);
numCounterOffers = 0;
- index = teeSource->negotiate(offers, 1, NULL, numCounterOffers);
+ index = teeSource->negotiate(offers2, 1, NULL, numCounterOffers);
ALOG_ASSERT(index == 0);
mTeeSource = teeSource;
}
@@ -4053,6 +4055,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
track->mState = TrackBase::STOPPED;
}
if (track->isStopped()) {
+ if (track->mState == TrackBase::FLUSHED) {
+ flushHw_l();
+ }
track->reset();
}
tracksToRemove->add(track);
@@ -4225,6 +4230,12 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l()
}
}
+void AudioFlinger::DirectOutputThread::flushHw_l()
+{
+ if (mOutput->stream->flush != NULL)
+ mOutput->stream->flush(mOutput->stream);
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::AsyncCallbackThread::AsyncCallbackThread(
@@ -4592,7 +4603,7 @@ bool AudioFlinger::OffloadThread::waitingAsyncCallback()
void AudioFlinger::OffloadThread::flushHw_l()
{
- mOutput->stream->flush(mOutput->stream);
+ DirectOutputThread::flushHw_l();
// Flush anything still waiting in the mixbuffer
mCurrentWriteLength = 0;
mBytesRemaining = 0;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index cda8095..7d3b854 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -895,6 +895,7 @@ public:
virtual bool checkForNewParameter_l(const String8& keyValuePair,
status_t& status);
+ virtual void flushHw_l();
protected:
virtual int getTrackName_l(audio_channel_mask_t channelMask,
@@ -930,6 +931,7 @@ public:
OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
audio_io_handle_t id, uint32_t device);
virtual ~OffloadThread() {};
+ virtual void flushHw_l();
protected:
// threadLoop snippets
@@ -942,9 +944,6 @@ protected:
virtual void onAddNewTrack_l();
private:
- void flushHw_l();
-
-private:
bool mHwPaused;
bool mFlushPending;
size_t mPausedWriteLength; // length in bytes of write interrupted by pause
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 8c2bee4..b2d53cf 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -824,6 +824,10 @@ void AudioFlinger::PlaybackThread::Track::flush()
// remove from active track list, reset(), and trigger presentation complete
if (playbackThread->mActiveTracks.indexOf(this) < 0) {
reset();
+ if (thread->type() == ThreadBase::DIRECT) {
+ DirectOutputThread *t = (DirectOutputThread *)playbackThread;
+ t->flushHw_l();
+ }
}
}
// Prevent flush being lost if the track is flushed and then resumed
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index d0b990f..536987a 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -930,7 +930,9 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
sp<IOProfile> profile;
// skip direct output selection if the request can obviously be attached to a mixed output
- if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE &&
+ // and not explicitly requested
+ if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
+ audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE &&
audio_channel_count_from_out_mask(channelMask) <= 2) {
goto non_direct_output;
}
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 48ec730..3610362 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -1049,32 +1049,35 @@ status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
}
}
- if (mZslProcessor->getStreamId() != NO_STREAM) {
- ALOGV("%s: Camera %d: Clearing out zsl stream before "
- "creating recording stream", __FUNCTION__, mCameraId);
- res = mStreamingProcessor->stopStream();
- if (res != OK) {
- ALOGE("%s: Camera %d: Can't stop streaming to delete callback stream",
- __FUNCTION__, mCameraId);
- return res;
- }
- res = mDevice->waitUntilDrained();
- if (res != OK) {
- ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
- __FUNCTION__, mCameraId, strerror(-res), res);
- }
- res = mZslProcessor->clearZslQueue();
- if (res != OK) {
- ALOGE("%s: Camera %d: Can't clear zsl queue",
- __FUNCTION__, mCameraId);
- return res;
- }
- res = mZslProcessor->deleteStream();
- if (res != OK) {
- ALOGE("%s: Camera %d: Unable to delete zsl stream before "
- "record: %s (%d)", __FUNCTION__, mCameraId,
- strerror(-res), res);
- return res;
+ // On current HALs, clean up ZSL before transitioning into recording
+ if (mDeviceVersion != CAMERA_DEVICE_API_VERSION_2_0) {
+ if (mZslProcessor->getStreamId() != NO_STREAM) {
+ ALOGV("%s: Camera %d: Clearing out zsl stream before "
+ "creating recording stream", __FUNCTION__, mCameraId);
+ res = mStreamingProcessor->stopStream();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Can't stop streaming to delete callback stream",
+ __FUNCTION__, mCameraId);
+ return res;
+ }
+ res = mDevice->waitUntilDrained();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
+ __FUNCTION__, mCameraId, strerror(-res), res);
+ }
+ res = mZslProcessor->clearZslQueue();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Can't clear zsl queue",
+ __FUNCTION__, mCameraId);
+ return res;
+ }
+ res = mZslProcessor->deleteStream();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Unable to delete zsl stream before "
+ "record: %s (%d)", __FUNCTION__, mCameraId,
+ strerror(-res), res);
+ return res;
+ }
}
}
@@ -1082,34 +1085,53 @@ status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
// and we can't fail record start without stagefright asserting.
params.previewCallbackFlags = 0;
- bool recordingStreamNeedsUpdate;
- res = mStreamingProcessor->recordingStreamNeedsUpdate(params, &recordingStreamNeedsUpdate);
- if (res != OK) {
- ALOGE("%s: Camera %d: Can't query recording stream",
- __FUNCTION__, mCameraId);
- return res;
- }
-
- if (recordingStreamNeedsUpdate) {
- // Need to stop stream here so updateProcessorStream won't trigger configureStream
- // Right now camera device cannot handle configureStream failure gracefully
- // when device is streaming
- res = mStreamingProcessor->stopStream();
+ if (mDeviceVersion != CAMERA_DEVICE_API_VERSION_2_0) {
+ // For newer devices, may need to reconfigure video snapshot JPEG sizes
+ // during recording startup, so need a more complex sequence here to
+ // ensure an early stream reconfiguration doesn't happen
+ bool recordingStreamNeedsUpdate;
+ res = mStreamingProcessor->recordingStreamNeedsUpdate(params, &recordingStreamNeedsUpdate);
if (res != OK) {
- ALOGE("%s: Camera %d: Can't stop streaming to update record stream",
+ ALOGE("%s: Camera %d: Can't query recording stream",
__FUNCTION__, mCameraId);
return res;
}
- res = mDevice->waitUntilDrained();
- if (res != OK) {
- ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
- __FUNCTION__, mCameraId, strerror(-res), res);
+
+ if (recordingStreamNeedsUpdate) {
+ // Need to stop stream here so updateProcessorStream won't trigger configureStream
+ // Right now camera device cannot handle configureStream failure gracefully
+ // when device is streaming
+ res = mStreamingProcessor->stopStream();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Can't stop streaming to update record "
+ "stream", __FUNCTION__, mCameraId);
+ return res;
+ }
+ res = mDevice->waitUntilDrained();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Waiting to stop streaming failed: "
+ "%s (%d)", __FUNCTION__, mCameraId,
+ strerror(-res), res);
+ }
+
+ res = updateProcessorStream<
+ StreamingProcessor,
+ &StreamingProcessor::updateRecordingStream>(
+ mStreamingProcessor,
+ params);
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Unable to update recording stream: "
+ "%s (%d)", __FUNCTION__, mCameraId,
+ strerror(-res), res);
+ return res;
+ }
}
+ } else {
+ // Maintain call sequencing for HALv2 devices.
res = updateProcessorStream<
StreamingProcessor,
&StreamingProcessor::updateRecordingStream>(mStreamingProcessor,
- params);
-
+ params);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
index cda98be..b433781 100644
--- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
@@ -89,14 +89,27 @@ status_t JpegProcessor::updateStream(const Parameters &params) {
mCaptureConsumer->setFrameAvailableListener(this);
mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
mCaptureWindow = new Surface(producer);
+ }
+
+ // Since ashmem heaps are rounded up to page size, don't reallocate if
+ // the capture heap isn't exactly the same size as the required JPEG buffer
+ const size_t HEAP_SLACK_FACTOR = 2;
+ if (mCaptureHeap == 0 ||
+ (mCaptureHeap->getSize() < static_cast<size_t>(maxJpegSize)) ||
+ (mCaptureHeap->getSize() >
+ static_cast<size_t>(maxJpegSize) * HEAP_SLACK_FACTOR) ) {
// Create memory for API consumption
- mCaptureHeap = new MemoryHeapBase(maxJpegSize, 0, "Camera2Client::CaptureHeap");
+ mCaptureHeap.clear();
+ mCaptureHeap =
+ new MemoryHeapBase(maxJpegSize, 0, "Camera2Client::CaptureHeap");
if (mCaptureHeap->getSize() == 0) {
ALOGE("%s: Camera %d: Unable to allocate memory for capture",
__FUNCTION__, mId);
return NO_MEMORY;
}
}
+ ALOGV("%s: Camera %d: JPEG capture heap now %d bytes; requested %d bytes",
+ __FUNCTION__, mId, mCaptureHeap->getSize(), maxJpegSize);
if (mCaptureStreamId != NO_STREAM) {
// Check if stream parameters have to change
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index bb72206..8f78103 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -154,7 +154,7 @@ status_t ZslProcessor::updateStream(const Parameters &params) {
mId, strerror(-res), res);
return res;
}
- if (mDeleted || currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
+ if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
res = device->deleteReprocessStream(mZslReprocessStreamId);
if (res != OK) {