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 | 16 | ||||
-rw-r--r-- | services/audioflinger/Tracks.cpp | 2 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyManager.cpp | 53 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyService.cpp | 36 | ||||
-rw-r--r-- | services/camera/libcameraservice/api1/CameraClient.cpp | 15 | ||||
-rw-r--r-- | services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp | 17 |
8 files changed, 135 insertions, 30 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..97b1753 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -662,12 +662,14 @@ void AudioFlinger::ThreadBase::acquireWakeLock_l(int uid) binder, getWakeLockTag(), String16("media"), - uid); + uid, + true /* FIXME force oneway contrary to .aidl */); } else { status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, binder, getWakeLockTag(), - String16("media")); + String16("media"), + true /* FIXME force oneway contrary to .aidl */); } if (status == NO_ERROR) { mWakeLockToken = binder; @@ -687,7 +689,8 @@ void AudioFlinger::ThreadBase::releaseWakeLock_l() if (mWakeLockToken != 0) { ALOGV("releaseWakeLock_l() %s", mName); if (mPowerManager != 0) { - mPowerManager->releaseWakeLock(mWakeLockToken, 0); + mPowerManager->releaseWakeLock(mWakeLockToken, 0, + true /* FIXME force oneway contrary to .aidl */); } mWakeLockToken.clear(); } @@ -723,7 +726,8 @@ void AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<int> &uid if (mPowerManager != 0) { sp<IBinder> binder = new BBinder(); status_t status; - status = mPowerManager->updateWakeLockUids(mWakeLockToken, uids.size(), uids.array()); + status = mPowerManager->updateWakeLockUids(mWakeLockToken, uids.size(), uids.array(), + true /* FIXME force oneway contrary to .aidl */); ALOGV("acquireWakeLock_l() %s status %d", mName, status); } } @@ -3662,6 +3666,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 a805923..6446a6e 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -4634,8 +4634,15 @@ audio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device) // - one A2DP device + another device: happens with duplicated output. In this case // retain the device on the A2DP output as the other must not correspond to an active // selection if not the speaker. + // - HDMI-CEC system audio mode only output: give priority to available item in order. if (device & AUDIO_DEVICE_OUT_SPEAKER) { device = AUDIO_DEVICE_OUT_SPEAKER; + } else if (device & AUDIO_DEVICE_OUT_HDMI_ARC) { + device = AUDIO_DEVICE_OUT_HDMI_ARC; + } else if (device & AUDIO_DEVICE_OUT_AUX_LINE) { + device = AUDIO_DEVICE_OUT_AUX_LINE; + } else if (device & AUDIO_DEVICE_OUT_SPDIF) { + device = AUDIO_DEVICE_OUT_SPDIF; } else { device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); } @@ -6032,14 +6039,26 @@ uint32_t AudioPolicyManager::AudioPort::pickSamplingRate() const return 0; } + // For direct outputs, pick minimum sampling rate: this helps ensuring that the + // channel count / sampling rate combination chosen will be supported by the connected + // sink + if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && + (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { + uint32_t samplingRate = UINT_MAX; + for (size_t i = 0; i < mSamplingRates.size(); i ++) { + if ((mSamplingRates[i] < samplingRate) && (mSamplingRates[i] > 0)) { + samplingRate = mSamplingRates[i]; + } + } + return (samplingRate == UINT_MAX) ? 0 : samplingRate; + } + uint32_t samplingRate = 0; uint32_t maxRate = MAX_MIXER_SAMPLING_RATE; // For mixed output and inputs, use max mixer sampling rates. Do not // limit sampling rate otherwise - if ((mType != AUDIO_PORT_TYPE_MIX) || - ((mRole == AUDIO_PORT_ROLE_SOURCE) && - (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)))) { + if (mType != AUDIO_PORT_TYPE_MIX) { maxRate = UINT_MAX; } for (size_t i = 0; i < mSamplingRates.size(); i ++) { @@ -6056,16 +6075,35 @@ audio_channel_mask_t AudioPolicyManager::AudioPort::pickChannelMask() const if (mChannelMasks.size() == 1 && mChannelMasks[0] == 0) { return AUDIO_CHANNEL_NONE; } - audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE; + + // For direct outputs, pick minimum channel count: this helps ensuring that the + // channel count / sampling rate combination chosen will be supported by the connected + // sink + if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && + (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { + uint32_t channelCount = UINT_MAX; + for (size_t i = 0; i < mChannelMasks.size(); i ++) { + uint32_t cnlCount; + if (mUseInChannelMask) { + cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]); + } else { + cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]); + } + if ((cnlCount < channelCount) && (cnlCount > 0)) { + channelMask = mChannelMasks[i]; + channelCount = cnlCount; + } + } + return channelMask; + } + uint32_t channelCount = 0; uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT; // For mixed output and inputs, use max mixer channel count. Do not // limit channel count otherwise - if ((mType != AUDIO_PORT_TYPE_MIX) || - ((mRole == AUDIO_PORT_ROLE_SOURCE) && - (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)))) { + if (mType != AUDIO_PORT_TYPE_MIX) { maxCount = UINT_MAX; } for (size_t i = 0; i < mChannelMasks.size(); i ++) { @@ -6077,6 +6115,7 @@ audio_channel_mask_t AudioPolicyManager::AudioPort::pickChannelMask() const } if ((cnlCount > channelCount) && (cnlCount <= maxCount)) { channelMask = mChannelMasks[i]; + channelCount = cnlCount; } } return channelMask; 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/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp index cb9aca6..9849f4d 100644 --- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp +++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp @@ -445,11 +445,18 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait( if (mNewAEState) { if (!mAeInPrecapture) { // Waiting to see PRECAPTURE state - if (mAETriggerId == mTriggerId && - mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { - ALOGV("%s: Got precapture start", __FUNCTION__); - mAeInPrecapture = true; - mTimeoutCount = kMaxTimeoutsForPrecaptureEnd; + if (mAETriggerId == mTriggerId) { + if (mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { + ALOGV("%s: Got precapture start", __FUNCTION__); + mAeInPrecapture = true; + mTimeoutCount = kMaxTimeoutsForPrecaptureEnd; + } else if (mAEState == ANDROID_CONTROL_AE_STATE_CONVERGED || + mAEState == ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED) { + // It is legal to transit to CONVERGED or FLASH_REQUIRED + // directly after a trigger. + ALOGV("%s: AE is already in good state, start capture", __FUNCTION__); + return STANDARD_CAPTURE; + } } } else { // Waiting to see PRECAPTURE state end |