From 0d273dd11aac9701c241f1097377614b80690fc3 Mon Sep 17 00:00:00 2001 From: Camillo Lugaresi Date: Tue, 15 Nov 2022 15:58:32 -0800 Subject: [PATCH] Factor out CvPixelBufferPoolWrapper This is platform-specific and does not need to live in the main multi_pool sources. PiperOrigin-RevId: 488781934 --- mediapipe/gpu/BUILD | 22 ++++++ mediapipe/gpu/cv_pixel_buffer_pool_wrapper.cc | 71 +++++++++++++++++++ mediapipe/gpu/cv_pixel_buffer_pool_wrapper.h | 50 +++++++++++++ mediapipe/gpu/gpu_buffer_multi_pool.cc | 49 +------------ mediapipe/gpu/gpu_buffer_multi_pool.h | 24 ++----- 5 files changed, 149 insertions(+), 67 deletions(-) create mode 100644 mediapipe/gpu/cv_pixel_buffer_pool_wrapper.cc create mode 100644 mediapipe/gpu/cv_pixel_buffer_pool_wrapper.h diff --git a/mediapipe/gpu/BUILD b/mediapipe/gpu/BUILD index 93527b56..26df167c 100644 --- a/mediapipe/gpu/BUILD +++ b/mediapipe/gpu/BUILD @@ -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", diff --git a/mediapipe/gpu/cv_pixel_buffer_pool_wrapper.cc b/mediapipe/gpu/cv_pixel_buffer_pool_wrapper.cc new file mode 100644 index 00000000..3293b023 --- /dev/null +++ b/mediapipe/gpu/cv_pixel_buffer_pool_wrapper.cc @@ -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 + +#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 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 diff --git a/mediapipe/gpu/cv_pixel_buffer_pool_wrapper.h b/mediapipe/gpu/cv_pixel_buffer_pool_wrapper.h new file mode 100644 index 00000000..081df467 --- /dev/null +++ b/mediapipe/gpu/cv_pixel_buffer_pool_wrapper.h @@ -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 flush); + + int GetBufferCount() const { return count_; } + std::string GetDebugString() const; + + void Flush(); + + private: + CFHolder pool_; + int count_ = 0; +}; + +} // namespace mediapipe + +#endif // MEDIAPIPE_GPU_CV_PIXEL_BUFFER_POOL_WRAPPER_H_ diff --git a/mediapipe/gpu/gpu_buffer_multi_pool.cc b/mediapipe/gpu/gpu_buffer_multi_pool.cc index f76833f2..1909d116 100644 --- a/mediapipe/gpu/gpu_buffer_multi_pool.cc +++ b/mediapipe/gpu/gpu_buffer_multi_pool.cc @@ -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 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::MakeSimplePool(const GpuBufferMultiPool::BufferSpec& spec) { - return std::make_shared(spec, - kMaxInactiveBufferAge); + return std::make_shared( + spec.width, spec.height, spec.format, kMaxInactiveBufferAge); } GpuBuffer GpuBufferMultiPool::GetBufferWithoutPool(const BufferSpec& spec) { diff --git a/mediapipe/gpu/gpu_buffer_multi_pool.h b/mediapipe/gpu/gpu_buffer_multi_pool.h index 7317ac60..f4857785 100644 --- a/mediapipe/gpu/gpu_buffer_multi_pool.h +++ b/mediapipe/gpu/gpu_buffer_multi_pool.h @@ -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 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 flush); - - int GetBufferCount() const { return count_; } - std::string GetDebugString() const; - - void Flush(); - - private: - CFHolder 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) {