diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/Threads.cpp | 19 | ||||
-rw-r--r-- | services/audioflinger/Threads.h | 5 | ||||
-rw-r--r-- | services/audioflinger/Tracks.cpp | 4 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyManager.cpp | 4 | ||||
-rw-r--r-- | services/camera/libcameraservice/api1/Camera2Client.cpp | 114 | ||||
-rw-r--r-- | services/camera/libcameraservice/api1/client2/JpegProcessor.cpp | 15 | ||||
-rw-r--r-- | services/camera/libcameraservice/api1/client2/ZslProcessor.cpp | 2 |
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 ¶ms, 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 ¶ms, 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 ¶ms) { 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 ¶ms) { 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) { |