libaudioprocessing: clamp application provided float audio
For security reason, float buffers provided by application must be
clamped to FLOAT_NOMINAL_RANGE_HEADROOM.
With the new all float pipeline, float are no longer clamped by their
conversion to fixed point.
This patch adds a float buffer provider that clamps float samples
as they are copied to audio pipeline.
Test: Play music, play video in chrome (opensles format float),
play float pcm audio file specially crafter with >> 1 samples.
Bug: 68099072
Change-Id: I220b436d9982bc43a75715a030efd0e6a0c79fa3
Signed-off-by: Kevin Rocard <krocard@google.com>
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index 93ed5f2..852252d 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -314,6 +314,14 @@
targetFormat,
kCopyBufferFrameCount));
requiresReconfigure = true;
+ } else if (mFormat == AUDIO_FORMAT_PCM_FLOAT) {
+ // Input and output are floats, make sure application did not provide > 3db samples
+ // that would break volume application (b/68099072)
+ // TODO: add a trusted source flag to avoid the overhead
+ mReformatBufferProvider.reset(new ClampFloatBufferProvider(
+ audio_channel_count_from_out_mask(channelMask),
+ kCopyBufferFrameCount));
+ requiresReconfigure = true;
}
if (targetFormat != mMixerInFormat) {
mPostDownmixReformatBufferProvider.reset(new ReformatBufferProvider(
diff --git a/media/libaudioprocessing/BufferProviders.cpp b/media/libaudioprocessing/BufferProviders.cpp
index e19af4a..2d9e1cb 100644
--- a/media/libaudioprocessing/BufferProviders.cpp
+++ b/media/libaudioprocessing/BufferProviders.cpp
@@ -376,6 +376,23 @@
memcpy_by_audio_format(dst, mOutputFormat, src, mInputFormat, frames * mChannelCount);
}
+ClampFloatBufferProvider::ClampFloatBufferProvider(int32_t channelCount, size_t bufferFrameCount) :
+ CopyBufferProvider(
+ channelCount * audio_bytes_per_sample(AUDIO_FORMAT_PCM_FLOAT),
+ channelCount * audio_bytes_per_sample(AUDIO_FORMAT_PCM_FLOAT),
+ bufferFrameCount),
+ mChannelCount(channelCount)
+{
+ ALOGV("ClampFloatBufferProvider(%p)(%u)", this, channelCount);
+}
+
+void ClampFloatBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
+{
+ memcpy_to_float_from_float_with_clamping((float*)dst, (const float*)src,
+ frames * mChannelCount,
+ FLOAT_NOMINAL_RANGE_HEADROOM);
+}
+
TimestretchBufferProvider::TimestretchBufferProvider(int32_t channelCount,
audio_format_t format, uint32_t sampleRate, const AudioPlaybackRate &playbackRate) :
mChannelCount(channelCount),
diff --git a/media/libmedia/include/media/BufferProviders.h b/media/libmedia/include/media/BufferProviders.h
index 9d026f6..d6a9cfb 100644
--- a/media/libmedia/include/media/BufferProviders.h
+++ b/media/libmedia/include/media/BufferProviders.h
@@ -161,6 +161,17 @@
const audio_format_t mOutputFormat;
};
+// ClampFloatBufferProvider derives from CopyBufferProvider to clamp floats inside -3db
+class ClampFloatBufferProvider : public CopyBufferProvider {
+public:
+ ClampFloatBufferProvider(int32_t channelCount,
+ size_t bufferFrameCount);
+ virtual void copyFrames(void *dst, const void *src, size_t frames);
+
+protected:
+ const uint32_t mChannelCount;
+};
+
// TimestretchBufferProvider derives from PassthruBufferProvider for time stretching
class TimestretchBufferProvider : public PassthruBufferProvider {
public: