Project import generated by Copybara.

GitOrigin-RevId: d073f8e21be2fcc0e503cb97c6695078b6b75310
This commit is contained in:
MediaPipe Team
2021-02-27 03:30:05 -05:00
committed by chuoling
parent 39309bedba
commit 350fbb2100
755 changed files with 16391 additions and 11075 deletions
+22 -1
View File
@@ -15,6 +15,7 @@
load("//mediapipe/gpu:metal.bzl", "metal_library")
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
load("//mediapipe/framework/port:build_config.bzl", "mediapipe_cc_proto_library")
load("//mediapipe/framework:mediapipe_cc_test.bzl", "mediapipe_cc_test")
licenses(["notice"])
@@ -166,6 +167,7 @@ cc_library(
deps = [
":gl_base",
":gl_thread_collector",
":gpu_buffer_format",
"//mediapipe/framework:executor",
"//mediapipe/framework/port:logging",
"//mediapipe/framework/port:ret_check",
@@ -364,13 +366,13 @@ cc_library(
hdrs = [
"gpu_shared_data_internal.h",
],
defines = ["MEDIAPIPE_DISABLE_GPU"],
visibility = ["//visibility:private"],
deps = [
":graph_support",
"//mediapipe/framework:calculator_context",
"//mediapipe/framework:calculator_node",
"//mediapipe/framework:executor",
"//mediapipe/framework:port",
"//mediapipe/framework/deps:no_destructor",
"//mediapipe/framework/port:ret_check",
"//mediapipe/gpu:gl_context_options_cc_proto",
@@ -560,6 +562,7 @@ cc_library(
"//mediapipe/framework:packet_set",
"//mediapipe/framework:packet_type",
"//mediapipe/framework:timestamp",
"//mediapipe/framework/formats:image",
"//mediapipe/framework/formats:image_frame",
"//mediapipe/framework/port:logging",
"//mediapipe/framework/port:ret_check",
@@ -597,6 +600,7 @@ objc_library(
":gpu_shared_data_internal",
":shader_util",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework/formats:image",
"//mediapipe/objc:mediapipe_framework_ios",
"//mediapipe/objc:util",
],
@@ -904,6 +908,23 @@ objc_library(
alwayslink = 1,
)
objc_library(
name = "mps_threshold_calculator",
srcs = ["MPSThresholdCalculator.mm"],
copts = ["-std=c++17"],
sdk_frameworks = [
"CoreVideo",
"Metal",
"MetalPerformanceShaders",
],
visibility = ["//visibility:public"],
deps = [
":MPPMetalHelper",
"//mediapipe/objc:mediapipe_framework_ios",
],
alwayslink = 1,
)
MIN_IOS_VERSION = "9.0" # For thread_local.
test_suite(
+2 -2
View File
@@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
/// Configures a calculator's contract for accessing GPU resources.
/// Calculators should use this in GetContract.
+ (::mediapipe::Status)updateContract:(mediapipe::CalculatorContract*)cc;
+ (absl::Status)updateContract:(mediapipe::CalculatorContract*)cc;
/// Deprecated initializer.
- (instancetype)initWithSidePackets:(const mediapipe::PacketSet&)inputSidePackets;
@@ -51,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
/// Configures a calculator's side packets for accessing GPU resources.
/// Calculators should use this in FillExpectations.
+ (::mediapipe::Status)setupInputSidePackets:(mediapipe::PacketTypeSet*)inputSidePackets;
+ (absl::Status)setupInputSidePackets:(mediapipe::PacketTypeSet*)inputSidePackets;
/// Get a metal command buffer.
/// Calculators should use this method instead of getting a buffer from the
+4 -4
View File
@@ -54,7 +54,7 @@ class MetalHelperLegacySupport {
return [self initWithGpuResources:&cc->Service(mediapipe::kGpuService).GetObject()];
}
+ (::mediapipe::Status)updateContract:(mediapipe::CalculatorContract*)cc {
+ (absl::Status)updateContract:(mediapipe::CalculatorContract*)cc {
cc->UseService(mediapipe::kGpuService);
// Allow the legacy side packet to be provided, too, for backwards
// compatibility with existing graphs. It will just be ignored.
@@ -63,7 +63,7 @@ class MetalHelperLegacySupport {
if (id.IsValid()) {
input_side_packets.Get(id).Set<mediapipe::GpuSharedData*>();
}
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
// Legacy support.
@@ -85,7 +85,7 @@ class MetalHelperLegacySupport {
}
// Legacy support.
+ (::mediapipe::Status)setupInputSidePackets:(mediapipe::PacketTypeSet*)inputSidePackets {
+ (absl::Status)setupInputSidePackets:(mediapipe::PacketTypeSet*)inputSidePackets {
auto cc = mediapipe::MetalHelperLegacySupport::GetCalculatorContract();
if (cc) {
CHECK_EQ(inputSidePackets, &cc->InputSidePackets());
@@ -101,7 +101,7 @@ class MetalHelperLegacySupport {
<< "A " << mediapipe::kGpuSharedTagName
<< " input side packet is required here.";
inputSidePackets->Get(id).Set<mediapipe::GpuSharedData*>();
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
- (id<MTLDevice>)mtlDevice {
+1 -1
View File
@@ -69,7 +69,7 @@
#include <GLES3/gl32.h>
// When using the Linux EGL headers, we may end up pulling a
// "#define Status int" from Xlib.h, which interferes with mediapipe::Status.
// "#define Status int" from Xlib.h, which interferes with absl::Status.
#undef Status
// More crud from X
+27 -9
View File
@@ -14,6 +14,7 @@
#include "mediapipe/gpu/gl_calculator_helper.h"
#include "mediapipe/framework/formats/image.h"
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/legacy_calculator_support.h"
#include "mediapipe/framework/port/canonical_errors.h"
@@ -39,12 +40,12 @@ GlCalculatorHelper::GlCalculatorHelper() {}
GlCalculatorHelper::~GlCalculatorHelper() {}
::mediapipe::Status GlCalculatorHelper::Open(CalculatorContext* cc) {
absl::Status GlCalculatorHelper::Open(CalculatorContext* cc) {
CHECK(cc);
// TODO return error from impl_ (needs two-stage init)
impl_ = absl::make_unique<GlCalculatorHelperImpl>(
cc, &cc->Service(kGpuService).GetObject());
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
void GlCalculatorHelper::InitializeForTest(GpuSharedData* gpu_shared) {
@@ -57,7 +58,7 @@ void GlCalculatorHelper::InitializeForTest(GpuResources* gpu_resources) {
}
// static
::mediapipe::Status GlCalculatorHelper::UpdateContract(CalculatorContract* cc) {
absl::Status GlCalculatorHelper::UpdateContract(CalculatorContract* cc) {
cc->UseService(kGpuService);
// Allow the legacy side packet to be provided, too, for backwards
// compatibility with existing graphs. It will just be ignored.
@@ -66,11 +67,11 @@ void GlCalculatorHelper::InitializeForTest(GpuResources* gpu_resources) {
if (id.IsValid()) {
input_side_packets.Get(id).Set<GpuSharedData*>();
}
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
// static
::mediapipe::Status GlCalculatorHelper::SetupInputSidePackets(
absl::Status GlCalculatorHelper::SetupInputSidePackets(
PacketTypeSet* input_side_packets) {
auto cc = LegacyCalculatorSupport::Scoped<CalculatorContract>::current();
if (cc) {
@@ -87,12 +88,12 @@ void GlCalculatorHelper::InitializeForTest(GpuResources* gpu_resources) {
RET_CHECK(id.IsValid()) << "A " << mediapipe::kGpuSharedTagName
<< " input side packet is required here.";
input_side_packets->Get(id).Set<GpuSharedData*>();
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status GlCalculatorHelper::RunInGlContext(
std::function<::mediapipe::Status(void)> gl_func) {
if (!impl_) return ::mediapipe::InternalError("helper not initialized");
absl::Status GlCalculatorHelper::RunInGlContext(
std::function<absl::Status(void)> gl_func) {
if (!impl_) return absl::InternalError("helper not initialized");
// TODO: Remove LegacyCalculatorSupport from MediaPipe OSS.
auto calculator_context =
LegacyCalculatorSupport::Scoped<CalculatorContext>::current();
@@ -140,4 +141,21 @@ GlContext& GlCalculatorHelper::GetGlContext() const {
return impl_->GetGlContext();
}
GlVersion GlCalculatorHelper::GetGlVersion() const {
return impl_->GetGlVersion();
}
GlTexture GlCalculatorHelper::CreateSourceTexture(
const mediapipe::Image& image) {
return impl_->CreateSourceTexture(image.GetGpuBuffer());
}
template <>
std::unique_ptr<mediapipe::Image> GlTexture::GetFrame<mediapipe::Image>()
const {
std::unique_ptr<GpuBuffer> buf = GetFrame<GpuBuffer>();
auto output = absl::make_unique<mediapipe::Image>(*buf);
return output;
}
} // namespace mediapipe
+12 -10
View File
@@ -18,6 +18,7 @@
#include "absl/memory/memory.h"
#include "mediapipe/framework/calculator_context.h"
#include "mediapipe/framework/calculator_contract.h"
#include "mediapipe/framework/formats/image.h"
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/packet.h"
#include "mediapipe/framework/packet_set.h"
@@ -68,7 +69,7 @@ class GlCalculatorHelper {
~GlCalculatorHelper();
// Call Open from the Open method of a calculator to initialize the helper.
::mediapipe::Status Open(CalculatorContext* cc);
absl::Status Open(CalculatorContext* cc);
// Can be used to initialize the helper outside of a calculator. Useful for
// testing.
@@ -77,33 +78,31 @@ class GlCalculatorHelper {
// This method can be called from GetContract to set up the needed GPU
// resources.
static ::mediapipe::Status UpdateContract(CalculatorContract* cc);
static absl::Status UpdateContract(CalculatorContract* cc);
// This method can be called from FillExpectations to set the correct types
// for the shared GL input side packet(s).
static ::mediapipe::Status SetupInputSidePackets(
PacketTypeSet* input_side_packets);
static absl::Status SetupInputSidePackets(PacketTypeSet* input_side_packets);
// Execute the provided function within the helper's GL context. On some
// platforms, this may be run on a different thread; however, this method
// will still wait for the function to finish executing before returning.
// The status result from the function is passed on to the caller.
::mediapipe::Status RunInGlContext(
std::function<::mediapipe::Status(void)> gl_func);
absl::Status RunInGlContext(std::function<absl::Status(void)> gl_func);
// Convenience version of RunInGlContext for arguments with a void result
// type. As with the ::mediapipe::Status version, this also waits for the
// type. As with the absl::Status version, this also waits for the
// function to finish executing before returning.
//
// Implementation note: we cannot use a std::function<void(void)> argument
// here, because that would break passing in a lambda that returns a status;
// e.g.:
// RunInGlContext([]() -> ::mediapipe::Status { ... });
// RunInGlContext([]() -> absl::Status { ... });
//
// The reason is that std::function<void(...)> allows the implicit conversion
// of a callable with any result type, as long as the argument types match.
// As a result, the above lambda would be implicitly convertible to both
// std::function<::mediapipe::Status(void)> and std::function<void(void)>, and
// std::function<absl::Status(void)> and std::function<void(void)>, and
// the invocation would be ambiguous.
//
// Therefore, instead of using std::function<void(void)>, we use a template
@@ -113,7 +112,7 @@ class GlCalculatorHelper {
void RunInGlContext(T f) {
RunInGlContext([f] {
f();
return ::mediapipe::OkStatus();
return absl::OkStatus();
}).IgnoreError();
}
@@ -125,6 +124,7 @@ class GlCalculatorHelper {
// Creates a texture representing an input frame, and manages sync token.
GlTexture CreateSourceTexture(const GpuBuffer& pixel_buffer);
GlTexture CreateSourceTexture(const ImageFrame& image_frame);
GlTexture CreateSourceTexture(const mediapipe::Image& image);
#ifdef __APPLE__
// Creates a texture from a plane of a planar buffer.
@@ -153,6 +153,8 @@ class GlCalculatorHelper {
GlContext& GetGlContext() const;
GlVersion GetGlVersion() const;
// Check if the calculator helper has been previously initialized.
bool Initialized() { return impl_ != nullptr; }
+3 -6
View File
@@ -37,9 +37,8 @@ class GlCalculatorHelperImpl {
GpuResources* gpu_resources);
~GlCalculatorHelperImpl();
::mediapipe::Status RunInGlContext(
std::function<::mediapipe::Status(void)> gl_func,
CalculatorContext* calculator_context);
absl::Status RunInGlContext(std::function<absl::Status(void)> gl_func,
CalculatorContext* calculator_context);
GlTexture CreateSourceTexture(const ImageFrame& image_frame);
GlTexture CreateSourceTexture(const GpuBuffer& gpu_buffer);
@@ -54,9 +53,7 @@ class GlCalculatorHelperImpl {
GLuint framebuffer() const { return framebuffer_; }
void BindFramebuffer(const GlTexture& dst);
#ifdef __APPLE__
GlVersion GetGlVersion();
#endif
GlVersion GetGlVersion() const { return gl_context_->GetGlVersion(); }
GlContext& GetGlContext() const;
@@ -36,6 +36,15 @@ std::unique_ptr<ImageFrame> GlTexture::GetFrame<ImageFrame>() const {
template <>
std::unique_ptr<GpuBuffer> GlTexture::GetFrame<GpuBuffer>() const {
#ifdef __EMSCRIPTEN__
// When WebGL is used, the GL context may be spontaneously lost which can
// cause GpuBuffer allocations to fail. In that case, return a dummy buffer
// to allow processing of the current frame complete.
if (!gpu_buffer_) {
return std::make_unique<GpuBuffer>();
}
#endif // __EMSCRIPTEN__
CHECK(gpu_buffer_);
// Inform the GlTextureBuffer that we have produced new content, and create
// a producer sync point.
@@ -42,7 +42,7 @@ GlCalculatorHelperImpl::~GlCalculatorHelperImpl() {
glDeleteFramebuffers(1, &framebuffer_);
framebuffer_ = 0;
}
return ::mediapipe::OkStatus();
return absl::OkStatus();
},
/*calculator_context=*/nullptr)
.IgnoreError();
@@ -50,8 +50,8 @@ GlCalculatorHelperImpl::~GlCalculatorHelperImpl() {
GlContext& GlCalculatorHelperImpl::GetGlContext() const { return *gl_context_; }
::mediapipe::Status GlCalculatorHelperImpl::RunInGlContext(
std::function<::mediapipe::Status(void)> gl_func,
absl::Status GlCalculatorHelperImpl::RunInGlContext(
std::function<absl::Status(void)> gl_func,
CalculatorContext* calculator_context) {
if (calculator_context) {
return gl_context_->Run(std::move(gl_func), calculator_context->NodeId(),
@@ -161,12 +161,14 @@ GlTexture GlCalculatorHelperImpl::MapGlTextureBuffer(
texture.target_ = texture_buffer->target_;
texture.name_ = texture_buffer->name_;
// TODO: do the params need to be reset here??
glBindTexture(texture.target(), texture.name());
GlTextureInfo info =
GlTextureInfoForGpuBufferFormat(texture_buffer->format(), texture.plane_);
SetStandardTextureParams(texture.target(), info.gl_internal_format);
glBindTexture(texture.target(), 0);
if (texture_buffer->format() != GpuBufferFormat::kUnknown) {
// TODO: do the params need to be reset here??
glBindTexture(texture.target(), texture.name());
GlTextureInfo info = GlTextureInfoForGpuBufferFormat(
texture_buffer->format(), texture.plane_, GetGlVersion());
SetStandardTextureParams(texture.target(), info.gl_internal_format);
glBindTexture(texture.target(), 0);
}
return texture;
}
@@ -178,11 +180,14 @@ GlTextureBufferSharedPtr GlCalculatorHelperImpl::MakeGlTextureBuffer(
image_frame.Width(), image_frame.Height(),
GpuBufferFormatForImageFormat(image_frame.Format()),
image_frame.PixelData());
glBindTexture(GL_TEXTURE_2D, buffer->name_);
GlTextureInfo info =
GlTextureInfoForGpuBufferFormat(buffer->format_, /*plane=*/0);
SetStandardTextureParams(buffer->target_, info.gl_internal_format);
glBindTexture(GL_TEXTURE_2D, 0);
if (buffer->format_ != GpuBufferFormat::kUnknown) {
glBindTexture(GL_TEXTURE_2D, buffer->name_);
GlTextureInfo info = GlTextureInfoForGpuBufferFormat(
buffer->format_, /*plane=*/0, GetGlVersion());
SetStandardTextureParams(buffer->target_, info.gl_internal_format);
glBindTexture(GL_TEXTURE_2D, 0);
}
return buffer;
}
+3 -12
View File
@@ -28,15 +28,6 @@
namespace mediapipe {
GlVersion GlCalculatorHelperImpl::GetGlVersion() {
#if TARGET_OS_OSX
return GlVersion::kGL;
#else
if (gl_context_->eagl_context().API == kEAGLRenderingAPIOpenGLES3) return GlVersion::kGLES3;
else return GlVersion::kGLES2;
#endif // TARGET_OS_OSX
}
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
GlTexture GlCalculatorHelperImpl::CreateSourceTexture(
const mediapipe::ImageFrame& image_frame) {
@@ -122,9 +113,9 @@ std::unique_ptr<ImageFrame> GlTexture::GetFrame<ImageFrame>() const {
ImageFormat::Format image_format =
ImageFormatForGpuBufferFormat(gpu_buffer_.format());
// TODO: handle gl version here.
GlTextureInfo info = GlTextureInfoForGpuBufferFormat(
gpu_buffer_.format(), plane_);
CHECK(helper_impl_);
GlTextureInfo info =
GlTextureInfoForGpuBufferFormat(gpu_buffer_.format(), plane_, helper_impl_->GetGlVersion());
auto output = absl::make_unique<ImageFrame>(
image_format, width_, height_);
+40 -27
View File
@@ -29,6 +29,7 @@
#include "mediapipe/framework/port/status.h"
#include "mediapipe/framework/port/status_builder.h"
#include "mediapipe/gpu/gl_context_internal.h"
#include "mediapipe/gpu/gpu_buffer_format.h"
#ifndef __EMSCRIPTEN__
#include "absl/debugging/leak_check.h"
@@ -140,13 +141,13 @@ void GlContext::DedicatedThread::ThreadBody() {
#endif
}
::mediapipe::Status GlContext::DedicatedThread::Run(GlStatusFunction gl_func) {
absl::Status GlContext::DedicatedThread::Run(GlStatusFunction gl_func) {
// Neither ENDO_SCOPE nor ENDO_TASK seem to work here.
if (IsCurrentThread()) {
return gl_func();
}
bool done = false; // Guarded by mutex_ after initialization.
::mediapipe::Status status;
absl::Status status;
PutJob([this, gl_func, &done, &status]() {
status = gl_func();
absl::MutexLock lock(&mutex_);
@@ -204,6 +205,14 @@ bool GlContext::ParseGlVersion(absl::string_view version_string, GLint* major,
return true;
}
GlVersion GlContext::GetGlVersion() const {
#ifdef GL_ES_VERSION_2_0 // This actually means "is GLES available".
return gl_major_version() < 3 ? GlVersion::kGLES2 : GlVersion::kGLES3;
#else // This is the "desktop GL" case.
return GlVersion::kGL;
#endif
}
bool GlContext::HasGlExtension(absl::string_view extension) const {
return gl_extensions_.find(extension) != gl_extensions_.end();
}
@@ -212,7 +221,7 @@ bool GlContext::HasGlExtension(absl::string_view extension) const {
// in an easily-accessible set. The glGetString call is actually *not* required
// to work with GL_EXTENSIONS for newer GL versions, so we must maintain both
// variations of this function.
::mediapipe::Status GlContext::GetGlExtensions() {
absl::Status GlContext::GetGlExtensions() {
gl_extensions_.clear();
// glGetStringi only introduced in GL 3.0+; so we exit out this function if
// we don't have that function defined, regardless of version number reported.
@@ -226,54 +235,52 @@ bool GlContext::HasGlExtension(absl::string_view extension) const {
LOG(ERROR) << "GL major version > 3.0 indicated, but glGetStringi not "
<< "defined. Falling back to deprecated GL extensions querying "
<< "method.";
return ::mediapipe::InternalError("glGetStringi not defined, but queried");
return absl::InternalError("glGetStringi not defined, but queried");
}
int num_extensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
if (glGetError() != 0) {
return ::mediapipe::InternalError(
"Error querying for number of extensions");
return absl::InternalError("Error querying for number of extensions");
}
for (int i = 0; i < num_extensions; ++i) {
const GLubyte* res = glGetStringi(GL_EXTENSIONS, i);
if (glGetError() != 0 || res == nullptr) {
return ::mediapipe::InternalError(
"Error querying for an extension by index");
return absl::InternalError("Error querying for an extension by index");
}
const char* signed_res = reinterpret_cast<const char*>(res);
gl_extensions_.insert(signed_res);
}
return ::mediapipe::OkStatus();
return absl::OkStatus();
#else
return ::mediapipe::InternalError("GL version mismatch in GlGetExtensions");
return absl::InternalError("GL version mismatch in GlGetExtensions");
#endif // (GL_VERSION_3_0 || GL_ES_VERSION_3_0) && !defined(__EMSCRIPTEN__)
}
// Same as GetGlExtensions() above, but for pre-GL3.0, where glGetStringi did
// not exist.
::mediapipe::Status GlContext::GetGlExtensionsCompat() {
absl::Status GlContext::GetGlExtensionsCompat() {
gl_extensions_.clear();
const GLubyte* res = glGetString(GL_EXTENSIONS);
if (glGetError() != 0 || res == nullptr) {
LOG(ERROR) << "Error querying for GL extensions";
return ::mediapipe::InternalError("Error querying for GL extensions");
return absl::InternalError("Error querying for GL extensions");
}
const char* signed_res = reinterpret_cast<const char*>(res);
gl_extensions_ = absl::StrSplit(signed_res, ' ');
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status GlContext::FinishInitialization(bool create_thread) {
absl::Status GlContext::FinishInitialization(bool create_thread) {
if (create_thread) {
thread_ = absl::make_unique<GlContext::DedicatedThread>();
MP_RETURN_IF_ERROR(thread_->Run([this] { return EnterContext(nullptr); }));
}
return Run([this]() -> ::mediapipe::Status {
return Run([this]() -> absl::Status {
// Clear any GL errors at this point: as this is a fresh context
// there shouldn't be any, but if we adopted an existing context (e.g. in
// some Emscripten cases), there might be some existing tripped error.
@@ -326,7 +333,7 @@ bool GlContext::HasGlExtension(absl::string_view extension) const {
if (gl_major_version_ >= 3) {
auto status = GetGlExtensions();
if (status.ok()) {
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
}
return GetGlExtensionsCompat();
@@ -368,7 +375,7 @@ void GlContext::SetProfilingContext(
}
}
::mediapipe::Status GlContext::SwitchContextAndRun(GlStatusFunction gl_func) {
absl::Status GlContext::SwitchContextAndRun(GlStatusFunction gl_func) {
ContextBinding saved_context;
MP_RETURN_IF_ERROR(EnterContext(&saved_context)) << " (entering GL context)";
auto status = gl_func();
@@ -377,9 +384,9 @@ void GlContext::SetProfilingContext(
return status;
}
::mediapipe::Status GlContext::Run(GlStatusFunction gl_func, int node_id,
Timestamp input_timestamp) {
::mediapipe::Status status;
absl::Status GlContext::Run(GlStatusFunction gl_func, int node_id,
Timestamp input_timestamp) {
absl::Status status;
if (profiling_helper_) {
gl_func = [=] {
profiling_helper_->MarkTimestamp(node_id, input_timestamp,
@@ -416,7 +423,7 @@ void GlContext::RunWithoutWaiting(GlVoidFunction gl_func) {
// TODO: queue up task instead.
auto status = SwitchContextAndRun([gl_func] {
gl_func();
return ::mediapipe::OkStatus();
return absl::OkStatus();
});
if (!status.ok()) {
LOG(ERROR) << "Error in RunWithoutWaiting: " << status;
@@ -433,8 +440,8 @@ std::weak_ptr<GlContext>& GlContext::CurrentContext() {
return current_context;
}
::mediapipe::Status GlContext::SwitchContext(ContextBinding* saved_context,
const ContextBinding& new_context)
absl::Status GlContext::SwitchContext(ContextBinding* saved_context,
const ContextBinding& new_context)
ABSL_NO_THREAD_SAFETY_ANALYSIS {
std::shared_ptr<GlContext> old_context_obj = CurrentContext().lock();
std::shared_ptr<GlContext> new_context_obj =
@@ -452,7 +459,7 @@ std::weak_ptr<GlContext>& GlContext::CurrentContext() {
}
if (new_context_obj && (old_context_obj == new_context_obj)) {
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
if (old_context_obj) {
@@ -479,13 +486,12 @@ std::weak_ptr<GlContext>& GlContext::CurrentContext() {
}
}
::mediapipe::Status GlContext::EnterContext(ContextBinding* saved_context) {
absl::Status GlContext::EnterContext(ContextBinding* saved_context) {
DCHECK(HasContext());
return SwitchContext(saved_context, ThisContextBinding());
}
::mediapipe::Status GlContext::ExitContext(
const ContextBinding* saved_context) {
absl::Status GlContext::ExitContext(const ContextBinding* saved_context) {
ContextBinding no_context;
if (!saved_context) {
saved_context = &no_context;
@@ -822,4 +828,11 @@ void GlContext::LogUncheckedGlErrors(bool had_gl_errors) {
}
}
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
int plane) {
std::shared_ptr<GlContext> ctx = GlContext::GetCurrent();
CHECK(ctx != nullptr);
return GlTextureInfoForGpuBufferFormat(format, plane, ctx->GetGlVersion());
}
} // namespace mediapipe
+34 -25
View File
@@ -29,6 +29,7 @@
#include "mediapipe/framework/port/threadpool.h"
#include "mediapipe/framework/timestamp.h"
#include "mediapipe/gpu/gl_base.h"
#include "mediapipe/gpu/gpu_buffer_format.h"
#ifdef __APPLE__
#include <CoreVideo/CoreVideo.h>
@@ -64,7 +65,7 @@ struct EAGLContext;
namespace mediapipe {
typedef std::function<void()> GlVoidFunction;
typedef std::function<::mediapipe::Status()> GlStatusFunction;
typedef std::function<absl::Status()> GlStatusFunction;
class GlContext;
@@ -141,10 +142,9 @@ constexpr PlatformGlContext kPlatformGlContextNone = nil;
// - Managing the interaction between threads and GL contexts.
// - Managing synchronization between different GL contexts.
//
// See go/mediapipe-gl-context for details.
class GlContext : public std::enable_shared_from_this<GlContext> {
public:
using StatusOrGlContext = ::mediapipe::StatusOr<std::shared_ptr<GlContext>>;
using StatusOrGlContext = absl::StatusOr<std::shared_ptr<GlContext>>;
// Creates a GlContext.
//
// The first argument (which can be a GlContext, or a platform-specific type)
@@ -180,8 +180,8 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
// Executes a function in the GL context. Waits for the
// function's execution to be complete before returning to the caller.
::mediapipe::Status Run(GlStatusFunction gl_func, int node_id = -1,
Timestamp input_timestamp = Timestamp::Unset());
absl::Status Run(GlStatusFunction gl_func, int node_id = -1,
Timestamp input_timestamp = Timestamp::Unset());
// Like Run, but does not wait.
void RunWithoutWaiting(GlVoidFunction gl_func);
@@ -237,6 +237,10 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
static bool ParseGlVersion(absl::string_view version_string, GLint* major,
GLint* minor);
// Returns a GlVersion code used with GpuBufferFormat.
// TODO: make this more generally applicable.
GlVersion GetGlVersion() const;
// Simple query for GL extension support; only valid after GlContext has
// finished its initialization successfully.
bool HasGlExtension(absl::string_view extension) const;
@@ -253,12 +257,12 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
// Implementation note: we cannot use a std::function<void(void)> argument
// here, because that would break passing in a lambda that returns a status;
// e.g.:
// RunInGlContext([]() -> ::mediapipe::Status { ... });
// RunInGlContext([]() -> absl::Status { ... });
//
// The reason is that std::function<void(...)> allows the implicit conversion
// of a callable with any result type, as long as the argument types match.
// As a result, the above lambda would be implicitly convertible to both
// std::function<::mediapipe::Status(void)> and std::function<void(void)>, and
// std::function<absl::Status(void)> and std::function<void(void)>, and
// the invocation would be ambiguous.
//
// Therefore, instead of using std::function<void(void)>, we use a template
@@ -268,7 +272,7 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
void Run(T f) {
Run([f] {
f();
return ::mediapipe::OkStatus();
return absl::OkStatus();
}).IgnoreError();
}
@@ -284,29 +288,27 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
GlContext();
#if defined(__EMSCRIPTEN__)
::mediapipe::Status CreateContext(
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE share_context);
::mediapipe::Status CreateContextInternal(
absl::Status CreateContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE share_context);
absl::Status CreateContextInternal(
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE share_context, int webgl_version);
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context_ = 0;
EmscriptenWebGLContextAttributes attrs_;
#elif HAS_EGL
::mediapipe::Status CreateContext(EGLContext share_context);
::mediapipe::Status CreateContextInternal(EGLContext share_context,
int gl_version);
absl::Status CreateContext(EGLContext share_context);
absl::Status CreateContextInternal(EGLContext share_context, int gl_version);
EGLDisplay display_ = EGL_NO_DISPLAY;
EGLConfig config_;
EGLSurface surface_ = EGL_NO_SURFACE;
EGLContext context_ = EGL_NO_CONTEXT;
#elif HAS_EAGL
::mediapipe::Status CreateContext(EAGLSharegroup* sharegroup);
absl::Status CreateContext(EAGLSharegroup* sharegroup);
EAGLContext* context_;
CFHolder<CVOpenGLESTextureCacheRef> texture_cache_;
#elif HAS_NSGL
::mediapipe::Status CreateContext(NSOpenGLContext* share_context);
absl::Status CreateContext(NSOpenGLContext* share_context);
NSOpenGLContext* context_;
NSOpenGLPixelFormat* pixel_format_;
@@ -335,16 +337,16 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
#endif // HAS_EGL
};
::mediapipe::Status FinishInitialization(bool create_thread);
absl::Status FinishInitialization(bool create_thread);
// This wraps a thread_local.
static std::weak_ptr<GlContext>& CurrentContext();
static ::mediapipe::Status SwitchContext(ContextBinding* old_context,
const ContextBinding& new_context);
static absl::Status SwitchContext(ContextBinding* old_context,
const ContextBinding& new_context);
::mediapipe::Status EnterContext(ContextBinding* previous_context);
::mediapipe::Status ExitContext(const ContextBinding* previous_context);
absl::Status EnterContext(ContextBinding* previous_context);
absl::Status ExitContext(const ContextBinding* previous_context);
void DestroyContext();
bool HasContext() const;
@@ -363,13 +365,13 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
bool CheckForGlErrors(bool force);
void LogUncheckedGlErrors(bool had_gl_errors);
::mediapipe::Status GetGlExtensions();
::mediapipe::Status GetGlExtensionsCompat();
absl::Status GetGlExtensions();
absl::Status GetGlExtensionsCompat();
// Make the context current, run gl_func, and restore the previous context.
// Internal helper only; callers should use Run or RunWithoutWaiting instead,
// which delegates to the dedicated thread if required.
::mediapipe::Status SwitchContextAndRun(GlStatusFunction gl_func);
absl::Status SwitchContextAndRun(GlStatusFunction gl_func);
// The following ContextBinding functions have platform-specific
// implementations.
@@ -380,7 +382,7 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
// context is current on this thread.
static void GetCurrentContextBinding(ContextBinding* binding);
// Makes the context described by new_context current on this thread.
static ::mediapipe::Status SetCurrentContextBinding(
static absl::Status SetCurrentContextBinding(
const ContextBinding& new_context);
// If not null, a dedicated thread used to execute tasks on this context.
@@ -415,5 +417,12 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
std::unique_ptr<mediapipe::GlProfilingHelper> profiling_helper_ = nullptr;
};
// For backward compatibility. TODO: migrate remaining callers.
ABSL_DEPRECATED(
"Prefer passing an explicit GlVersion argument (use "
"GlContext::GetGlVersion)")
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
int plane);
} // namespace mediapipe
#endif // MEDIAPIPE_GPU_GL_CONTEXT_H_
+4 -4
View File
@@ -53,7 +53,7 @@ GlContext::StatusOrGlContext GlContext::Create(EAGLSharegroup* sharegroup,
return std::move(context);
}
::mediapipe::Status GlContext::CreateContext(EAGLSharegroup* sharegroup) {
absl::Status GlContext::CreateContext(EAGLSharegroup* sharegroup) {
context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
sharegroup:sharegroup];
if (context_) {
@@ -72,7 +72,7 @@ GlContext::StatusOrGlContext GlContext::Create(EAGLSharegroup* sharegroup,
<< "Error at CVOpenGLESTextureCacheCreate";
texture_cache_.adopt(cache);
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
void GlContext::DestroyContext() {
@@ -95,11 +95,11 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
binding->context = [EAGLContext currentContext];
}
::mediapipe::Status GlContext::SetCurrentContextBinding(
absl::Status GlContext::SetCurrentContextBinding(
const ContextBinding& new_binding) {
BOOL success = [EAGLContext setCurrentContext:new_binding.context];
RET_CHECK(success) << "Cannot set OpenGL context";
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
bool GlContext::HasContext() const { return context_ != nil; }
+8 -8
View File
@@ -85,8 +85,8 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
return std::move(context);
}
::mediapipe::Status GlContext::CreateContextInternal(
EGLContext external_context, int gl_version) {
absl::Status GlContext::CreateContextInternal(EGLContext external_context,
int gl_version) {
CHECK(gl_version == 2 || gl_version == 3);
const EGLint config_attr[] = {
@@ -146,10 +146,10 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
// GLES 2 does not have them, so let's set the major version here at least.
gl_major_version_ = gl_version;
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status GlContext::CreateContext(EGLContext external_context) {
absl::Status GlContext::CreateContext(EGLContext external_context) {
EGLint major = 0;
EGLint minor = 0;
@@ -178,7 +178,7 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
<< "eglCreatePbufferSurface() returned error " << std::showbase
<< std::hex << eglGetError();
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
void GlContext::DestroyContext() {
@@ -212,7 +212,7 @@ void GlContext::DestroyContext() {
thread_
->Run([] {
eglReleaseThread();
return ::mediapipe::OkStatus();
return absl::OkStatus();
})
.IgnoreError();
}
@@ -271,7 +271,7 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
binding->context = eglGetCurrentContext();
}
::mediapipe::Status GlContext::SetCurrentContextBinding(
absl::Status GlContext::SetCurrentContextBinding(
const ContextBinding& new_binding) {
EnsureEglThreadRelease();
EGLDisplay display = new_binding.display;
@@ -286,7 +286,7 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
new_binding.read_surface, new_binding.context);
RET_CHECK(success) << "eglMakeCurrent() returned error " << std::showbase
<< std::hex << eglGetError();
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
bool GlContext::HasContext() const { return context_ != EGL_NO_CONTEXT; }
+1 -1
View File
@@ -35,7 +35,7 @@ class GlContext::DedicatedThread {
DedicatedThread(const DedicatedThread&) = delete;
DedicatedThread& operator=(DedicatedThread) = delete;
::mediapipe::Status Run(GlStatusFunction gl_func);
absl::Status Run(GlStatusFunction gl_func);
void RunWithoutWaiting(GlVoidFunction gl_fund);
bool IsCurrentThread();
+5 -6
View File
@@ -44,7 +44,7 @@ GlContext::StatusOrGlContext GlContext::Create(NSOpenGLContext* share_context,
return std::move(context);
}
::mediapipe::Status GlContext::CreateContext(NSOpenGLContext* share_context) {
absl::Status GlContext::CreateContext(NSOpenGLContext* share_context) {
// TODO: choose a better list?
NSOpenGLPixelFormatAttribute attrs[] = {
// This is required to get any OpenGL version 3.2 or higher. Note that
@@ -96,8 +96,7 @@ GlContext::StatusOrGlContext GlContext::Create(NSOpenGLContext* share_context,
[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs_no_accel];
}
if (!pixel_format_)
return ::mediapipe::InternalError(
"Could not create an NSOpenGLPixelFormat");
return absl::InternalError("Could not create an NSOpenGLPixelFormat");
context_ = [[NSOpenGLContext alloc] initWithFormat:pixel_format_
shareContext:share_context];
@@ -123,7 +122,7 @@ GlContext::StatusOrGlContext GlContext::Create(NSOpenGLContext* share_context,
RET_CHECK_EQ(err, kCVReturnSuccess) << "Error at CVOpenGLTextureCacheCreate";
texture_cache_.adopt(cache);
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
void GlContext::DestroyContext() {
@@ -146,14 +145,14 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
binding->context = [NSOpenGLContext currentContext];
}
::mediapipe::Status GlContext::SetCurrentContextBinding(
absl::Status GlContext::SetCurrentContextBinding(
const ContextBinding& new_binding) {
if (new_binding.context) {
[new_binding.context makeCurrentContext];
} else {
[NSOpenGLContext clearCurrentContext];
}
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
bool GlContext::HasContext() const { return context_ != nil; }
+13 -10
View File
@@ -46,7 +46,7 @@ GlContext::StatusOrGlContext GlContext::Create(
return std::move(context);
}
::mediapipe::Status GlContext::CreateContextInternal(
absl::Status GlContext::CreateContextInternal(
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE external_context, int webgl_version) {
CHECK(webgl_version == 1 || webgl_version == 2);
@@ -58,9 +58,12 @@ GlContext::StatusOrGlContext GlContext::Create(
attrs.majorVersion = webgl_version;
attrs.minorVersion = 0;
attrs.premultipliedAlpha = 0;
// New one to try out... TODO: see if actually necessary for
// pushing resulting texture through MediaPipe pipeline.
// This flag tells the page compositor that the image written to the canvas
// uses premultiplied alpha, and so can be used directly for compositing.
// Without this, it needs to make an additional full-canvas rendering pass.
attrs.premultipliedAlpha = 1;
// TODO: Investigate this option in more detail, esp. on Safari.
attrs.preserveDrawingBuffer = 0;
// Since the Emscripten canvas target finding function is visible from here,
@@ -124,10 +127,10 @@ GlContext::StatusOrGlContext GlContext::Create(
// GLES 2 does not have them, so let's set the major version here at least.
// WebGL 1.0 maps to GLES 2.0 and WebGL 2.0 maps to GLES 3.0, so we add 1.
gl_major_version_ = webgl_version + 1;
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status GlContext::CreateContext(
absl::Status GlContext::CreateContext(
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE external_context) {
// TODO: If we're given a non-0 external_context, could try to use
// that directly, since we're assuming a single-threaded single-context
@@ -144,7 +147,7 @@ GlContext::StatusOrGlContext GlContext::Create(
LOG(INFO) << "Successfully created a WebGL context with major version "
<< gl_major_version_ << " and handle " << context_;
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
void GlContext::DestroyContext() {
@@ -177,13 +180,13 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
binding->context = emscripten_webgl_get_current_context();
}
::mediapipe::Status GlContext::SetCurrentContextBinding(
absl::Status GlContext::SetCurrentContextBinding(
const ContextBinding& new_binding) {
if (new_binding.context == 0) {
// Calling emscripten_webgl_make_context_current(0) is resulting in an error
// so don't remove context for now, only replace! In the future, can
// perhaps create a separate "do-nothing" context for this.
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
// TODO: See if setting the same context to current multiple times
// comes with a performance cost, and fix if so.
@@ -191,7 +194,7 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
emscripten_webgl_make_context_current(new_binding.context);
RET_CHECK(res == EMSCRIPTEN_RESULT_SUCCESS)
<< "emscripten_webgl_make_context_current() returned error " << res;
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
bool GlContext::HasContext() const { return context_ != 0; }
+5 -5
View File
@@ -98,7 +98,7 @@
- (void)testGlConverters {
CFHolder<CVPixelBufferRef> originalPixelBuffer;
::mediapipe::Status status =
absl::Status status =
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
XCTAssert(status.ok());
@@ -121,7 +121,7 @@
- (void)testGlConvertersNoOpInserted {
CFHolder<CVPixelBufferRef> originalPixelBuffer;
::mediapipe::Status status =
absl::Status status =
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
XCTAssert(status.ok());
@@ -149,7 +149,7 @@
- (void)testGlConvertersWithOptionalSidePackets {
CFHolder<CVPixelBufferRef> originalPixelBuffer;
::mediapipe::Status status =
absl::Status status =
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
XCTAssert(status.ok());
@@ -191,7 +191,7 @@
- (void)testSimpleConversionFromFormat:(OSType)cvPixelFormat {
CFHolder<CVPixelBufferRef> originalPixelBuffer;
::mediapipe::Status status =
absl::Status status =
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
XCTAssert(status.ok());
CVPixelBufferRef convertedPixelBuffer =
@@ -225,7 +225,7 @@
NSLog(@"Metal tests skipped on Simulator.");
#else
CFHolder<CVPixelBufferRef> originalPixelBuffer;
::mediapipe::Status status =
absl::Status status =
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
XCTAssert(status.ok());
CVPixelBufferRef redPixelBuffer = [self redPixelBuffer:*originalPixelBuffer];
+12 -11
View File
@@ -54,11 +54,11 @@ FrameRotation FrameRotationFromDegrees(int degrees_ccw) {
}
}
::mediapipe::Status QuadRenderer::GlSetup() {
absl::Status QuadRenderer::GlSetup() {
return GlSetup(kBasicTexturedFragmentShader, {"video_frame"});
}
::mediapipe::Status QuadRenderer::GlSetup(
absl::Status QuadRenderer::GlSetup(
const GLchar* custom_frag_shader,
const std::vector<const GLchar*>& custom_frame_uniforms) {
// Load vertex and fragment shaders
@@ -87,7 +87,7 @@ FrameRotation FrameRotationFromDegrees(int degrees_ccw) {
glGenVertexArrays(1, &vao_);
glGenBuffers(2, vbo_);
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
void QuadRenderer::GlTeardown() {
@@ -106,10 +106,12 @@ void QuadRenderer::GlTeardown() {
}
}
::mediapipe::Status QuadRenderer::GlRender(
float frame_width, float frame_height, float view_width, float view_height,
FrameScaleMode scale_mode, FrameRotation rotation, bool flip_horizontal,
bool flip_vertical, bool flip_texture) {
absl::Status QuadRenderer::GlRender(float frame_width, float frame_height,
float view_width, float view_height,
FrameScaleMode scale_mode,
FrameRotation rotation,
bool flip_horizontal, bool flip_vertical,
bool flip_texture) {
RET_CHECK(program_) << "Must setup the program before rendering.";
glUseProgram(program_);
@@ -195,15 +197,14 @@ void QuadRenderer::GlTeardown() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status FrameRotationFromInt(FrameRotation* rotation,
int degrees_ccw) {
absl::Status FrameRotationFromInt(FrameRotation* rotation, int degrees_ccw) {
RET_CHECK(degrees_ccw % 90 == 0) << "rotation must be a multiple of 90; "
<< degrees_ccw << " was provided";
*rotation = FrameRotationFromDegrees(degrees_ccw % 360);
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
} // namespace mediapipe
+8 -11
View File
@@ -49,13 +49,12 @@ class QuadRenderer {
QuadRenderer() {}
// Creates the rendering program. Must be called within the GL context that
// will be used for rendering.
::mediapipe::Status GlSetup();
absl::Status GlSetup();
// Creates the rendering program. Must be called within the GL context that
// will be used for rendering.
// This version allows you to customize the fragment shader.
::mediapipe::Status GlSetup(
const GLchar* custom_frag_shader,
const std::vector<const GLchar*>& custom_frame_uniforms);
absl::Status GlSetup(const GLchar* custom_frag_shader,
const std::vector<const GLchar*>& custom_frame_uniforms);
// Renders the texture bound to texture unit 1 onto the current viewport.
// Note: mirroring and flipping are handled differently, by design.
// - flip_texture is meant to be used when the texture image's rows are stored
@@ -70,11 +69,10 @@ class QuadRenderer {
// what's needed for the front-camera use case.
// - flip_vertical is meant to be used to flip the output image vertically.
// This flipping is applied AFTER rotation.
::mediapipe::Status GlRender(float frame_width, float frame_height,
float view_width, float view_height,
FrameScaleMode scale_mode,
FrameRotation rotation, bool flip_horizontal,
bool flip_vertical, bool flip_texture);
absl::Status GlRender(float frame_width, float frame_height, float view_width,
float view_height, FrameScaleMode scale_mode,
FrameRotation rotation, bool flip_horizontal,
bool flip_vertical, bool flip_texture);
// Deletes the rendering program. Must be called withn the GL context where
// it was created.
void GlTeardown();
@@ -87,8 +85,7 @@ class QuadRenderer {
GLuint vbo_[2] = {0, 0}; // for vertex buffer storage
};
::mediapipe::Status FrameRotationFromInt(FrameRotation* rotation,
int degrees_ccw);
absl::Status FrameRotationFromInt(FrameRotation* rotation, int degrees_ccw);
// Input degrees must be one of: [0, 90, 180, 270].
FrameRotation FrameRotationFromDegrees(int degrees_ccw);
+13 -13
View File
@@ -66,13 +66,13 @@ class GlScalerCalculator : public CalculatorBase {
GlScalerCalculator() {}
~GlScalerCalculator();
static ::mediapipe::Status GetContract(CalculatorContract* cc);
static absl::Status GetContract(CalculatorContract* cc);
::mediapipe::Status Open(CalculatorContext* cc) override;
::mediapipe::Status Process(CalculatorContext* cc) override;
absl::Status Open(CalculatorContext* cc) override;
absl::Status Process(CalculatorContext* cc) override;
::mediapipe::Status GlSetup();
::mediapipe::Status GlRender(const GlTexture& src, const GlTexture& dst);
absl::Status GlSetup();
absl::Status GlRender(const GlTexture& src, const GlTexture& dst);
void GetOutputDimensions(int src_width, int src_height, int* dst_width,
int* dst_height);
void GetOutputPadding(int src_width, int src_height, int dst_width,
@@ -98,7 +98,7 @@ class GlScalerCalculator : public CalculatorBase {
REGISTER_CALCULATOR(GlScalerCalculator);
// static
::mediapipe::Status GlScalerCalculator::GetContract(CalculatorContract* cc) {
absl::Status GlScalerCalculator::GetContract(CalculatorContract* cc) {
TagOrIndex(&cc->Inputs(), "VIDEO", 0).Set<GpuBuffer>();
TagOrIndex(&cc->Outputs(), "VIDEO", 0).Set<GpuBuffer>();
if (cc->Inputs().HasTag("ROTATION")) {
@@ -126,10 +126,10 @@ REGISTER_CALCULATOR(GlScalerCalculator);
cc->Outputs().Tag("TOP_BOTTOM_PADDING").Set<float>();
cc->Outputs().Tag("LEFT_RIGHT_PADDING").Set<float>();
}
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status GlScalerCalculator::Open(CalculatorContext* cc) {
absl::Status GlScalerCalculator::Open(CalculatorContext* cc) {
// Inform the framework that we always output at the same timestamp
// as we receive a packet at.
cc->SetOffset(mediapipe::TimestampDiff(0));
@@ -181,14 +181,14 @@ REGISTER_CALCULATOR(GlScalerCalculator);
MP_RETURN_IF_ERROR(FrameRotationFromInt(&rotation_, rotation_ccw));
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status GlScalerCalculator::Process(CalculatorContext* cc) {
absl::Status GlScalerCalculator::Process(CalculatorContext* cc) {
if (cc->Inputs().HasTag("OUTPUT_DIMENSIONS")) {
if (cc->Inputs().Tag("OUTPUT_DIMENSIONS").IsEmpty()) {
// OUTPUT_DIMENSIONS input stream is specified, but value is missing.
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
const auto& dimensions =
@@ -197,7 +197,7 @@ REGISTER_CALCULATOR(GlScalerCalculator);
dst_height_ = dimensions[1];
}
return helper_.RunInGlContext([this, cc]() -> ::mediapipe::Status {
return helper_.RunInGlContext([this, cc]() -> absl::Status {
const auto& input = TagOrIndex(cc->Inputs(), "VIDEO", 0).Get<GpuBuffer>();
QuadRenderer* renderer = nullptr;
GlTexture src1;
@@ -294,7 +294,7 @@ REGISTER_CALCULATOR(GlScalerCalculator);
TagOrIndex(&cc->Outputs(), "VIDEO", 0)
.Add(output.release(), cc->InputTimestamp());
return ::mediapipe::OkStatus();
return absl::OkStatus();
});
}
+7 -8
View File
@@ -17,7 +17,7 @@
namespace mediapipe {
// static
::mediapipe::Status GlSimpleCalculator::GetContract(CalculatorContract* cc) {
absl::Status GlSimpleCalculator::GetContract(CalculatorContract* cc) {
TagOrIndex(&cc->Inputs(), "VIDEO", 0).Set<GpuBuffer>();
TagOrIndex(&cc->Outputs(), "VIDEO", 0).Set<GpuBuffer>();
// Currently we pass GL context information and other stuff as external
@@ -25,7 +25,7 @@ namespace mediapipe {
return GlCalculatorHelper::UpdateContract(cc);
}
::mediapipe::Status GlSimpleCalculator::Open(CalculatorContext* cc) {
absl::Status GlSimpleCalculator::Open(CalculatorContext* cc) {
// Inform the framework that we always output at the same timestamp
// as we receive a packet at.
cc->SetOffset(mediapipe::TimestampDiff(0));
@@ -34,8 +34,8 @@ namespace mediapipe {
return helper_.Open(cc);
}
::mediapipe::Status GlSimpleCalculator::Process(CalculatorContext* cc) {
return RunInGlContext([this, cc]() -> ::mediapipe::Status {
absl::Status GlSimpleCalculator::Process(CalculatorContext* cc) {
return RunInGlContext([this, cc]() -> absl::Status {
const auto& input = TagOrIndex(cc->Inputs(), "VIDEO", 0).Get<GpuBuffer>();
if (!initialized_) {
MP_RETURN_IF_ERROR(GlSetup());
@@ -69,13 +69,12 @@ namespace mediapipe {
TagOrIndex(&cc->Outputs(), "VIDEO", 0)
.Add(output.release(), cc->InputTimestamp());
return ::mediapipe::OkStatus();
return absl::OkStatus();
});
}
::mediapipe::Status GlSimpleCalculator::Close(CalculatorContext* cc) {
return RunInGlContext(
[this]() -> ::mediapipe::Status { return GlTeardown(); });
absl::Status GlSimpleCalculator::Close(CalculatorContext* cc) {
return RunInGlContext([this]() -> absl::Status { return GlTeardown(); });
}
} // namespace mediapipe
+8 -9
View File
@@ -53,30 +53,29 @@ class GlSimpleCalculator : public CalculatorBase {
GlSimpleCalculator& operator=(const GlSimpleCalculator&) = delete;
~GlSimpleCalculator() override = default;
static ::mediapipe::Status GetContract(CalculatorContract* cc);
::mediapipe::Status Open(CalculatorContext* cc) override;
::mediapipe::Status Process(CalculatorContext* cc) override;
::mediapipe::Status Close(CalculatorContext* cc) override;
static absl::Status GetContract(CalculatorContract* cc);
absl::Status Open(CalculatorContext* cc) override;
absl::Status Process(CalculatorContext* cc) override;
absl::Status Close(CalculatorContext* cc) override;
// This method is called once on the first frame. Use it to setup any objects
// that will be reused throughout the calculator's life.
virtual ::mediapipe::Status GlSetup() = 0;
virtual absl::Status GlSetup() = 0;
// You can use this optional method to do any pre-rendering setup that needs
// to be redone after the context has been used by another calculator.
// If your context is not shared, it will only be called once.
virtual ::mediapipe::Status GlBind() { return ::mediapipe::OkStatus(); }
virtual absl::Status GlBind() { return absl::OkStatus(); }
// Do your rendering here. The source and destination textures have already
// been created and bound for you.
// - src: source texture (contains input frame); already bound to GL_TEXTURE1.
// - dst: destination texture (write output frame here); already bound to
// GL_TEXTURE0 and attached to the framebuffer.
virtual ::mediapipe::Status GlRender(const GlTexture& src,
const GlTexture& dst) = 0;
virtual absl::Status GlRender(const GlTexture& src, const GlTexture& dst) = 0;
// The method is called to delete all the programs.
virtual ::mediapipe::Status GlTeardown() = 0;
virtual absl::Status GlTeardown() = 0;
// You can override this method to compute the size of the destination
// texture. By default, it will take the same size as the source texture.
+9 -10
View File
@@ -42,10 +42,10 @@ class GlSurfaceSinkCalculator : public CalculatorBase {
GlSurfaceSinkCalculator() : initialized_(false) {}
~GlSurfaceSinkCalculator() override;
static ::mediapipe::Status GetContract(CalculatorContract* cc);
static absl::Status GetContract(CalculatorContract* cc);
::mediapipe::Status Open(CalculatorContext* cc) override;
::mediapipe::Status Process(CalculatorContext* cc) override;
absl::Status Open(CalculatorContext* cc) override;
absl::Status Process(CalculatorContext* cc) override;
private:
GlCalculatorHelper helper_;
@@ -57,8 +57,7 @@ class GlSurfaceSinkCalculator : public CalculatorBase {
REGISTER_CALCULATOR(GlSurfaceSinkCalculator);
// static
::mediapipe::Status GlSurfaceSinkCalculator::GetContract(
CalculatorContract* cc) {
absl::Status GlSurfaceSinkCalculator::GetContract(CalculatorContract* cc) {
TagOrIndex(&(cc->Inputs()), "VIDEO", 0).Set<GpuBuffer>();
cc->InputSidePackets()
.Tag("SURFACE")
@@ -68,7 +67,7 @@ REGISTER_CALCULATOR(GlSurfaceSinkCalculator);
return GlCalculatorHelper::UpdateContract(cc);
}
::mediapipe::Status GlSurfaceSinkCalculator::Open(CalculatorContext* cc) {
absl::Status GlSurfaceSinkCalculator::Open(CalculatorContext* cc) {
surface_holder_ = cc->InputSidePackets()
.Tag("SURFACE")
.Get<std::unique_ptr<EglSurfaceHolder>>()
@@ -82,13 +81,13 @@ REGISTER_CALCULATOR(GlSurfaceSinkCalculator);
return helper_.Open(cc);
}
::mediapipe::Status GlSurfaceSinkCalculator::Process(CalculatorContext* cc) {
return helper_.RunInGlContext([this, &cc]() -> ::mediapipe::Status {
absl::Status GlSurfaceSinkCalculator::Process(CalculatorContext* cc) {
return helper_.RunInGlContext([this, &cc]() -> absl::Status {
absl::MutexLock lock(&surface_holder_->mutex);
EGLSurface surface = surface_holder_->surface;
if (surface == EGL_NO_SURFACE) {
LOG_EVERY_N(INFO, 300) << "GlSurfaceSinkCalculator: no surface";
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
const auto& input = TagOrIndex(cc->Inputs(), "VIDEO", 0).Get<GpuBuffer>();
@@ -139,7 +138,7 @@ REGISTER_CALCULATOR(GlSurfaceSinkCalculator);
RET_CHECK(success) << "failed to restore old surface";
src.Release();
return ::mediapipe::OkStatus();
return absl::OkStatus();
});
}
+2 -1
View File
@@ -63,7 +63,8 @@ bool GlTextureBuffer::CreateInternal(const void* data) {
if (!name_) return false;
glBindTexture(target_, name_);
GlTextureInfo info = GlTextureInfoForGpuBufferFormat(format_, 0);
GlTextureInfo info =
GlTextureInfoForGpuBufferFormat(format_, 0, context->GetGlVersion());
// See b/70294573 for details about this.
if (info.gl_internal_format == GL_RGBA16F &&
+1 -10
View File
@@ -37,6 +37,7 @@ static void AdaptGlTextureInfoForGLES2(GlTextureInfo* info) {
info->gl_internal_format = info->gl_format = GL_LUMINANCE;
return;
case GL_RG16F:
case GL_RG32F:
// Should this be GL_RG_EXT instead?
info->gl_internal_format = info->gl_format = GL_LUMINANCE_ALPHA;
return;
@@ -52,16 +53,6 @@ static void AdaptGlTextureInfoForGLES2(GlTextureInfo* info) {
}
#endif // GL_ES_VERSION_2_0
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
int plane) {
#if defined(__APPLE__) && TARGET_OS_OSX
constexpr GlVersion default_version = GlVersion::kGL;
#else
constexpr GlVersion default_version = GlVersion::kGLES3;
#endif // defined(__APPLE__) && TARGET_OS_OSX
return GlTextureInfoForGpuBufferFormat(format, plane, default_version);
}
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
int plane,
GlVersion gl_version) {
-2
View File
@@ -63,8 +63,6 @@ struct GlTextureInfo {
int downscale;
};
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
int plane);
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
int plane,
GlVersion gl_version);
+1 -1
View File
@@ -82,7 +82,7 @@ class GpuBufferMultiPool {
std::size_t operator()(const BufferSpec& spec) const {
// Width and height are expected to be smaller than half the width of
// size_t. We can combine them into a single integer, and then use
// std::hash, which is what go/hashing recommends for hashing numbers.
// std::hash.
constexpr int kWidth = std::numeric_limits<size_t>::digits;
return std::hash<std::size_t>{}(
spec.width ^ RotateLeft(spec.height, kWidth / 2) ^
@@ -31,10 +31,10 @@ class GpuBufferToImageFrameCalculator : public CalculatorBase {
public:
GpuBufferToImageFrameCalculator() {}
static ::mediapipe::Status GetContract(CalculatorContract* cc);
static absl::Status GetContract(CalculatorContract* cc);
::mediapipe::Status Open(CalculatorContext* cc) override;
::mediapipe::Status Process(CalculatorContext* cc) override;
absl::Status Open(CalculatorContext* cc) override;
absl::Status Process(CalculatorContext* cc) override;
private:
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
@@ -44,7 +44,7 @@ class GpuBufferToImageFrameCalculator : public CalculatorBase {
REGISTER_CALCULATOR(GpuBufferToImageFrameCalculator);
// static
::mediapipe::Status GpuBufferToImageFrameCalculator::GetContract(
absl::Status GpuBufferToImageFrameCalculator::GetContract(
CalculatorContract* cc) {
cc->Inputs().Index(0).SetAny();
cc->Outputs().Index(0).Set<ImageFrame>();
@@ -52,25 +52,23 @@ REGISTER_CALCULATOR(GpuBufferToImageFrameCalculator);
// to ensure the calculator's contract is the same. In particular, the helper
// enables support for the legacy side packet, which several graphs still use.
MP_RETURN_IF_ERROR(GlCalculatorHelper::UpdateContract(cc));
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status GpuBufferToImageFrameCalculator::Open(
CalculatorContext* cc) {
absl::Status GpuBufferToImageFrameCalculator::Open(CalculatorContext* cc) {
// Inform the framework that we always output at the same timestamp
// as we receive a packet at.
cc->SetOffset(TimestampDiff(0));
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
MP_RETURN_IF_ERROR(helper_.Open(cc));
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status GpuBufferToImageFrameCalculator::Process(
CalculatorContext* cc) {
absl::Status GpuBufferToImageFrameCalculator::Process(CalculatorContext* cc) {
if (cc->Inputs().Index(0).Value().ValidateAsType<ImageFrame>().ok()) {
cc->Outputs().Index(0).AddPacket(cc->Inputs().Index(0).Value());
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
#ifdef HAVE_GPU_BUFFER
@@ -87,7 +85,8 @@ REGISTER_CALCULATOR(GpuBufferToImageFrameCalculator);
ImageFormatForGpuBufferFormat(input.format()), src.width(),
src.height(), ImageFrame::kGlDefaultAlignmentBoundary);
helper_.BindFramebuffer(src);
const auto info = GlTextureInfoForGpuBufferFormat(input.format(), 0);
const auto info = GlTextureInfoForGpuBufferFormat(input.format(), 0,
helper_.GetGlVersion());
glReadPixels(0, 0, src.width(), src.height(), info.gl_format,
info.gl_type, frame->MutablePixelData());
glFlush();
@@ -95,12 +94,12 @@ REGISTER_CALCULATOR(GpuBufferToImageFrameCalculator);
src.Release();
});
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
#endif // defined(HAVE_GPU_BUFFER)
return ::mediapipe::Status(::mediapipe::StatusCode::kInvalidArgument,
"Input packets must be ImageFrame or GpuBuffer.");
return absl::Status(absl::StatusCode::kInvalidArgument,
"Input packets must be ImageFrame or GpuBuffer.");
}
} // namespace mediapipe
+1 -1
View File
@@ -104,7 +104,7 @@ GpuResources::~GpuResources() {
#endif
}
mediapipe::Status GpuResources::PrepareGpuNode(CalculatorNode* node) {
absl::Status GpuResources::PrepareGpuNode(CalculatorNode* node) {
CHECK(node->UsesGpu());
std::string node_id = node->GetCalculatorState().NodeName();
std::string node_type = node->GetCalculatorState().CalculatorType();
+3 -4
View File
@@ -42,8 +42,7 @@ namespace mediapipe {
// TODO: rename to GpuService or GpuManager or something.
class GpuResources {
public:
using StatusOrGpuResources =
::mediapipe::StatusOr<std::shared_ptr<GpuResources>>;
using StatusOrGpuResources = absl::StatusOr<std::shared_ptr<GpuResources>>;
static StatusOrGpuResources Create();
static StatusOrGpuResources Create(PlatformGlContext external_context);
@@ -69,7 +68,7 @@ class GpuResources {
MPPGraphGPUData* ios_gpu_data();
#endif // defined(__APPLE__)§
mediapipe::Status PrepareGpuNode(CalculatorNode* node);
absl::Status PrepareGpuNode(CalculatorNode* node);
// If the node requires custom GPU executors in the current configuration,
// returns the executor's names and the executors themselves.
@@ -124,7 +123,7 @@ struct GpuSharedData {
auto status_or_resources = GpuResources::Create(external_context);
MEDIAPIPE_CHECK_OK(status_or_resources.status())
<< ": could not create GpuResources";
return std::move(status_or_resources).ValueOrDie();
return std::move(status_or_resources).value();
}
};
@@ -28,10 +28,10 @@ class ImageFrameToGpuBufferCalculator : public CalculatorBase {
public:
ImageFrameToGpuBufferCalculator() {}
static ::mediapipe::Status GetContract(CalculatorContract* cc);
static absl::Status GetContract(CalculatorContract* cc);
::mediapipe::Status Open(CalculatorContext* cc) override;
::mediapipe::Status Process(CalculatorContext* cc) override;
absl::Status Open(CalculatorContext* cc) override;
absl::Status Process(CalculatorContext* cc) override;
private:
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
@@ -41,7 +41,7 @@ class ImageFrameToGpuBufferCalculator : public CalculatorBase {
REGISTER_CALCULATOR(ImageFrameToGpuBufferCalculator);
// static
::mediapipe::Status ImageFrameToGpuBufferCalculator::GetContract(
absl::Status ImageFrameToGpuBufferCalculator::GetContract(
CalculatorContract* cc) {
cc->Inputs().Index(0).Set<ImageFrame>();
cc->Outputs().Index(0).Set<GpuBuffer>();
@@ -49,22 +49,20 @@ REGISTER_CALCULATOR(ImageFrameToGpuBufferCalculator);
// to ensure the calculator's contract is the same. In particular, the helper
// enables support for the legacy side packet, which several graphs still use.
MP_RETURN_IF_ERROR(GlCalculatorHelper::UpdateContract(cc));
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status ImageFrameToGpuBufferCalculator::Open(
CalculatorContext* cc) {
absl::Status ImageFrameToGpuBufferCalculator::Open(CalculatorContext* cc) {
// Inform the framework that we always output at the same timestamp
// as we receive a packet at.
cc->SetOffset(TimestampDiff(0));
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
MP_RETURN_IF_ERROR(helper_.Open(cc));
#endif // !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
::mediapipe::Status ImageFrameToGpuBufferCalculator::Process(
CalculatorContext* cc) {
absl::Status ImageFrameToGpuBufferCalculator::Process(CalculatorContext* cc) {
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
CFHolder<CVPixelBufferRef> buffer;
MP_RETURN_IF_ERROR(CreateCVPixelBufferForImageFramePacket(
@@ -80,7 +78,7 @@ REGISTER_CALCULATOR(ImageFrameToGpuBufferCalculator);
src.Release();
});
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
return ::mediapipe::OkStatus();
return absl::OkStatus();
}
} // namespace mediapipe