diff --git a/Assets/MediaPipe/SDK/Scripts/Core/MediaPipePluginException.cs b/Assets/MediaPipe/SDK/Scripts/Core/MediaPipePluginException.cs new file mode 100644 index 000000000..f9edcd90b --- /dev/null +++ b/Assets/MediaPipe/SDK/Scripts/Core/MediaPipePluginException.cs @@ -0,0 +1,7 @@ +using System; + +namespace Mediapipe { + public class MediaPipePluginException : ApplicationException { + public MediaPipePluginException(string message) : base(message) {} + } +} diff --git a/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Safe.cs.meta b/Assets/MediaPipe/SDK/Scripts/Core/MediaPipePluginException.cs.meta similarity index 83% rename from Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Safe.cs.meta rename to Assets/MediaPipe/SDK/Scripts/Core/MediaPipePluginException.cs.meta index afbb72006..d4bd2d02b 100644 --- a/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Safe.cs.meta +++ b/Assets/MediaPipe/SDK/Scripts/Core/MediaPipePluginException.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d3405497c2137c582a953b552e0d9066 +guid: e17a1d893e9d74c4eb7e85860d115c02 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/MediaPipe/SDK/Scripts/Framework/BoolPacket.cs b/Assets/MediaPipe/SDK/Scripts/Framework/BoolPacket.cs index 2bf692abc..0a14dac29 100644 --- a/Assets/MediaPipe/SDK/Scripts/Framework/BoolPacket.cs +++ b/Assets/MediaPipe/SDK/Scripts/Framework/BoolPacket.cs @@ -11,8 +11,16 @@ public BoolPacket(bool value) : base() { this.ptr = ptr; } + public BoolPacket(bool value, Timestamp timestamp) : base() { + UnsafeNativeMethods.mp__MakeBoolPacket_At__b_Rtimestamp(value, timestamp.mpPtr, out var ptr).Assert(); + this.ptr = ptr; + } + public override bool Get() { - return SafeNativeMethods.mp_Packet__GetBool(ptr); + UnsafeNativeMethods.mp_Packet__GetBool(mpPtr, out var value).Assert(); + + GC.KeepAlive(this); + return value; } public override bool Consume() { diff --git a/Assets/MediaPipe/SDK/Scripts/PInvoke/MpReturnCode.cs b/Assets/MediaPipe/SDK/Scripts/PInvoke/MpReturnCode.cs index 6193d39b3..2e9d46b14 100644 --- a/Assets/MediaPipe/SDK/Scripts/PInvoke/MpReturnCode.cs +++ b/Assets/MediaPipe/SDK/Scripts/PInvoke/MpReturnCode.cs @@ -1,17 +1,27 @@ namespace Mediapipe { public enum MpReturnCode : int { Success = 0, + /// A standard exception is thrown StandardError = 1, - UnknownError = 2, + /// Something other than standard exception is thrown + UnknownError = 70, + /// SDK failed to set status code (bug) + Unset = 128, // + /// Received SIGABRT + Aborted = 134, } public static class MpReturnCodeExtension { public static void Assert(this MpReturnCode code) { - if (code == MpReturnCode.Success) { - return; + switch (code) { + case MpReturnCode.Success: return; + case MpReturnCode.Aborted: { + throw new MediaPipeException("MediaPipe Aborted, refer glog files for more details"); + } + default: { + throw new MediaPipePluginException($"Failed to call a native function (code={code}"); + } } - - throw new MediaPipeException($"Failed to call a native method (code={code})"); } } } diff --git a/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Safe.cs b/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Safe.cs deleted file mode 100644 index c728ead40..000000000 --- a/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Safe.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Diagnostics.Contracts; -using System.Runtime.InteropServices; - -namespace Mediapipe { - internal static partial class SafeNativeMethods { - [Pure, DllImport (MediaPipeLibrary, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.I1)] - public static extern bool mp_Packet__GetBool(IntPtr packet); - } -} diff --git a/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Unsafe.cs b/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Unsafe.cs index 885b1e923..a3c015d8f 100644 --- a/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Unsafe.cs +++ b/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Unsafe.cs @@ -32,5 +32,11 @@ internal static partial class UnsafeNativeMethods { [DllImport (MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode mp__MakeBoolPacket__b([MarshalAs(UnmanagedType.I1)] bool value, out IntPtr packet); + + [DllImport (MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp__MakeBoolPacket_At__b_Rtimestamp([MarshalAs(UnmanagedType.I1)] bool value, IntPtr timestamp, out IntPtr packet); + + [DllImport (MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp_Packet__GetBool(IntPtr packet, [MarshalAs(UnmanagedType.I1)]out bool value); } } diff --git a/C/mediapipe_api/BUILD b/C/mediapipe_api/BUILD index 3eb6f420e..a85f9a4a4 100644 --- a/C/mediapipe_api/BUILD +++ b/C/mediapipe_api/BUILD @@ -73,11 +73,13 @@ cc_library( cc_library( name = "common", + srcs = ["common.cc"], hdrs = ["common.h"], deps = [ "@com_google_mediapipe//mediapipe/framework/port:logging", ], visibility = ["//visibility:public"], + alwayslink = True, ) pkg_model( diff --git a/C/mediapipe_api/common.cc b/C/mediapipe_api/common.cc new file mode 100644 index 000000000..664f5834f --- /dev/null +++ b/C/mediapipe_api/common.cc @@ -0,0 +1,29 @@ +#include "mediapipe_api/common.h" + +namespace { + thread_local struct sigaction orig_act; + thread_local sigjmp_buf abrt_jbuf; + + void sigabrt_handler(int sig) { + siglongjmp(abrt_jbuf, 1); + } +} + +bool sigabrt_is_not_received() { + return sigsetjmp(abrt_jbuf, 1) == 0; +} + +void setup_sigaction() { + struct sigaction act; + + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = sigabrt_handler; + + sigaction(SIGABRT, &act, &orig_act); +} + +void restore_sigaction() { + sigaction(SIGABRT, &orig_act, nullptr); +} + diff --git a/C/mediapipe_api/common.h b/C/mediapipe_api/common.h index 8235d9156..0558d7643 100644 --- a/C/mediapipe_api/common.h +++ b/C/mediapipe_api/common.h @@ -7,6 +7,8 @@ #define MP_CAPI_EXPORT #endif +#include +#include #include #include "mediapipe/framework/port/logging.h" @@ -22,19 +24,38 @@ extern inline const char* strcpy_to_heap(const std::string& str) { enum class MpReturnCode : int { Success = 0, StandardError = 1, - UnknownError = 2 + UnknownError = 70, + Unset = 128, + Aborted = 134, }; -#define TRY try -#define CATCH_ALL catch (std::exception& e) {\ - LOG(ERROR) << e.what();\ - google::FlushLogFiles(google::ERROR);\ - return MpReturnCode::StandardError;\ - } catch (...) {\ - LOG(ERROR) << "Unknown exception";\ - google::FlushLogFiles(google::ERROR);\ - return MpReturnCode::UnknownError;\ - } +bool sigabrt_is_not_received(); +void setup_sigaction(); +void restore_sigaction(); + +// TODO(homuler): make code more readable +#define TRY auto _mp_return_code = MpReturnCode::Unset;\ + try +#define CATCH_EXCEPTION catch (std::exception& e) {\ + LOG(ERROR) << e.what();\ + google::FlushLogFiles(google::ERROR);\ + _mp_return_code = MpReturnCode::StandardError;\ + } catch (...) {\ + LOG(ERROR) << "Unknown exception";\ + google::FlushLogFiles(google::ERROR);\ + _mp_return_code = MpReturnCode::UnknownError;\ + }\ + return _mp_return_code; + +#define TRY_ALL TRY {\ + setup_sigaction();\ + if (sigabrt_is_not_received()) +#define CATCH_ALL else {\ + _mp_return_code = MpReturnCode::Aborted;\ + }\ + restore_sigaction();\ + } CATCH_EXCEPTION +#define RETURN_CODE(code) _mp_return_code = code #define MP_CAPI(rettype) MP_CAPI_EXPORT extern rettype #endif // C_MEDIAPIPE_API_COMMON_H_ diff --git a/C/mediapipe_api/external/protobuf.cc b/C/mediapipe_api/external/protobuf.cc index 5066025f2..f249413dd 100644 --- a/C/mediapipe_api/external/protobuf.cc +++ b/C/mediapipe_api/external/protobuf.cc @@ -16,8 +16,8 @@ MpReturnCode google_protobuf__SetLogHandler__PF(LogHandler* handler) { TRY { logHandler = handler; google::protobuf::SetLogHandler(&HandleProtobufLog); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } void MpSerializedProtoDestroy(MpSerializedProto* proto) { diff --git a/C/mediapipe_api/framework/calculator.cc b/C/mediapipe_api/framework/calculator.cc index 830da0f46..3226daae2 100644 --- a/C/mediapipe_api/framework/calculator.cc +++ b/C/mediapipe_api/framework/calculator.cc @@ -8,8 +8,8 @@ MpReturnCode google_protobuf_TextFormat__ParseFromStringAsCalculatorGraphConfig_ auto result = google::protobuf::TextFormat::ParseFromString(input, config); *config_out = result ? config : nullptr; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } void mp_CalculatorGraphConfig__delete(mediapipe::CalculatorGraphConfig* config) { diff --git a/C/mediapipe_api/framework/packet.cc b/C/mediapipe_api/framework/packet.cc index 7d7345b6d..27c56f7f7 100644 --- a/C/mediapipe_api/framework/packet.cc +++ b/C/mediapipe_api/framework/packet.cc @@ -5,8 +5,8 @@ MpReturnCode mp_Packet__(mediapipe::Packet** packet_out) { TRY { *packet_out = new mediapipe::Packet(); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } void mp_Packet__delete(mediapipe::Packet* packet) { @@ -15,62 +15,73 @@ void mp_Packet__delete(mediapipe::Packet* packet) { MpReturnCode mp_Packet__At__Rtimestamp(mediapipe::Packet* packet, mediapipe::Timestamp* timestamp, mediapipe::Packet** packet_out) { TRY { + // not move but copy *packet_out = new mediapipe::Packet { packet->At(*timestamp) }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Packet__ValidateAsProtoMessageLite(mediapipe::Packet* packet, mediapipe::Status** status_out) { TRY { *status_out = new mediapipe::Status { packet->ValidateAsProtoMessageLite() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Packet__Timestamp(mediapipe::Packet* packet, mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { packet->Timestamp() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Packet__DebugString(mediapipe::Packet* packet, const char** str_out) { TRY { *str_out = strcpy_to_heap(packet->DebugString()); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Packet__RegisteredTypeName(mediapipe::Packet* packet, const char** str_out) { TRY { *str_out = strcpy_to_heap(packet->RegisteredTypeName()); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Packet__DebugTypeName(mediapipe::Packet* packet, const char** str_out) { TRY { *str_out = strcpy_to_heap(packet->DebugTypeName()); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp__MakeBoolPacket__b(bool value, mediapipe::Packet** packet_out) { TRY { - *packet_out = new mediapipe::Packet(mediapipe::MakePacket(value)); - return MpReturnCode::Success; - } CATCH_ALL + *packet_out = new mediapipe::Packet { mediapipe::MakePacket(value) }; + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } -bool mp_Packet__GetBool(mediapipe::Packet* packet) { - return packet->Get(); +MpReturnCode mp__MakeBoolPacket_At__b_Rtimestamp(bool value, mediapipe::Timestamp* timestamp, mediapipe::Packet** packet_out) { + TRY { + *packet_out = new mediapipe::Packet { mediapipe::MakePacket(value).At(*timestamp) }; + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION +} + +MpReturnCode mp_Packet__GetBool(mediapipe::Packet* packet, bool* value_out) { + TRY_ALL { + *value_out = packet->Get(); + RETURN_CODE(MpReturnCode::Success); + } CATCH_ALL } MpReturnCode mp_Packet__ValidateAsBool(mediapipe::Packet* packet, mediapipe::Status** status_out) { TRY { *status_out = new mediapipe::Status { packet->ValidateAsType() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpPacket* MpMakeFloatPacket(float value) { @@ -99,8 +110,8 @@ const char* MpPacketGetString(MpPacket* packet) { MpReturnCode mp_SidePacket__(SidePacket** side_packet_out) { TRY { *side_packet_out = new SidePacket(); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } void mp_SidePacket__delete(SidePacket* side_packet) { @@ -110,6 +121,6 @@ void mp_SidePacket__delete(SidePacket* side_packet) { MpReturnCode mp_SidePacket__emplace(SidePacket* side_packet, const char* key, mediapipe::Packet* packet) { TRY { side_packet->emplace(std::string(key), *packet); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } diff --git a/C/mediapipe_api/framework/packet.h b/C/mediapipe_api/framework/packet.h index 4cf1f19a1..05b450485 100644 --- a/C/mediapipe_api/framework/packet.h +++ b/C/mediapipe_api/framework/packet.h @@ -43,7 +43,8 @@ MP_CAPI(MpReturnCode) mp_Packet__DebugTypeName(mediapipe::Packet* packet, const // Boolean MP_CAPI(MpReturnCode) mp__MakeBoolPacket__b(bool value, mediapipe::Packet** packet_out); -MP_CAPI(bool) mp_Packet__GetBool(mediapipe::Packet* packet); +MP_CAPI(MpReturnCode) mp__MakeBoolPacket_At__b_Rtimestamp(bool value, mediapipe::Timestamp* timestamp, mediapipe::Packet** packet_out); +MP_CAPI(MpReturnCode) mp_Packet__GetBool(mediapipe::Packet* packet, bool* value_out); MP_CAPI(MpReturnCode) mp_Packet__ValidateAsBool(mediapipe::Packet* packet, mediapipe::Status** status_out); // Float diff --git a/C/mediapipe_api/framework/port/status.cc b/C/mediapipe_api/framework/port/status.cc index 7cd3b7b4f..fef536865 100644 --- a/C/mediapipe_api/framework/port/status.cc +++ b/C/mediapipe_api/framework/port/status.cc @@ -5,8 +5,8 @@ MpReturnCode mp_Status__i_PKc(int code, const char* message, mediapipe::Status** TRY { auto status_code = static_cast(code); *status_out = new mediapipe::Status { status_code, message }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } void mp_Status__delete(mediapipe::Status* status) { @@ -16,8 +16,8 @@ void mp_Status__delete(mediapipe::Status* status) { MpReturnCode mp_Status__ToString(mediapipe::Status* status, const char** str_out) { TRY { *str_out = strcpy_to_heap(status->ToString()); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } bool mp_Status__ok(mediapipe::Status* status) { diff --git a/C/mediapipe_api/framework/timestamp.cc b/C/mediapipe_api/framework/timestamp.cc index d244c7d03..c90fcf312 100644 --- a/C/mediapipe_api/framework/timestamp.cc +++ b/C/mediapipe_api/framework/timestamp.cc @@ -3,8 +3,8 @@ MpReturnCode mp_Timestamp__l(int64 timestamp, mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp(timestamp); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } void mp_Timestamp__delete(mediapipe::Timestamp* timestamp) { @@ -26,8 +26,8 @@ int64 mp_Timestamp__Microseconds(mediapipe::Timestamp* timestamp) { MpReturnCode mp_Timestamp__DebugString(mediapipe::Timestamp* timestamp, const char** str_out) { TRY { *str_out = strcpy_to_heap(timestamp->DebugString()); - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } bool mp_Timestamp__IsSpecialValue(mediapipe::Timestamp* timestamp) { @@ -45,76 +45,76 @@ bool mp_Timestamp__IsAllowedInStream(mediapipe::Timestamp* timestamp) { MpReturnCode mp_Timestamp__NextAllowedInStream(mediapipe::Timestamp* timestamp, mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { timestamp->NextAllowedInStream() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp__PreviousAllowedInStream(mediapipe::Timestamp* timestamp, mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { timestamp->PreviousAllowedInStream() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_FromSeconds__d(double seconds, mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::FromSeconds(seconds) }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_Unset(mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::Unset() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_Unstarted(mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::Unstarted() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_PreStream(mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::PreStream() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_Min(mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::Min() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_Max(mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::Max() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_PostStream(mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::PostStream() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_OneOverPostStream(mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::OneOverPostStream() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION } MpReturnCode mp_Timestamp_Done(mediapipe::Timestamp** timestamp_out) { TRY { *timestamp_out = new mediapipe::Timestamp { mediapipe::Timestamp::Done() }; - return MpReturnCode::Success; - } CATCH_ALL + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION }