CCodecBuffers: fix null buffer PCM conversion
EOS w/ null buffer may be queued, and it needs to go through the
conversion processing to keep the converted format.
Bug: 228576052
Test: atest ccodec_unit_test
Change-Id: I8503132a779aae6bc652ea030d29fc466c8a31a9
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 57c70c1..0f4a8d8 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -208,7 +208,7 @@
bool OutputBuffers::convert(
const std::shared_ptr<C2Buffer> &src, sp<Codec2Buffer> *dst) {
- if (!src || src->data().type() != C2BufferData::LINEAR) {
+ if (src && src->data().type() != C2BufferData::LINEAR) {
return false;
}
int32_t configEncoding = kAudioEncodingPcm16bit;
@@ -237,7 +237,12 @@
if (!mDataConverter) {
return false;
}
- sp<MediaCodecBuffer> srcBuffer = ConstLinearBlockBuffer::Allocate(mFormat, src);
+ sp<MediaCodecBuffer> srcBuffer;
+ if (src) {
+ srcBuffer = ConstLinearBlockBuffer::Allocate(mFormat, src);
+ } else {
+ srcBuffer = new MediaCodecBuffer(mFormat, new ABuffer(0));
+ }
if (!srcBuffer) {
return false;
}
@@ -1259,8 +1264,8 @@
if (newBuffer == nullptr) {
return NO_MEMORY;
}
+ newBuffer->setFormat(mFormat);
}
- newBuffer->setFormat(mFormat);
*index = mImpl.assignSlot(newBuffer);
handleImageData(newBuffer);
*clientBuffer = newBuffer;
diff --git a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
index 41e4fff..a471291 100644
--- a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
+++ b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
@@ -861,4 +861,57 @@
+ std::to_string(std::get<3>(info.param));
});
+TEST(LinearOutputBuffersTest, PcmConvertFormat) {
+ // Prepare LinearOutputBuffers
+ std::shared_ptr<LinearOutputBuffers> buffers =
+ std::make_shared<LinearOutputBuffers>("test");
+ sp<AMessage> format{new AMessage};
+ format->setInt32(KEY_CHANNEL_COUNT, 1);
+ format->setInt32(KEY_SAMPLE_RATE, 8000);
+ format->setInt32(KEY_PCM_ENCODING, kAudioEncodingPcmFloat);
+ format->setInt32("android._config-pcm-encoding", kAudioEncodingPcm16bit);
+ format->setInt32("android._codec-pcm-encoding", kAudioEncodingPcmFloat);
+ buffers->setFormat(format);
+
+ // Prepare a linear C2Buffer
+ std::shared_ptr<C2BlockPool> pool;
+ ASSERT_EQ(OK, GetCodec2BlockPool(C2BlockPool::BASIC_LINEAR, nullptr, &pool));
+
+ std::shared_ptr<C2LinearBlock> block;
+ ASSERT_EQ(OK, pool->fetchLinearBlock(
+ 1024, C2MemoryUsage{C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block));
+ std::shared_ptr<C2Buffer> c2Buffer =
+ C2Buffer::CreateLinearBuffer(block->share(0, 1024, C2Fence()));
+
+ // Test regular buffer convert
+ size_t index;
+ sp<MediaCodecBuffer> clientBuffer;
+ ASSERT_EQ(OK, buffers->registerBuffer(c2Buffer, &index, &clientBuffer));
+ int32_t pcmEncoding = 0;
+ ASSERT_TRUE(clientBuffer->format()->findInt32(KEY_PCM_ENCODING, &pcmEncoding));
+ EXPECT_EQ(kAudioEncodingPcm16bit, pcmEncoding);
+ ASSERT_TRUE(buffers->releaseBuffer(clientBuffer, &c2Buffer));
+
+ // Test null buffer convert
+ ASSERT_EQ(OK, buffers->registerBuffer(nullptr, &index, &clientBuffer));
+ ASSERT_TRUE(clientBuffer->format()->findInt32(KEY_PCM_ENCODING, &pcmEncoding));
+ EXPECT_EQ(kAudioEncodingPcm16bit, pcmEncoding);
+ ASSERT_TRUE(buffers->releaseBuffer(clientBuffer, &c2Buffer));
+
+ // Do the same test in the array mode
+ std::shared_ptr<OutputBuffersArray> array = buffers->toArrayMode(8);
+
+ // Test regular buffer convert
+ ASSERT_EQ(OK, buffers->registerBuffer(c2Buffer, &index, &clientBuffer));
+ ASSERT_TRUE(clientBuffer->format()->findInt32(KEY_PCM_ENCODING, &pcmEncoding));
+ EXPECT_EQ(kAudioEncodingPcm16bit, pcmEncoding);
+ ASSERT_TRUE(buffers->releaseBuffer(clientBuffer, &c2Buffer));
+
+ // Test null buffer convert
+ ASSERT_EQ(OK, buffers->registerBuffer(nullptr, &index, &clientBuffer));
+ ASSERT_TRUE(clientBuffer->format()->findInt32(KEY_PCM_ENCODING, &pcmEncoding));
+ EXPECT_EQ(kAudioEncodingPcm16bit, pcmEncoding);
+ ASSERT_TRUE(buffers->releaseBuffer(clientBuffer, &c2Buffer));
+}
+
} // namespace android