Skip to content
Snippets Groups Projects
Commit b9a66ded authored by Bartłomiej Grzesik's avatar Bartłomiej Grzesik
Browse files

VideoFramePool: limit the number of provided buffers

This CL moves limitation logic from C2VdaPooledBufferPool to
VideoFramePool. This will allow removal of C2VdaPooledBufferPool.

Bug: 268301611
Bug: 268305422
Bug: 270329448
Bug: 238710012
Bug: 238390060
Bug: 270331759
Bug: 238709912
Test: CtsMediaCodecTestCases
Test: CtsMediaDecoderTestCases
Test: CtsMediaV2TestCases
Test: GtsExoPlayerTestCases com.google.android.exoplayer.gts.CommonEncryptionDrmTest#cencSchemeTypeV*
Change-Id: I78abfdbcda6f9b3de2a6d5bcfd705a7028490f9b
parent cb4034b1
No related branches found
No related tags found
No related merge requests found
...@@ -91,16 +91,19 @@ std::unique_ptr<VideoFramePool> VideoFramePool::Create( ...@@ -91,16 +91,19 @@ std::unique_ptr<VideoFramePool> VideoFramePool::Create(
return nullptr; return nullptr;
} }
std::unique_ptr<VideoFramePool> pool = ::base::WrapUnique(new VideoFramePool( std::unique_ptr<VideoFramePool> pool =
std::move(blockPool), size, pixelFormat, memoryUsage, std::move(taskRunner))); ::base::WrapUnique(new VideoFramePool(std::move(blockPool), numBuffers, size,
pixelFormat, memoryUsage, std::move(taskRunner)));
if (!pool->initialize()) return nullptr; if (!pool->initialize()) return nullptr;
return pool; return pool;
} }
VideoFramePool::VideoFramePool(std::shared_ptr<C2BlockPool> blockPool, const ui::Size& size, VideoFramePool::VideoFramePool(std::shared_ptr<C2BlockPool> blockPool, const size_t maxBufferCount,
HalPixelFormat pixelFormat, C2MemoryUsage memoryUsage, const ui::Size& size, HalPixelFormat pixelFormat,
C2MemoryUsage memoryUsage,
scoped_refptr<::base::SequencedTaskRunner> taskRunner) scoped_refptr<::base::SequencedTaskRunner> taskRunner)
: mBlockPool(std::move(blockPool)), : mBlockPool(std::move(blockPool)),
mMaxBufferCount(maxBufferCount),
mSize(size), mSize(size),
mPixelFormat(pixelFormat), mPixelFormat(pixelFormat),
mMemoryUsage(memoryUsage), mMemoryUsage(memoryUsage),
...@@ -144,6 +147,18 @@ void VideoFramePool::destroyTask() { ...@@ -144,6 +147,18 @@ void VideoFramePool::destroyTask() {
mFetchWeakThisFactory.InvalidateWeakPtrs(); mFetchWeakThisFactory.InvalidateWeakPtrs();
} }
bool VideoFramePool::shouldDropBuffer(uint32_t bufferId) {
if (mBuffers.size() < mMaxBufferCount) {
return false;
}
if (mBuffers.find(bufferId) != mBuffers.end()) {
return false;
}
return true;
}
bool VideoFramePool::getVideoFrame(GetVideoFrameCB cb) { bool VideoFramePool::getVideoFrame(GetVideoFrameCB cb) {
ALOGV("%s()", __func__); ALOGV("%s()", __func__);
ALOG_ASSERT(mClientTaskRunner->RunsTasksInCurrentSequence()); ALOG_ASSERT(mClientTaskRunner->RunsTasksInCurrentSequence());
...@@ -202,6 +217,23 @@ void VideoFramePool::getVideoFrameTask() { ...@@ -202,6 +217,23 @@ void VideoFramePool::getVideoFrameTask() {
&block); &block);
} }
std::optional<uint32_t> bufferId;
if (err == C2_OK) {
bufferId = getBufferIdFromGraphicBlock(*mBlockPool, *block);
if (bufferId) {
ALOGV("%s(): Got buffer with id = %u", __func__, *bufferId);
if (shouldDropBuffer(*bufferId)) {
// We drop buffer, since we got more then needed.
ALOGV("%s(): Dropping allocated buffer with id = %u", __func__, *bufferId);
bufferId = std::nullopt;
block.reset();
err = C2_TIMED_OUT;
}
}
}
if (err == C2_TIMED_OUT || err == C2_BLOCKING) { if (err == C2_TIMED_OUT || err == C2_BLOCKING) {
ALOGV("%s(): fetchGraphicBlock() timeout, waiting %zuus (%zu retry)", __func__, sDelay, ALOGV("%s(): fetchGraphicBlock() timeout, waiting %zuus (%zu retry)", __func__, sDelay,
sNumRetries + 1); sNumRetries + 1);
...@@ -226,18 +258,12 @@ void VideoFramePool::getVideoFrameTask() { ...@@ -226,18 +258,12 @@ void VideoFramePool::getVideoFrameTask() {
ALOG_ASSERT(block != nullptr); ALOG_ASSERT(block != nullptr);
std::unique_ptr<VideoFrame> frame = VideoFrame::Create(std::move(block)); std::unique_ptr<VideoFrame> frame = VideoFrame::Create(std::move(block));
std::optional<FrameWithBlockId> frameWithBlockId; std::optional<FrameWithBlockId> frameWithBlockId;
std::optional<uint32_t> bufferId;
if (bufferId && frame) { if (bufferId && frame) {
bufferId = getBufferIdFromGraphicBlock(*mBlockPool, *block);
if (bufferId) {
ALOGV("%s(): Got buffer with id = %u", __func__, *bufferId);
}
// Only pass the frame + id pair if both have successfully been obtained. // Only pass the frame + id pair if both have successfully been obtained.
// Otherwise exit the loop so a nullopt is passed to the client. // Otherwise exit the loop so a nullopt is passed to the client.
frameWithBlockId = std::make_pair(std::move(frame), *bufferId); frameWithBlockId = std::make_pair(std::move(frame), *bufferId);
mBuffers.insert(*bufferId);
} else { } else {
ALOGE("%s(): Failed to generate VideoFrame or get the buffer id.", __func__); ALOGE("%s(): Failed to generate VideoFrame or get the buffer id.", __func__);
} }
......
...@@ -44,12 +44,13 @@ public: ...@@ -44,12 +44,13 @@ public:
private: private:
// |blockPool| is the C2BlockPool that we fetch graphic blocks from. // |blockPool| is the C2BlockPool that we fetch graphic blocks from.
// |maxBufferCount| maximum number of buffer that should should provide to client
// |size| is the resolution size of the required graphic blocks. // |size| is the resolution size of the required graphic blocks.
// |pixelFormat| is the pixel format of the required graphic blocks. // |pixelFormat| is the pixel format of the required graphic blocks.
// |isSecure| indicates the video stream is encrypted or not. // |isSecure| indicates the video stream is encrypted or not.
// All public methods and the callbacks should be run on |taskRunner|. // All public methods and the callbacks should be run on |taskRunner|.
VideoFramePool(std::shared_ptr<C2BlockPool> blockPool, const ui::Size& size, VideoFramePool(std::shared_ptr<C2BlockPool> blockPool, const size_t maxBufferCount,
HalPixelFormat pixelFormat, C2MemoryUsage memoryUsage, const ui::Size& size, HalPixelFormat pixelFormat, C2MemoryUsage memoryUsage,
scoped_refptr<::base::SequencedTaskRunner> taskRunner); scoped_refptr<::base::SequencedTaskRunner> taskRunner);
bool initialize(); bool initialize();
void destroyTask(); void destroyTask();
...@@ -59,6 +60,9 @@ private: ...@@ -59,6 +60,9 @@ private:
void getVideoFrameTask(); void getVideoFrameTask();
void onVideoFrameReady(std::optional<FrameWithBlockId> frameWithBlockId); void onVideoFrameReady(std::optional<FrameWithBlockId> frameWithBlockId);
// Returns true if a buffer shall not be handed to client.
bool shouldDropBuffer(uint32_t bufferId);
// Ask |blockPool| to allocate the specified number of buffers. // Ask |blockPool| to allocate the specified number of buffers.
// |bufferCount| is the number of requested buffers. // |bufferCount| is the number of requested buffers.
static c2_status_t requestNewBufferSet(C2BlockPool& blockPool, int32_t bufferCount, static c2_status_t requestNewBufferSet(C2BlockPool& blockPool, int32_t bufferCount,
...@@ -73,6 +77,13 @@ private: ...@@ -73,6 +77,13 @@ private:
static bool setNotifyBlockAvailableCb(C2BlockPool& blockPool, ::base::OnceClosure cb); static bool setNotifyBlockAvailableCb(C2BlockPool& blockPool, ::base::OnceClosure cb);
std::shared_ptr<C2BlockPool> mBlockPool; std::shared_ptr<C2BlockPool> mBlockPool;
// Holds the number of maximum amount of buffers that VideoFramePool
// should provide to client.
size_t mMaxBufferCount;
// Contains known buffer ids that are valid for the pool.
std::set<uint32_t> mBuffers;
const ui::Size mSize; const ui::Size mSize;
const HalPixelFormat mPixelFormat; const HalPixelFormat mPixelFormat;
const C2MemoryUsage mMemoryUsage; const C2MemoryUsage mMemoryUsage;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment