diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 24 | ||||
-rw-r--r-- | services/audioflinger/FastMixer.cpp | 2 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 4 | ||||
-rw-r--r-- | services/audioflinger/Tracks.cpp | 2 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyManager.cpp | 20 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyService.cpp | 36 | ||||
-rw-r--r-- | services/camera/libcameraservice/api1/CameraClient.cpp | 15 | ||||
-rw-r--r-- | services/soundtrigger/SoundTriggerHwService.cpp | 58 |
8 files changed, 125 insertions, 36 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 1f77b2f..1843722 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1941,9 +1941,8 @@ sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t m TEE_SINK_NEW, // copy input using a new pipe TEE_SINK_OLD, // copy input using an existing pipe } kind; - NBAIO_Format format = Format_from_SR_C(inStream->common.get_sample_rate(&inStream->common), - audio_channel_count_from_in_mask( - inStream->common.get_channels(&inStream->common))); + NBAIO_Format format = Format_from_SR_C(halconfig.sample_rate, + audio_channel_count_from_in_mask(halconfig.channel_mask), halconfig.format); if (!mTeeSinkInputEnabled) { kind = TEE_SINK_NO; } else if (!Format_isValid(format)) { @@ -2700,24 +2699,26 @@ void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_hand // if 2 dumpsys are done within 1 second, and rotation didn't work, then discard 2nd int teeFd = open(teePath, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR); if (teeFd >= 0) { + // FIXME use libsndfile char wavHeader[44]; memcpy(wavHeader, "RIFF\0\0\0\0WAVEfmt \20\0\0\0\1\0\2\0\104\254\0\0\0\0\0\0\4\0\20\0data\0\0\0\0", sizeof(wavHeader)); NBAIO_Format format = teeSource->format(); unsigned channelCount = Format_channelCount(format); - ALOG_ASSERT(channelCount <= FCC_2); uint32_t sampleRate = Format_sampleRate(format); + size_t frameSize = Format_frameSize(format); wavHeader[22] = channelCount; // number of channels wavHeader[24] = sampleRate; // sample rate wavHeader[25] = sampleRate >> 8; - wavHeader[32] = channelCount * 2; // block alignment + wavHeader[32] = frameSize; // block alignment + wavHeader[33] = frameSize >> 8; write(teeFd, wavHeader, sizeof(wavHeader)); size_t total = 0; bool firstRead = true; +#define TEE_SINK_READ 1024 // frames per I/O operation + void *buffer = malloc(TEE_SINK_READ * frameSize); for (;;) { -#define TEE_SINK_READ 1024 - short buffer[TEE_SINK_READ * FCC_2]; size_t count = TEE_SINK_READ; ssize_t actual = teeSource->read(buffer, count, AudioBufferProvider::kInvalidPTS); @@ -2730,14 +2731,17 @@ void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_hand break; } ALOG_ASSERT(actual <= (ssize_t)count); - write(teeFd, buffer, actual * channelCount * sizeof(short)); + write(teeFd, buffer, actual * frameSize); total += actual; } + free(buffer); lseek(teeFd, (off_t) 4, SEEK_SET); - uint32_t temp = 44 + total * channelCount * sizeof(short) - 8; + uint32_t temp = 44 + total * frameSize - 8; + // FIXME not big-endian safe write(teeFd, &temp, sizeof(temp)); lseek(teeFd, (off_t) 40, SEEK_SET); - temp = total * channelCount * sizeof(short); + temp = total * frameSize; + // FIXME not big-endian safe write(teeFd, &temp, sizeof(temp)); close(teeFd); if (fd >= 0) { diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp index 9e15293..2678cbf 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -420,7 +420,7 @@ void FastMixer::onWork() // if non-NULL, then duplicate write() to this non-blocking sink NBAIO_Sink* teeSink; if ((teeSink = current->mTeeSink) != NULL) { - (void) teeSink->write(mMixerBuffer, frameCount); + (void) teeSink->write(buffer, frameCount); } // FIXME write() is non-blocking and lock-free for a properly implemented NBAIO sink, // but this code should be modified to handle both non-blocking and blocking sinks diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index f721d5c..942bff6 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -3662,6 +3662,10 @@ track_is_ready: ; // remove all the tracks that need to be... removeTracks_l(*tracksToRemove); + if (getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX) != 0) { + mEffectBufferValid = true; + } + // sink or mix buffer must be cleared if all tracks are connected to an // effect chain as in this case the mixer will not write to the sink or mix buffer // and track effects will accumulate into it diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index c5ab832..6cbab04 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -182,7 +182,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( #ifdef TEE_SINK if (mTeeSinkTrackEnabled) { - NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount); + NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount, mFormat); if (Format_isValid(pipeFormat)) { Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat); size_t numCounterOffers = 0; diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp index 06dd22c..a805923 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -1297,21 +1297,23 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; bool isSoundTrigger = false; + audio_source_t halInputSource = inputSource; if (inputSource == AUDIO_SOURCE_HOTWORD) { ssize_t index = mSoundTriggerSessions.indexOfKey(session); if (index >= 0) { input = mSoundTriggerSessions.valueFor(session); isSoundTrigger = true; ALOGV("SoundTrigger capture on session %d input %d", session, input); + } else { + halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION; } } - status_t status = mpClientInterface->openInput(profile->mModule->mHandle, &input, &config, &device, String8(""), - inputSource, + halInputSource, flags); // only accept input with the exact requested set of parameters @@ -4317,6 +4319,20 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, mpClientInterface->onAudioPatchListUpdate(); } } + + // inform all input as well + for (size_t i = 0; i < mInputs.size(); i++) { + const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i); + if (!isVirtualInputDevice(inputDescriptor->mDevice)) { + AudioParameter inputCmd = AudioParameter(); + ALOGV("%s: inform input %d of device:%d", __func__, + inputDescriptor->mIoHandle, device); + inputCmd.addInt(String8(AudioParameter::keyRouting),device); + mpClientInterface->setParameters(inputDescriptor->mIoHandle, + inputCmd.toString(), + delayMs); + } + } } // update stream volumes according to new device diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp index 7f14960..50bb8c7 100644 --- a/services/audiopolicy/AudioPolicyService.cpp +++ b/services/audiopolicy/AudioPolicyService.cpp @@ -765,7 +765,16 @@ void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& c sp<AudioCommand> command2 = mAudioCommands[i]; // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands if (command2->mTime <= command->mTime) break; - if (command2->mCommand != command->mCommand) continue; + + // create audio patch or release audio patch commands are equivalent + // with regard to filtering + if ((command->mCommand == CREATE_AUDIO_PATCH) || + (command->mCommand == RELEASE_AUDIO_PATCH)) { + if ((command2->mCommand != CREATE_AUDIO_PATCH) && + (command2->mCommand != RELEASE_AUDIO_PATCH)) { + continue; + } + } else if (command2->mCommand != command->mCommand) continue; switch (command->mCommand) { case SET_PARAMETERS: { @@ -817,6 +826,31 @@ void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& c // command status as the command is now delayed delayMs = 1; } break; + + case CREATE_AUDIO_PATCH: + case RELEASE_AUDIO_PATCH: { + audio_patch_handle_t handle; + if (command->mCommand == CREATE_AUDIO_PATCH) { + handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle; + } else { + handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle; + } + audio_patch_handle_t handle2; + if (command2->mCommand == CREATE_AUDIO_PATCH) { + handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle; + } else { + handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle; + } + if (handle != handle2) break; + ALOGV("Filtering out %s audio patch command for handle %d", + (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle); + removedCommands.add(command2); + command->mTime = command2->mTime; + // force delayMs to non 0 so that code below does not request to wait for + // command status as the command is now delayed + delayMs = 1; + } break; + case START_TONE: case STOP_TONE: default: diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index abe1235..33bdaa3 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -938,7 +938,20 @@ void CameraClient::copyFrameAndPostCopiedFrame( } previewBuffer = mPreviewBuffer; - memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size); + void* previewBufferBase = previewBuffer->base(); + void* heapBase = heap->base(); + + if (heapBase == MAP_FAILED) { + ALOGE("%s: Failed to mmap heap for preview frame.", __FUNCTION__); + mLock.unlock(); + return; + } else if (previewBufferBase == MAP_FAILED) { + ALOGE("%s: Failed to mmap preview buffer for preview frame.", __FUNCTION__); + mLock.unlock(); + return; + } + + memcpy(previewBufferBase, (uint8_t *) heapBase + offset, size); sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size); if (frame == 0) { diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp index 2502e0d..b5aaee3 100644 --- a/services/soundtrigger/SoundTriggerHwService.cpp +++ b/services/soundtrigger/SoundTriggerHwService.cpp @@ -249,7 +249,7 @@ sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent_l( event->data_offset = sizeof(struct sound_trigger_recognition_event); break; default: - return eventMemory; + return eventMemory; } size_t size = event->data_offset + event->data_size; @@ -653,7 +653,6 @@ void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& eve { ALOGV("onCallbackEvent type %d", event->mType); - AutoMutex lock(mLock); sp<IMemory> eventMemory = event->mMemory; if (eventMemory == 0 || eventMemory->pointer() == NULL) { @@ -668,34 +667,53 @@ void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& eve case CallbackEvent::TYPE_RECOGNITION: { struct sound_trigger_recognition_event *recognitionEvent = (struct sound_trigger_recognition_event *)eventMemory->pointer(); + sp<ISoundTriggerClient> client; + { + AutoMutex lock(mLock); + sp<Model> model = getModel(recognitionEvent->model); + if (model == 0) { + ALOGW("%s model == 0", __func__); + return; + } + if (model->mState != Model::STATE_ACTIVE) { + ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState); + return; + } - sp<Model> model = getModel(recognitionEvent->model); - if (model == 0) { - ALOGW("%s model == 0", __func__); - return; + recognitionEvent->capture_session = model->mCaptureSession; + model->mState = Model::STATE_IDLE; + client = mClient; } - if (model->mState != Model::STATE_ACTIVE) { - ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState); - return; + if (client != 0) { + client->onRecognitionEvent(eventMemory); } - - recognitionEvent->capture_session = model->mCaptureSession; - mClient->onRecognitionEvent(eventMemory); - model->mState = Model::STATE_IDLE; } break; case CallbackEvent::TYPE_SOUNDMODEL: { struct sound_trigger_model_event *soundmodelEvent = (struct sound_trigger_model_event *)eventMemory->pointer(); - - sp<Model> model = getModel(soundmodelEvent->model); - if (model == 0) { - ALOGW("%s model == 0", __func__); - return; + sp<ISoundTriggerClient> client; + { + AutoMutex lock(mLock); + sp<Model> model = getModel(soundmodelEvent->model); + if (model == 0) { + ALOGW("%s model == 0", __func__); + return; + } + client = mClient; + } + if (client != 0) { + client->onSoundModelEvent(eventMemory); } - mClient->onSoundModelEvent(eventMemory); } break; case CallbackEvent::TYPE_SERVICE_STATE: { - mClient->onServiceStateChange(eventMemory); + sp<ISoundTriggerClient> client; + { + AutoMutex lock(mLock); + client = mClient; + } + if (client != 0) { + client->onServiceStateChange(eventMemory); + } } break; default: LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType); |