C2SoftOpusEnc: CleanUp output allocations for opus encoder
Bug: 332052537
Test: atest android.mediav2.cts.CodecEncoderTest
Test: atest android.mediav2.cts.AudioEncoderTest
Test: atest android.mediav2.cts.CodecEncoderMultiAccessUnitTest
Test: atest android.mediav2.cts.CodecEncoderBlockModelMultiAccessUnitTest
Change-Id: I9a1859f976b70babb58e794ef0811d3e667f4727
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index cdc3be0..40bb26e 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -29,7 +29,6 @@
#include <opus_multistream.h>
}
-#define DEFAULT_FRAME_DURATION_MS 20
namespace android {
namespace {
@@ -38,7 +37,6 @@
} // namespace
-static const int kMaxNumChannelsSupported = 2;
class C2SoftOpusEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
public:
@@ -248,10 +246,11 @@
mAnchorTimeStamp = 0;
mProcessedSamples = 0;
mFilledLen = 0;
- mFrameDurationMs = DEFAULT_FRAME_DURATION_MS;
+ mFrameDurationMs = kDefaultFrameDurationMs;
if (!mInputBufferPcm16) {
+ size_t frameSize = (mFrameDurationMs * kMaxSampleRateSupported) / 1000;
mInputBufferPcm16 =
- (int16_t*)malloc(kFrameSize * kMaxNumChannels * sizeof(int16_t));
+ (int16_t*)malloc(frameSize * kMaxNumChannelsSupported * sizeof(int16_t));
}
if (!mInputBufferPcm16) return C2_NO_MEMORY;
@@ -368,7 +367,9 @@
}
C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
- err = pool->fetchLinearBlock(kMaxPayload, usage, &mOutputBlock);
+ int outCapacity =
+ kMaxPayload * ((inSize + mNumPcmBytesPerInputFrame) / mNumPcmBytesPerInputFrame);
+ err = pool->fetchLinearBlock(outCapacity, usage, &mOutputBlock);
if (err != C2_OK) {
ALOGE("fetchLinearBlock for Output failed with status %d", err);
work->result = C2_NO_MEMORY;
@@ -497,11 +498,11 @@
uint8_t* outPtr = wView.data() + mBytesEncoded;
int encodedBytes =
opus_multistream_encode(mEncoder, mInputBufferPcm16,
- mNumSamplesPerFrame, outPtr, kMaxPayload - mBytesEncoded);
+ mNumSamplesPerFrame, outPtr, outCapacity - mBytesEncoded);
ALOGV("encoded %i Opus bytes from %zu PCM bytes", encodedBytes,
processSize);
- if (encodedBytes < 0 || encodedBytes > (kMaxPayload - mBytesEncoded)) {
+ if (encodedBytes < 0 || encodedBytes > (outCapacity - mBytesEncoded)) {
ALOGE("opus_encode failed, encodedBytes : %d", encodedBytes);
mSignalledError = true;
work->result = C2_CORRUPTED;
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.h b/media/codec2/components/opus/C2SoftOpusEnc.h
index 733a6bc..2c9f5e5 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.h
+++ b/media/codec2/components/opus/C2SoftOpusEnc.h
@@ -45,12 +45,13 @@
uint32_t drainMode,
const std::shared_ptr<C2BlockPool> &pool) override;
private:
- /* OPUS_FRAMESIZE_20_MS */
- const int kFrameSize = 960;
- const int kMaxSampleRate = 48000;
- const int kMinSampleRate = 8000;
- const int kMaxPayload = (4000 * kMaxSampleRate) / kMinSampleRate;
- const int kMaxNumChannels = 8;
+ static const int kMaxNumChannelsSupported = 2;
+ static const int kMaxSampleRateSupported = 48000;
+ static const int kDefaultFrameDurationMs = 20;
+ // For a frame duration of 20ms, payload recommended size is 1276 as per
+ // https://www.opus-codec.org/docs/html_api/group__opusencoder.html.
+ // For 40ms, 60ms, .. payload size will change proportionately, 1276 x 2, 1276 x 3, ..
+ static const int kMaxPayload = 1500; // from tests/test_opus_encode.c
std::shared_ptr<IntfImpl> mIntf;
std::shared_ptr<C2LinearBlock> mOutputBlock;