Factor out CvPixelBufferPoolWrapper

This is platform-specific and does not need to live in the main multi_pool sources.

PiperOrigin-RevId: 488781934
This commit is contained in:
Camillo Lugaresi 2022-11-15 15:58:32 -08:00 committed by Copybara-Service
parent ab2dd779e7
commit 0d273dd11a
5 changed files with 149 additions and 67 deletions

View File

@ -356,6 +356,26 @@ cc_library(
],
)
cc_library(
name = "cv_pixel_buffer_pool_wrapper",
srcs = ["cv_pixel_buffer_pool_wrapper.cc"],
hdrs = ["cv_pixel_buffer_pool_wrapper.h"],
copts = select({
"//conditions:default": [],
"//mediapipe:apple": [
"-x objective-c++",
"-fobjc-arc",
],
}),
deps = [
":gpu_buffer",
":pixel_buffer_pool_util",
"//mediapipe/framework/port:logging",
"//mediapipe/objc:CFHolder",
"@com_google_absl//absl/synchronization",
],
)
cc_library(
name = "gpu_buffer_storage_image_frame",
hdrs = ["gpu_buffer_storage_image_frame.h"],
@ -631,12 +651,14 @@ cc_library(
":gl_texture_buffer_pool",
],
"//mediapipe:ios": [
":cv_pixel_buffer_pool_wrapper",
":cv_texture_cache_manager",
":pixel_buffer_pool_util",
"//mediapipe/objc:CFHolder",
"//mediapipe/objc:util",
],
"//mediapipe:macos": [
":cv_pixel_buffer_pool_wrapper",
":cv_texture_cache_manager",
":pixel_buffer_pool_util",
":gl_texture_buffer",

View File

@ -0,0 +1,71 @@
// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mediapipe/gpu/cv_pixel_buffer_pool_wrapper.h"
#include <tuple>
#include "CoreFoundation/CFBase.h"
#include "mediapipe/framework/port/logging.h"
#include "mediapipe/objc/CFHolder.h"
namespace mediapipe {
CvPixelBufferPoolWrapper::CvPixelBufferPoolWrapper(int width, int height,
GpuBufferFormat format,
CFTimeInterval maxAge) {
OSType cv_format = CVPixelFormatForGpuBufferFormat(format);
CHECK_NE(cv_format, -1) << "unsupported pixel format";
pool_ = MakeCFHolderAdopting(
/* keep count is 0 because the age param keeps buffers around anyway */
CreateCVPixelBufferPool(width, height, cv_format, 0, maxAge));
}
GpuBuffer CvPixelBufferPoolWrapper::GetBuffer(std::function<void(void)> flush) {
CVPixelBufferRef buffer;
int threshold = 1;
NSMutableDictionary* auxAttributes =
[NSMutableDictionary dictionaryWithCapacity:1];
CVReturn err;
bool tried_flushing = false;
while (1) {
auxAttributes[(id)kCVPixelBufferPoolAllocationThresholdKey] = @(threshold);
err = CVPixelBufferPoolCreatePixelBufferWithAuxAttributes(
kCFAllocatorDefault, *pool_, (__bridge CFDictionaryRef)auxAttributes,
&buffer);
if (err != kCVReturnWouldExceedAllocationThreshold) break;
if (flush && !tried_flushing) {
// Call the flush function to potentially release old holds on buffers
// and try again to create a pixel buffer.
// This is used to flush CV texture caches, which may retain buffers until
// flushed.
flush();
tried_flushing = true;
} else {
++threshold;
}
}
CHECK(!err) << "Error creating pixel buffer: " << err;
count_ = threshold;
return GpuBuffer(MakeCFHolderAdopting(buffer));
}
std::string CvPixelBufferPoolWrapper::GetDebugString() const {
auto description = MakeCFHolderAdopting(CFCopyDescription(*pool_));
return [(__bridge NSString*)*description UTF8String];
}
void CvPixelBufferPoolWrapper::Flush() { CVPixelBufferPoolFlush(*pool_, 0); }
} // namespace mediapipe

View File

@ -0,0 +1,50 @@
// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This class lets calculators allocate GpuBuffers of various sizes, caching
// and reusing them as needed. It does so by automatically creating and using
// platform-specific buffer pools for the requested sizes.
//
// This class is not meant to be used directly by calculators, but is instead
// used by GlCalculatorHelper to allocate buffers.
#ifndef MEDIAPIPE_GPU_CV_PIXEL_BUFFER_POOL_WRAPPER_H_
#define MEDIAPIPE_GPU_CV_PIXEL_BUFFER_POOL_WRAPPER_H_
#include "CoreFoundation/CFBase.h"
#include "mediapipe/gpu/gpu_buffer.h"
#include "mediapipe/gpu/pixel_buffer_pool_util.h"
#include "mediapipe/objc/CFHolder.h"
namespace mediapipe {
class CvPixelBufferPoolWrapper {
public:
CvPixelBufferPoolWrapper(int width, int height, GpuBufferFormat format,
CFTimeInterval maxAge);
GpuBuffer GetBuffer(std::function<void(void)> flush);
int GetBufferCount() const { return count_; }
std::string GetDebugString() const;
void Flush();
private:
CFHolder<CVPixelBufferPoolRef> pool_;
int count_ = 0;
};
} // namespace mediapipe
#endif // MEDIAPIPE_GPU_CV_PIXEL_BUFFER_POOL_WRAPPER_H_

View File

@ -45,55 +45,10 @@ static constexpr int kRequestCountScrubInterval = 50;
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
CvPixelBufferPoolWrapper::CvPixelBufferPoolWrapper(
const GpuBufferMultiPool::BufferSpec& spec, CFTimeInterval maxAge) {
OSType cv_format = CVPixelFormatForGpuBufferFormat(spec.format);
CHECK_NE(cv_format, -1) << "unsupported pixel format";
pool_ = MakeCFHolderAdopting(
/* keep count is 0 because the age param keeps buffers around anyway */
CreateCVPixelBufferPool(spec.width, spec.height, cv_format, 0, maxAge));
}
GpuBuffer CvPixelBufferPoolWrapper::GetBuffer(std::function<void(void)> flush) {
CVPixelBufferRef buffer;
int threshold = 1;
NSMutableDictionary* auxAttributes =
[NSMutableDictionary dictionaryWithCapacity:1];
CVReturn err;
bool tried_flushing = false;
while (1) {
auxAttributes[(id)kCVPixelBufferPoolAllocationThresholdKey] = @(threshold);
err = CVPixelBufferPoolCreatePixelBufferWithAuxAttributes(
kCFAllocatorDefault, *pool_, (__bridge CFDictionaryRef)auxAttributes,
&buffer);
if (err != kCVReturnWouldExceedAllocationThreshold) break;
if (flush && !tried_flushing) {
// Call the flush function to potentially release old holds on buffers
// and try again to create a pixel buffer.
// This is used to flush CV texture caches, which may retain buffers until
// flushed.
flush();
tried_flushing = true;
} else {
++threshold;
}
}
CHECK(!err) << "Error creating pixel buffer: " << err;
count_ = threshold;
return GpuBuffer(MakeCFHolderAdopting(buffer));
}
std::string CvPixelBufferPoolWrapper::GetDebugString() const {
auto description = MakeCFHolderAdopting(CFCopyDescription(*pool_));
return [(__bridge NSString*)*description UTF8String];
}
void CvPixelBufferPoolWrapper::Flush() { CVPixelBufferPoolFlush(*pool_, 0); }
std::shared_ptr<GpuBufferMultiPool::SimplePool>
GpuBufferMultiPool::MakeSimplePool(const GpuBufferMultiPool::BufferSpec& spec) {
return std::make_shared<CvPixelBufferPoolWrapper>(spec,
kMaxInactiveBufferAge);
return std::make_shared<CvPixelBufferPoolWrapper>(
spec.width, spec.height, spec.format, kMaxInactiveBufferAge);
}
GpuBuffer GpuBufferMultiPool::GetBufferWithoutPool(const BufferSpec& spec) {

View File

@ -31,9 +31,11 @@
#include "mediapipe/gpu/pixel_buffer_pool_util.h"
#endif // __APPLE__
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
#include "mediapipe/gpu/cv_pixel_buffer_pool_wrapper.h"
#else
#include "mediapipe/gpu/gl_texture_buffer_pool.h"
#endif // !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
namespace mediapipe {
@ -93,24 +95,6 @@ class GpuBufferMultiPool {
std::function<void(void)> flush_platform_caches_;
};
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
class CvPixelBufferPoolWrapper {
public:
CvPixelBufferPoolWrapper(const GpuBufferMultiPool::BufferSpec& spec,
CFTimeInterval maxAge);
GpuBuffer GetBuffer(std::function<void(void)> flush);
int GetBufferCount() const { return count_; }
std::string GetDebugString() const;
void Flush();
private:
CFHolder<CVPixelBufferPoolRef> pool_;
int count_ = 0;
};
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
// BufferSpec equality operators
inline bool operator==(const GpuBufferMultiPool::BufferSpec& lhs,
const GpuBufferMultiPool::BufferSpec& rhs) {