From e9eb33021d75959565b63ef42bba2c1860296a61 Mon Sep 17 00:00:00 2001 From: Speykious Date: Tue, 28 Sep 2021 03:59:26 +0200 Subject: [PATCH] Fix remaining bugs of the library (#29) * Starting to fix every literal bug of the lib * Removed protofiles as they should be downloaded automatically through the build script * Tried to reintegrate mediapipe_api, third_party and build.py... Still doesn't build * Added another missing Assert() * Added *another* other missing Assert() * Remove CharSet attribute The `CharSet = CharSet.Unicode` was making the test fail. * Remove CharSet attribute on google logging unsafe native methods * Mismatch: MpPtr * D: * Added StandardError enum * Re-add opencv flags and disable Windows again * Make SignalAbortAttribute filterable Co-authored-by: Capuccino --- .github/workflows/ci.yml | 6 +- build.py | 6 +- mediapipe_api/objc/BUILD | 4 +- protofiles/any.proto | 158 ------- protofiles/framework/calculator.proto | 430 ------------------ .../framework/calculator_contract_test.proto | 30 -- protofiles/framework/calculator_options.proto | 40 -- protofiles/framework/calculator_profile.proto | 192 -------- .../formats/annotation/rasterization.proto | 35 -- .../framework/formats/classification.proto | 42 -- protofiles/framework/formats/detection.proto | 64 --- protofiles/framework/formats/landmark.proto | 60 --- .../framework/formats/location_data.proto | 88 ---- .../framework/formats/matrix_data.proto | 40 -- protofiles/framework/formats/rect.proto | 55 --- protofiles/framework/mediapipe_options.proto | 26 -- protofiles/framework/packet_factory.proto | 48 -- protofiles/framework/packet_generator.proto | 50 -- protofiles/framework/packet_test.proto | 47 -- protofiles/framework/status_handler.proto | 43 -- protofiles/framework/stream_handler.proto | 49 -- protofiles/framework/test_calculators.proto | 34 -- .../framework/thread_pool_executor.proto | 59 --- .../sticker_buffer.proto | 30 -- .../object_detection_3d/model_matrix.proto | 48 -- .../modules/face_geometry/face_geometry.proto | 57 --- .../modules/face_geometry/mesh_3d.proto | 38 -- .../Framework/ImageFormat/ImageFrameTest.cs | 176 +++---- .../Framework/Port/StatusTest.cs | 7 + src/Akihabara.Tests/SignalAbortAttribute.cs | 5 +- src/Akihabara/Core/MpResourceHandle.cs | 4 +- .../Framework/ImageFormat/ImageFrame.cs | 32 +- src/Akihabara/Framework/Port/Status.cs | 2 +- src/Akihabara/Gpu/GpuResources.cs | 2 +- src/Akihabara/Native/MpReturnCode.cs | 5 +- src/Akihabara/Native/UnsafeNativeMethods.cs | 12 +- third_party/opencv_linux.BUILD | 32 +- 37 files changed, 161 insertions(+), 1895 deletions(-) delete mode 100644 protofiles/any.proto delete mode 100644 protofiles/framework/calculator.proto delete mode 100644 protofiles/framework/calculator_contract_test.proto delete mode 100644 protofiles/framework/calculator_options.proto delete mode 100644 protofiles/framework/calculator_profile.proto delete mode 100644 protofiles/framework/formats/annotation/rasterization.proto delete mode 100644 protofiles/framework/formats/classification.proto delete mode 100644 protofiles/framework/formats/detection.proto delete mode 100644 protofiles/framework/formats/landmark.proto delete mode 100644 protofiles/framework/formats/location_data.proto delete mode 100644 protofiles/framework/formats/matrix_data.proto delete mode 100644 protofiles/framework/formats/rect.proto delete mode 100644 protofiles/framework/mediapipe_options.proto delete mode 100644 protofiles/framework/packet_factory.proto delete mode 100644 protofiles/framework/packet_generator.proto delete mode 100644 protofiles/framework/packet_test.proto delete mode 100644 protofiles/framework/status_handler.proto delete mode 100644 protofiles/framework/stream_handler.proto delete mode 100644 protofiles/framework/test_calculators.proto delete mode 100644 protofiles/framework/thread_pool_executor.proto delete mode 100644 protofiles/graphs/instant_motion_tracking/sticker_buffer.proto delete mode 100644 protofiles/graphs/object_detection_3d/model_matrix.proto delete mode 100644 protofiles/modules/face_geometry/face_geometry.proto delete mode 100644 protofiles/modules/face_geometry/mesh_3d.proto diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 590cdc6..455b296 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: fail-fast: false matrix: os: - - { prettyname: Windows, fullname: windows-latest } + # - { prettyname: Windows, fullname: windows-latest } - { prettyname: Linux, fullname: ubuntu-latest } steps: - name: Cache Bazel directory @@ -60,13 +60,13 @@ jobs: $env:PYTHON_BIN_PATH=(Get-Command python).Path echo $env:PYTHON_BIN_PATH pip install numpy - python build.py build --desktop cpu -vv + python build.py build --desktop cpu --opencv=local -vv - name: Build (Native, *nix) if: ${{ matrix.os.prettyname != 'Windows' }} run: | pip install numpy - python build.py build --desktop cpu -vv + python build.py build --desktop cpu --opencv=cmake -vv - name: Build (.NET) run: dotnet build -c Debug src/${{env.PROJECT_NAME}}.sln diff --git a/build.py b/build.py index 257cb87..7e54eee 100644 --- a/build.py +++ b/build.py @@ -93,6 +93,7 @@ def __init__(self, command_args): self.system = platform.system() self.desktop = command_args.args.desktop + self.protobuf = command_args.args.protobuf # self.android = command_args.args.android # self.ios= command_args.args.ios self.resources = command_args.args.resources @@ -102,7 +103,6 @@ def __init__(self, command_args): self.compilation_mode = command_args.args.compilation_mode self.linkopt = command_args.args.linkopt - self.protobuf = command_args.args.protobuf def run(self): if self.protobuf: @@ -163,7 +163,7 @@ def run(self): # os.path.join(_BAZEL_BIN_PATH, 'mediapipe_api', 'objc', 'MediaPipeUnity.zip'), # os.path.join(_BUILD_PATH, 'Plugins', 'iOS')) - # self.console.info('Built native libraries for iOS') + self.console.info('Printing build path...') for root, directories, files in os.walk(_BUILD_PATH, topdown=False): @@ -325,7 +325,7 @@ def run(self): if self.ios: self.console.info('Uninstalling native libraries for iOS...') - ios_framework_path = os.path.join(_INSTALL_PATH, 'Plugins', 'iOS', 'MediaPipeUnity.framework') + ios_framework_path = os.path.join(_INSTALL_PATH, 'Plugins', 'iOS', 'Akihabara.framework') if os.path.exists(ios_framework_path): self._rmtree(ios_framework_path) diff --git a/mediapipe_api/objc/BUILD b/mediapipe_api/objc/BUILD index 146f072..2ced13c 100644 --- a/mediapipe_api/objc/BUILD +++ b/mediapipe_api/objc/BUILD @@ -19,8 +19,8 @@ objc_library( ) ios_framework( - name = "MediaPipeUnity", - bundle_id = "YOUR_BUNDLE_ID_HERE.MediaPipeUnity", + name = "Akihabara", + bundle_id = "YOUR_BUNDLE_ID_HERE.Akihabara", families = [ "iphone", "ipad", diff --git a/protofiles/any.proto b/protofiles/any.proto deleted file mode 100644 index 6ed8a23..0000000 --- a/protofiles/any.proto +++ /dev/null @@ -1,158 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package google.protobuf; - -option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option go_package = "google.golang.org/protobuf/types/known/anypb"; -option java_package = "com.google.protobuf"; -option java_outer_classname = "AnyProto"; -option java_multiple_files = true; -option objc_class_prefix = "GPB"; - -// `Any` contains an arbitrary serialized protocol buffer message along with a -// URL that describes the type of the serialized message. -// -// Protobuf library provides support to pack/unpack Any values in the form -// of utility functions or additional generated methods of the Any type. -// -// Example 1: Pack and unpack a message in C++. -// -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } -// -// Example 2: Pack and unpack a message in Java. -// -// Foo foo = ...; -// Any any = Any.pack(foo); -// ... -// if (any.is(Foo.class)) { -// foo = any.unpack(Foo.class); -// } -// -// Example 3: Pack and unpack a message in Python. -// -// foo = Foo(...) -// any = Any() -// any.Pack(foo) -// ... -// if any.Is(Foo.DESCRIPTOR): -// any.Unpack(foo) -// ... -// -// Example 4: Pack and unpack a message in Go -// -// foo := &pb.Foo{...} -// any, err := anypb.New(foo) -// if err != nil { -// ... -// } -// ... -// foo := &pb.Foo{} -// if err := any.UnmarshalTo(foo); err != nil { -// ... -// } -// -// The pack methods provided by protobuf library will by default use -// 'type.googleapis.com/full.type.name' as the type URL and the unpack -// methods only use the fully qualified type name after the last '/' -// in the type URL, for example "foo.bar.com/x/y.z" will yield type -// name "y.z". -// -// -// JSON -// ==== -// The JSON representation of an `Any` value uses the regular -// representation of the deserialized, embedded message, with an -// additional field `@type` which contains the type URL. Example: -// -// package google.profile; -// message Person { -// string first_name = 1; -// string last_name = 2; -// } -// -// { -// "@type": "type.googleapis.com/google.profile.Person", -// "firstName": , -// "lastName": -// } -// -// If the embedded message type is well-known and has a custom JSON -// representation, that representation will be embedded adding a field -// `value` which holds the custom JSON in addition to the `@type` -// field. Example (for message [google.protobuf.Duration][]): -// -// { -// "@type": "type.googleapis.com/google.protobuf.Duration", -// "value": "1.212s" -// } -// -message Any { - // A URL/resource name that uniquely identifies the type of the serialized - // protocol buffer message. This string must contain at least - // one "/" character. The last segment of the URL's path must represent - // the fully qualified name of the type (as in - // `path/google.protobuf.Duration`). The name should be in a canonical form - // (e.g., leading "." is not accepted). - // - // In practice, teams usually precompile into the binary all types that they - // expect it to use in the context of Any. However, for URLs which use the - // scheme `http`, `https`, or no scheme, one can optionally set up a type - // server that maps type URLs to message definitions as follows: - // - // * If no scheme is provided, `https` is assumed. - // * An HTTP GET on the URL must yield a [google.protobuf.Type][] - // value in binary format, or produce an error. - // * Applications are allowed to cache lookup results based on the - // URL, or have them precompiled into a binary to avoid any - // lookup. Therefore, binary compatibility needs to be preserved - // on changes to types. (Use versioned type names to manage - // breaking changes.) - // - // Note: this functionality is not currently available in the official - // protobuf release, and it is not used for type URLs beginning with - // type.googleapis.com. - // - // Schemes other than `http`, `https` (or the empty scheme) might be - // used with implementation specific semantics. - // - string type_url = 1; - - // Must be a valid serialized protocol buffer of the above specified type. - bytes value = 2; -} diff --git a/protofiles/framework/calculator.proto b/protofiles/framework/calculator.proto deleted file mode 100644 index 8c64139..0000000 --- a/protofiles/framework/calculator.proto +++ /dev/null @@ -1,430 +0,0 @@ -// 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. -// -// Forked from calculator.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. -syntax = "proto3"; - -package akihabara.framework.protobuf; - -import public "protofiles/framework/calculator_options.proto"; - -import "protofiles/any.proto"; -import "protofiles/framework/mediapipe_options.proto"; -import "protofiles/framework/packet_factory.proto"; -import "protofiles/framework/packet_generator.proto"; -import "protofiles/framework/status_handler.proto"; -import "protofiles/framework/stream_handler.proto"; - -// Describes a MediaPipe Executor. -message ExecutorConfig { - // The name of the executor (used by a CalculatorGraphConfig::Node or - // PacketGeneratorConfig to specify which executor it will execute on). - // This field must be unique within a CalculatorGraphConfig. If this field - // is omitted or is an empty string, the ExecutorConfig describes the - // default executor. - // - // NOTE: The names "default" and "gpu" are reserved and must not be used. - string name = 1; - // The registered type of the executor. For example: "ThreadPoolExecutor". - // The framework will create an executor of this type (with the options in - // the options field) for the CalculatorGraph. - // - // The ExecutorConfig for the default executor may omit this field and let - // the framework choose an appropriate executor type. Note: If the options - // field is used in this case, it should contain the - // ThreadPoolExecutorOptions. - // - // If the ExecutorConfig for an additional (non-default) executor omits this - // field, the executor must be created outside the CalculatorGraph and - // passed to the CalculatorGraph for use. - string type = 2; - // The options passed to the Executor. The extension in the options field - // must match the type field. For example, if the type field is - // "ThreadPoolExecutor", then the options field should contain the - // ThreadPoolExecutorOptions. - MediaPipeOptions options = 3; -} - -// A collection of input data to a CalculatorGraph. -message InputCollection { - // The name of the input collection. Name must match [a-z_][a-z0-9_]* - string name = 1; - // The names of each side packet. The number of side_packet_name - // must match the number of packets generated by the input file. - repeated string side_packet_name = 2; - // DEPRECATED: old way of referring to side_packet_name. - repeated string external_input_name = 1002; - - // The input can be specified in several ways. - enum InputType { - // An invalid default value. This value is guaranteed to be the - // lowest enum value (i.e. don't add negative enum values). - UNKNOWN = 0; - // A recordio where each record is a serialized PacketManagerConfig. - // Each PacketManagerConfig must have the same number of packet - // factories in it as the number of side packet names. Furthermore, - // the output side packet name field in each PacketFactoryConfig - // must not be set. This is the most general input, and allows - // multiple side packet values to be set in arbitrarily complicated - // ways before each run. - RECORDIO = 1; - // A recordio where each record is a serialized packet payload. - // For example a recordio of serialized OmniaFeature protos dumped - // from Omnia. - FOREIGN_RECORDIO = 2; - // A text file where each line is a comma separated list. The number - // of elements for each csv string must be the same as the number - // of side_packet_name (and the order must match). Each line must - // be less than 1MiB in size. Lines comprising of only whitespace - // or only whitespace and a pound comment will be skipped. - FOREIGN_CSV_TEXT = 3; - // This and all higher values are invalid. Update this value to - // always be larger than any other enum values you add. - INVALID_UPPER_BOUND = 4; - } - // Sets the source of the input collection data. - // The default value is UNKNOWN. - InputType input_type = 3; - // A file name pointing to the data. The format of the data is - // specified by the "input_type" field. Multiple shards may be - // specified using @N or glob expressions. - string file_name = 4; -} - -// A convenient way to specify a number of InputCollections. -message InputCollectionSet { - repeated InputCollection input_collection = 1; -} - -// Additional information about an input stream. -message InputStreamInfo { - // A description of the input stream. - // This description uses the Calculator visible specification of - // a stream. The format is a tag, then an index with both being - // optional. If the tag is missing it is assumed to be "" and if - // the index is missing then it is assumed to be 0. If the index - // is provided then a colon (':') must be used. - // Examples: - // "TAG" -> tag "TAG", index 0 - // "" -> tag "", index 0 - // ":0" -> tag "", index 0 - // ":3" -> tag "", index 3 - // "VIDEO:0" -> tag "VIDEO", index 0 - // "VIDEO:2" -> tag "VIDEO", index 2 - string tag_index = 1; - // Whether the input stream is a back edge. - // By default, MediaPipe requires graphs to be acyclic and treats cycles in a - // graph as errors. To allow MediaPipe to accept a cyclic graph, set the - // back_edge fields of the input streams that are back edges to true. A - // cyclic graph usually has an obvious forward direction, and a back edge - // goes in the opposite direction. For a formal definition of a back edge, - // please see https://en.wikipedia.org/wiki/Depth-first_search. - bool back_edge = 2; -} - -// Configs for the profiler for a calculator. Not applicable to subgraphs. -message ProfilerConfig { - // Size of the runtimes histogram intervals (in microseconds) to generate the - // histogram of the Process() time. The last interval extends to +inf. - // If not specified, the interval is 1000000 usec = 1 sec. - int64 histogram_interval_size_usec = 1; - - // Number of intervals to generate the histogram of the Process() runtime. - // If not specified, one interval is used. - int64 num_histogram_intervals = 2; - - // TODO: clean up after migration to MediaPipeProfiler. - // DEPRECATED: If true, the profiler also profiles the input output latency. - // Should be true only if the packet timestamps corresponds to the - // microseconds wall time from epoch. - bool enable_input_output_latency = 3 [deprecated = true]; - - // If true, the profiler starts profiling when graph is initialized. - bool enable_profiler = 4; - - // If true, the profiler also profiles the stream latency and input-output - // latency. - // No-op if enable_profiler is false. - bool enable_stream_latency = 5; - - // If true, the profiler uses packet timestamp (as production time and source - // production time) for packets added by calling - // CalculatorGraph::AddPacketToInputStream(). - // If false, uses profiler's clock. - bool use_packet_timestamp_for_added_packet = 6; - - // The maximum number of trace events buffered in memory. - // The default value buffers up to 20000 events. - int64 trace_log_capacity = 7; - - // Trace event types that are not logged. - repeated int32 trace_event_types_disabled = 8; - - // The output directory and base-name prefix for trace log files. - // Log files are written to: StrCat(trace_log_path, index, ".binarypb") - string trace_log_path = 9; - - // The number of trace log files retained. - // The trace log files are named "trace_0.log" through "trace_k.log". - // The default value specifies 2 output files retained. - int32 trace_log_count = 10; - - // The interval in microseconds between trace log output. - // The default value specifies trace log output once every 0.5 sec. - int64 trace_log_interval_usec = 11; - - // The interval in microseconds between TimeNow and the highest times - // included in trace log output. This margin allows time for events - // to be appended to the TraceBuffer. - int64 trace_log_margin_usec = 12; - - // Deprecated, replaced by trace_log_instant_events. - bool trace_log_duration_events = 13 [deprecated = true]; - - // The number of trace log intervals per file. The total log duration is: - // trace_log_interval_usec * trace_log_file_count * trace_log_interval_count. - // The default value specifies 10 intervals per file. - int32 trace_log_interval_count = 14; - - // An option to turn ON/OFF writing trace files to disk. Saving trace files to - // disk is enabled by default. - bool trace_log_disabled = 15; - - // If true, tracer timing events are recorded and reported. - bool trace_enabled = 16; - - // False specifies an event for each calculator invocation. - // True specifies a separate event for each start and finish time. - bool trace_log_instant_events = 17; - - // Limits calculator-profile histograms to a subset of calculators. - string calculator_filter = 18; -} - -// Describes the topology and function of a MediaPipe Graph. The graph of -// Nodes must be a Directed Acyclic Graph (DAG) except as annotated by -// "back_edge" in InputStreamInfo. Use a mediapipe::CalculatorGraph object to -// run the graph. -message CalculatorGraphConfig { - // A single node in the DAG. - message Node { - // The name of the node. This field is optional and doesn't generally - // need to be specified, but does improve error messaging. - string name = 1; - // The registered type of a calculator (provided via REGISTER_CALCULATOR), - // or of a subgraph (via REGISTER_MEDIAPIPE_GRAPH). - string calculator = 2; - // A Calculator can choose to access its input streams, output - // streams, and input side packets either by tag or by index. If the - // calculator chooses indexes then it will receive the streams or side - // packets in the same order as they are specified in this proto. - // If the calculator chooses to use tags then it must specify a - // tag along with each name. The field is given as "TAG:name". - // Meaning a tag name followed by a colon followed by the name. - // Tags use only upper case letters, numbers, and underscores, whereas - // names use only lower case letters, numbers, and underscores. - // Example: - // Node { - // calculator: "SomeAudioVideoCalculator" - // # This calculator accesses its inputs by index (no tag needed). - // input_stream: "combined_input" - // # This calculator accesses its outputs by tags, so all - // # output_streams must specify a tag. - // output_stream: "AUDIO:audio_stream" - // output_stream: "VIDEO:video_stream" - // # This calculator accesses its input side packets by tag. - // input_side_packet: "MODEL:model_01" - // } - - // String(s) representing "TAG:name" of the stream(s) from which the current - // node will get its inputs. "TAG:" part is optional, see above. - // A calculator with no input stream is a source. - repeated string input_stream = 3; - // String(s) representing "TAG:name" of the stream(s) produced by this node. - // "TAG:" part is optional, see above. These must be different from any - // other output_streams specified for other nodes in the graph. - repeated string output_stream = 4; - // String(s) representing "TAG:name" of the input side packet(s). - // "TAG:" part is optional, see above. - repeated string input_side_packet = 5; - // String(s) representing "TAG:name" of the output side packet(s). Only - // used by subgraphs. - // "TAG:" part is optional, see above. - repeated string output_side_packet = 6; - // The options passed to the Calculator, in proto2 syntax. - CalculatorOptions options = 7; - // The options passed to the Calculator, in proto3 syntax. - // Each node_options message must have a different message type. - // If the same message type is specified in |options| and |node_options|, - // only the message in |options| is used. - repeated google.protobuf.Any node_options = 8; - - // Note: the following fields are only applicable to calculators, not - // subgraphs. - - // For a Source Calculator (i.e. a calculator with no inputs), - // this is the "layer" on which the calculator is executed. For a - // non-source calculator (i.e. a calculator with one or more input - // streams) this field has no effect. The sources on each layer - // are completely exhausted before Process() is called on any source - // calculator on a higher numbered layer. - // Example: - // Decoder -> Median Frame (requires all frames) -> Image Subtraction - // ---------------------------------------> - // The entire video will be buffered on the edge from the decoder - // to the Image subtraction. To fix this problem, layers can be used. - // Decoder (layer 0) -> Median Frame -> Image Subtraction - // Decoder (layer 1) -----------------> - // The frames from layer 0 will no longer be buffered, but the video - // will be decoded again instead. Note, that different options can - // be used in the second decoder. - int32 source_layer = 9; - // Optional parameter that allows the user to indicate to the scheduler that - // this node has a buffering behavior (i.e. waits for a bunch of packets - // before emitting any) and specify the size of the buffer that is built up. - // The scheduler will then try to keep the maximum size of any input queues - // in the graph to remain below the maximum of all buffer_size_hints and - // max_queue_size (if specified). The ideal value is typically something - // larger than the actual number of buffered packets to maintain pipelining. - // The default value 0 indicates that the node has no buffering behavior. - int32 buffer_size_hint = 10; - // Config for this node's InputStreamHandler. - // If unspecified, the graph-level input stream handler will be used. - InputStreamHandlerConfig input_stream_handler = 11; - // Config for this node's OutputStreamHandler. - // If unspecified, the graph-level output stream handler will be used. - OutputStreamHandlerConfig output_stream_handler = 12; - // Additional information about an input stream. The |name| field of the - // InputStreamInfo must match an input_stream. - repeated InputStreamInfo input_stream_info = 13; - // Set the executor which the calculator will execute on. - string executor = 14; - // TODO: Remove from Node when switched to Profiler. - // DEPRECATED: Configs for the profiler. - ProfilerConfig profiler_config = 15 [deprecated = true]; - // The maximum number of invocations that can be executed in parallel. - // If not specified, the limit is one invocation. - int32 max_in_flight = 16; - // DEPRECATED: For backwards compatibility we allow users to - // specify the old name for "input_side_packet" in proto configs. - // These are automatically converted to input_side_packets during - // config canonicalization. - repeated string external_input = 1005; - } - - // The nodes. - repeated Node node = 1; - // Create a side packet using a PacketFactory. This side packet is - // created as close to the worker that does the work as possible. A - // PacketFactory is basically a PacketGenerator that takes no input side - // packets and produces a single output side packet. - repeated PacketFactoryConfig packet_factory = 6; - // Configs for PacketGenerators. Generators take zero or more - // input side packets and produce any number of output side - // packets. For example, MediaDecoderCalculator takes an input - // side packet with type DeletingFile. However, most users want - // to specify videos by ContentIdHex (i.e. video id). By using - // the VideoIdToLocalFileGenerator, a user can specify a video id - // (as a string) and obtain a DeletingFile to use with the decoder. - // PacketGenerators can take as a input side packet the output side - // packet of another PacketGenerator. The graph of PacketGenerators - // must be a directed acyclic graph. - repeated PacketGeneratorConfig packet_generator = 7; - // Number of threads for running calculators in multithreaded mode. - // If not specified, the scheduler will pick an appropriate number - // of threads depending on the number of available processors. - // To run on the calling thread, specify "ApplicationThreadExecutor" - // see: http://g3doc/mediapipe/g3doc/running.md. - int32 num_threads = 8; - // Configs for StatusHandlers that will be called after each call to - // Run() on the graph. StatusHandlers take zero or more input side - // packets and the absl::Status returned by a graph run. For example, - // a StatusHandler could store information about graph failures and - // their causes for later monitoring. Note that graph failures during - // initialization may cause required input side packets (created by a - // PacketFactory or PacketGenerator) to be missing. In these cases, - // the handler with missing input side packets will be skipped. - repeated StatusHandlerConfig status_handler = 9; - // Specify input streams to the entire graph. Streams specified here may have - // packets added to them using CalculatorGraph::AddPacketToInputStream. This - // works much like a source calculator, except that the source is outside of - // the mediapipe graph. - repeated string input_stream = 10; - // Output streams for the graph when used as a subgraph. - repeated string output_stream = 15; - // Input side packets for the graph when used as a subgraph. - repeated string input_side_packet = 16; - // Output side packets for the graph when used as a subgraph. - repeated string output_side_packet = 17; - // Maximum queue size of any input stream in the graph. This can be used to - // control the memory usage of a MediaPipe graph by preventing fast sources - // from flooding the graph with packets. Any source that is connected to an - // input stream that has hit its maximum capacity will not be scheduled until - // the queue size falls under the specified limits, or if the scheduler queue - // is empty and no other nodes are running (to prevent possible deadlocks due - // to a incorrectly specified value). This global parameter is set to 100 - // packets by default to enable pipelining. If any node indicates that it - // buffers packets before emitting them, then the max(node_buffer_size, - // max_queue_size) is used. Set this parameter to -1 to disable throttling - // (i.e. the graph will use as much memory as it requires). If not specified, - // the limit is 100 packets. - int32 max_queue_size = 11; - // If true, the graph run fails with an error when throttling prevents all - // calculators from running. If false, max_queue_size for an input stream - // is adjusted when throttling prevents all calculators from running. - bool report_deadlock = 21; - // Config for this graph's InputStreamHandler. - // If unspecified, the framework will automatically install the default - // handler, which works as follows. - // The calculator's Process() method is called for timestamp t when: - // - at least one stream has a packet available at t; and, - // - all other streams either have packets at t, or it is known that they will - // not have packets at t (i.e. their next timestamp bound is greater than t). - // The handler then provides all available packets with timestamp t, with no - // preprocessing. - InputStreamHandlerConfig input_stream_handler = 12; - // Config for this graph's OutputStreamHandler. - // If unspecified, the default output stream handler will be automatically - // installed by the framework which does not modify any outgoing packets. - OutputStreamHandlerConfig output_stream_handler = 13; - // Configs for Executors. - // The names of the executors must be distinct. The default executor, whose - // name is the empty string, is predefined. The num_threads field of the - // CalculatorGraphConfig specifies the number of threads in the default - // executor. If the config for the default executor is specified, the - // CalculatorGraphConfig must not have the num_threads field. - repeated ExecutorConfig executor = 14; - // The default profiler-config for all calculators. If set, this defines the - // profiling settings such as num_histogram_intervals for every calculator in - // the graph. Each of these settings can be overridden by the - // |profiler_config| specified for a node. - ProfilerConfig profiler_config = 18; - - // The namespace used for class name lookup within this graph. - // An unqualified or partially qualified class name is looked up in - // this namespace first and then in enclosing namespaces. - string package = 19; - - // The type name for the graph config, used for registering and referencing - // the graph config. - string type = 20; - - // The types and default values for graph options, in proto2 syntax. - MediaPipeOptions options = 1001; - - // The types and default values for graph options, in proto3 syntax. - repeated google.protobuf.Any graph_options = 1002; -} diff --git a/protofiles/framework/calculator_contract_test.proto b/protofiles/framework/calculator_contract_test.proto deleted file mode 100644 index 8271270..0000000 --- a/protofiles/framework/calculator_contract_test.proto +++ /dev/null @@ -1,30 +0,0 @@ -// 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. -// -// Forked from mediapipe_options.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -import "protofiles/framework/calculator.proto"; - -message CalculatorContractTestOptions { - extend CalculatorOptions { - optional CalculatorContractTestOptions ext = 188754615; - } - optional double test_field = 1 [default = -1.0]; -} diff --git a/protofiles/framework/calculator_options.proto b/protofiles/framework/calculator_options.proto deleted file mode 100644 index b895653..0000000 --- a/protofiles/framework/calculator_options.proto +++ /dev/null @@ -1,40 +0,0 @@ -// 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. -// -// Forked from mediapipe/framework/calculator.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -// Options for Calculators. Each Calculator implementation should -// have its own options proto, which should look like this: -// -// message MyCalculatorOptions { -// extend CalculatorOptions { -// optional MyCalculatorOptions ext = ; -// } -// optional string field_needed_by_my_calculator = 1; -// optional int32 another_field = 2; -// // etc -// } -message CalculatorOptions { - // If true, this proto specifies a subset of field values, - // which should override corresponding field values. - optional bool merge_fields = 1 [deprecated = true]; - - extensions 20000 to max; -} diff --git a/protofiles/framework/calculator_profile.proto b/protofiles/framework/calculator_profile.proto deleted file mode 100644 index d11f54e..0000000 --- a/protofiles/framework/calculator_profile.proto +++ /dev/null @@ -1,192 +0,0 @@ -// 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. -// -// Forked from calculator_profile.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -import "protofiles/framework/calculator.proto"; - -// Stores the profiling information. -// -// It is the responsibility of the user of this message to make sure the 'total' -// field and the interval information (num, size and count) are in a valid -// state and all get updated together. -// -// Each interval of the histogram is closed on the lower range and open on the -// higher end. An example histogram with interval_size=1000 and num_interval=3 -// will have the following intervals: -// - First interval = [0, 1000) -// - Second interval = [1000, 2000) -// - Third interval = [2000, +inf) -// -// IMPORTANT: If You add any new field, update CalculatorProfiler::Reset() -// accordingly. -message TimeHistogram { - // Total time (in microseconds). - optional int64 total = 1 [default = 0]; - - // Size of the runtimes histogram intervals (in microseconds) to generate the - // histogram of the Process() time. The last interval extends to +inf. - optional int64 interval_size_usec = 2 [default = 1000000 /* 1 sec */]; - - // Number of intervals to generate the histogram of the Process() runtime. - optional int64 num_intervals = 3 [default = 1]; - - // Number of calls in each interval. - repeated int64 count = 4; -} - -// Stores the profiling information of a stream. -message StreamProfile { - // Stream name. - optional string name = 1; - - // If true, than this is a back edge input stream and won't be profiled. - optional bool back_edge = 2 [default = false]; - - // Total and histogram of the time that this stream took. - optional TimeHistogram latency = 3; -} - -// Stores the profiling information for a calculator node. -// All the times are in microseconds. -message CalculatorProfile { - // The calculator name. - optional string name = 1; - - // Total time the calculator spent on Open (in microseconds). - optional int64 open_runtime = 2 [default = 0]; - - // Total time the calculator spent on Close (in microseconds). - optional int64 close_runtime = 3 [default = 0]; - - // Total and histogram of the time that the calculator spent on the Process() - // (in microseconds). - optional TimeHistogram process_runtime = 4; - - // Total and histogram of the time that the input latency, ie. difference - // between input timestamp and process call time. - // (in microseconds). - optional TimeHistogram process_input_latency = 5; - - // Total and histogram of the time that the output latency, ie. difference - // between input timestamp and process finished time. - optional TimeHistogram process_output_latency = 6; - - // Total and histogram of the time that input streams of this calculator took. - repeated StreamProfile input_stream_profiles = 7; -} - -// Latency timing for recent mediapipe packets. -message GraphTrace { - // The timing for one packet across one packet stream. - message StreamTrace { - // The time at which the packet entered the stream. - optional int64 start_time = 1; - - // The time at which the packet exited the stream. - optional int64 finish_time = 2; - - // The identifying timetamp of the packet. - optional int64 packet_timestamp = 3; - - // The index of the stream in the stream_name list. - optional int32 stream_id = 4; - - // The address of the packet contents. - optional int64 packet_id = 5 [deprecated = true]; - - // Data describing the event, such as the packet contents. - optional int64 event_data = 6; - } - - // The kind of event recorded. - enum EventType { - UNKNOWN = 0; - OPEN = 1; - PROCESS = 2; - CLOSE = 3; - NOT_READY = 4; - READY_FOR_PROCESS = 5; - READY_FOR_CLOSE = 6; - THROTTLED = 7; - UNTHROTTLED = 8; - CPU_TASK_USER = 9; - CPU_TASK_SYSTEM = 10; - GPU_TASK = 11; - DSP_TASK = 12; - TPU_TASK = 13; - GPU_CALIBRATION = 14; - PACKET_QUEUED = 15; - } - - // The timing for one packet set being processed at one caclulator node. - message CalculatorTrace { - // The index of the calculator node in the calculator_name list. - optional int32 node_id = 1; - - // The input timestamp during Open, Process, or Close. - optional int64 input_timestamp = 2; - - // The kind of event, 1=Open, 2=Process, 3=Close, etc. - optional EventType event_type = 3; - - // The time at which the packets entered the caclulator node. - optional int64 start_time = 4; - - // The time at which the packets exited the caclulator node. - optional int64 finish_time = 5; - - // The timing data for each input packet. - repeated StreamTrace input_trace = 6; - - // The identifying timetamp and stream_id for each output packet. - repeated StreamTrace output_trace = 7; - - // An identifier for the current process thread. - optional int32 thread_id = 8; - } - - // The time represented as 0 in the trace. - optional int64 base_time = 1; - - // The timestamp represented as 0 in the trace. - optional int64 base_timestamp = 2; - - // The list of calculator node names indexed by node id. - repeated string calculator_name = 3; - - // The list of stream names indexed by stream id. - repeated string stream_name = 4; - - // Recent packet timing informtion about each calculator node and stream. - repeated CalculatorTrace calculator_trace = 5; -} - -// Latency events and summaries for recent mediapipe packets. -message GraphProfile { - // Recent packet timing informtion about each calculator node and stream. - repeated GraphTrace graph_trace = 1; - - // Aggregated latency information about each calculator node. - repeated CalculatorProfile calculator_profiles = 2; - - // The canonicalized calculator graph that is traced. - optional CalculatorGraphConfig config = 3; -} diff --git a/protofiles/framework/formats/annotation/rasterization.proto b/protofiles/framework/formats/annotation/rasterization.proto deleted file mode 100644 index 4ca398d..0000000 --- a/protofiles/framework/formats/annotation/rasterization.proto +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2018 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. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -// A Region can be represented in each frame as a set of scanlines -// (compressed RLE, similar to rasterization of polygons). -// For each scanline with y-coordinate y, we save (possibly multiple) intervals -// of occupied pixels represented as a pair [left_x, right_x]. -message Rasterization { - message Interval { - required int32 y = 1; - required int32 left_x = 2; - required int32 right_x = 3; - } - - // Intervals are always sorted by y-coordinate. - // Therefore, a region occupies a set of scanlines ranging - // from interval(0).y() to interval(interval_size() - 1)).y(). - // Note: In video, at some scanlines no interval might be present. - repeated Interval interval = 1; -} diff --git a/protofiles/framework/formats/classification.proto b/protofiles/framework/formats/classification.proto deleted file mode 100644 index 82da160..0000000 --- a/protofiles/framework/formats/classification.proto +++ /dev/null @@ -1,42 +0,0 @@ -// 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. -// -// A protocol buffer encoding one or several classifications in an image. A -// classification is defined by label and corresponding score, representing the -// classifier confidence for the label. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -message Classification { - // The index of the class in the corresponding label map. - optional int32 index = 1; - // The probability score for this class. - optional float score = 2; - // Label or name of the class. - optional string label = 3; - // Optional human-readable string for display purposes. - optional string display_name = 4; -} - -// Group of Classification protos. -message ClassificationList { - repeated Classification classification = 1; -} - -// Group of ClassificationList protos. -message ClassificationListCollection { - repeated ClassificationList classification_list = 1; -} diff --git a/protofiles/framework/formats/detection.proto b/protofiles/framework/formats/detection.proto deleted file mode 100644 index 588fdd2..0000000 --- a/protofiles/framework/formats/detection.proto +++ /dev/null @@ -1,64 +0,0 @@ -// 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. -// -// A protocol buffer encoding one or several detections in an image. A detection -// is defined by label and corresponding score, representing the classifier -// confidence for the label, and location, representing the spatial extent of -// the detection. All detections encoded by the protocol buffer relate to the -// same image location. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -import "protofiles/framework/formats/location_data.proto"; - -message Detection { - // i-th label or label_id has a score encoded by the i-th element in score. - repeated string label = 1; - repeated int32 label_id = 2 [packed = true]; - repeated float score = 3 [packed = true]; - - // Location data corresponding to all detected labels above. - optional LocationData location_data = 4; - // Optional string to indicate the feature generation method. Useful in - // associating a name to the pipeline used to generate this detection. - optional string feature_tag = 5; - // Optional string to specify track_id if detection is part of a track. - optional string track_id = 6; - - // Optional unique id to help associate different Detections to each other. - optional int64 detection_id = 7; - // Useful for associating a detection with other detections based on the - // detection_id. For example, this could be used to associate a face detection - // with a body detection when they belong to the same person. - message AssociatedDetection { - optional int32 id = 1; - optional float confidence = 2; - } - repeated AssociatedDetection associated_detections = 8; - - // Human-readable string for display, intended for debugging purposes. The - // display name corresponds to the label (or label_id). This is optional. - repeated string display_name = 9; - - // The timestamp (in microseconds) *at which* this detection was - // created/detected. - optional int64 timestamp_usec = 10; -} - -// Group of Detection protos. -message DetectionList { - repeated Detection detection = 1; -} diff --git a/protofiles/framework/formats/landmark.proto b/protofiles/framework/formats/landmark.proto deleted file mode 100644 index 9ab39c6..0000000 --- a/protofiles/framework/formats/landmark.proto +++ /dev/null @@ -1,60 +0,0 @@ -// 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. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -// A landmark that can have 1 to 3 dimensions. Use x for 1D points, (x, y) for -// 2D points and (x, y, z) for 3D points. For more dimensions, consider using -// matrix_data.proto. -message Landmark { - optional float x = 1; - optional float y = 2; - optional float z = 3; - - // Landmark visibility. Should stay unset if not supported. - // Float score of whether landmark is visible or occluded by other objects. - // Landmark considered as invisible also if it is not present on the screen - // (out of scene bounds). Depending on the model, visibility value is either a - // sigmoid or an argument of sigmoid. - optional float visibility = 4; - - // Landmark presence. Should stay unset if not supported. - // Float score of whether landmark is present on the scene (located within - // scene bounds). Depending on the model, presence value is either a result of - // sigmoid or an argument of sigmoid function to get landmark presence - // probability. - optional float presence = 5; -} - -// Group of Landmark protos. -message LandmarkList { - repeated Landmark landmark = 1; -} - -// A normalized version of above Landmark proto. All coordinates should be -// within [0, 1]. -message NormalizedLandmark { - optional float x = 1; - optional float y = 2; - optional float z = 3; - optional float visibility = 4; - optional float presence = 5; -} - -// Group of NormalizedLandmark protos. -message NormalizedLandmarkList { - repeated NormalizedLandmark landmark = 1; -} diff --git a/protofiles/framework/formats/location_data.proto b/protofiles/framework/formats/location_data.proto deleted file mode 100644 index a2b8257..0000000 --- a/protofiles/framework/formats/location_data.proto +++ /dev/null @@ -1,88 +0,0 @@ -// 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. -// -// A protocol buffer containing location information. It allows for storing -// location information related to an image in several formats -- relative -// and absolute bounding boxes, foreground mask. -// See location.h for a helper wrapper to work with the LocationData. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -import "protofiles/framework/formats/annotation/rasterization.proto"; - -message LocationData { - // The supported formats for representing location data. A single location - // must store its data in exactly one way. - enum Format { - // The full image. This is a handy format when one needs to refer to the - // full image, e.g. one uses global image labels. No other fields need to - // be populated. - GLOBAL = 0; - // A rectangle aka bounding box of an object. The field bounding_box must be - // used to store the location data. - BOUNDING_BOX = 1; - // A rectangle aka bounding box of an object, defined in coordinates - // normalized by the image dimensions. The field relative_bounding_box must - // be used to store the location data. - RELATIVE_BOUNDING_BOX = 2; - // A foreground mask. The field mask must be used to store the location - // data. - MASK = 3; - } - optional Format format = 1; - - // A bounding box in pixel units. The box is defined by its upper left corner - // (xmin, ymin) and its width and height. - message BoundingBox { - optional int32 xmin = 1; - optional int32 ymin = 2; - optional int32 width = 3; - optional int32 height = 4; - } - optional BoundingBox bounding_box = 2; - - // A bounding box. The box is defined by its upper left corner (xmin, ymin) - // and its width and height, all in coordinates normalized by the image - // dimensions. - message RelativeBoundingBox { - optional float xmin = 1; - optional float ymin = 2; - optional float width = 3; - optional float height = 4; - } - optional RelativeBoundingBox relative_bounding_box = 3; - - // A mask of size equivalent to the image size. It encodes a region, which - // can be thought of as a foreground object mask. - message BinaryMask { - // Dimensions of the mask. - optional int32 width = 1; - optional int32 height = 2; - // A rasterization-like format for storing the mask. - optional Rasterization rasterization = 3; - } - optional BinaryMask mask = 4; - - // A keypoint. The keypoint is defined by the coordinates (x, y), normalized - // by the image dimensions. - message RelativeKeypoint { - optional float x = 1; - optional float y = 2; - optional string keypoint_label = 3; - optional float score = 4; - } - repeated RelativeKeypoint relative_keypoints = 5; -} diff --git a/protofiles/framework/formats/matrix_data.proto b/protofiles/framework/formats/matrix_data.proto deleted file mode 100644 index 6fe9ade..0000000 --- a/protofiles/framework/formats/matrix_data.proto +++ /dev/null @@ -1,40 +0,0 @@ -// 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. -// -// Forked from -// mediapipe/framework/formats/matrix_data.proto -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -// Proto for serializing Matrix data. -// Data are stored in column-major order by default. -message MatrixData { - optional int32 rows = 1; - optional int32 cols = 2; - - repeated float packed_data = 3 [packed = true]; - - enum Layout { - COLUMN_MAJOR = 0; - ROW_MAJOR = 1; - } - - // Order in which the data are stored. Defaults to COLUMN_MAJOR, which matches - // the default for mediapipe::Matrix and Eigen::Matrix*. - optional Layout layout = 4 [default = COLUMN_MAJOR]; -} diff --git a/protofiles/framework/formats/rect.proto b/protofiles/framework/formats/rect.proto deleted file mode 100644 index e9c382f..0000000 --- a/protofiles/framework/formats/rect.proto +++ /dev/null @@ -1,55 +0,0 @@ -// 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. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -// A rectangle with rotation in image coordinates. -message Rect { - // Location of the center of the rectangle in image coordinates. - // The (0, 0) point is at the (top, left) corner. - required int32 x_center = 1; - required int32 y_center = 2; - - // Size of the rectangle. - required int32 height = 3; - required int32 width = 4; - - // Rotation angle is clockwise in radians. - optional float rotation = 5 [default = 0.0]; - - // Optional unique id to help associate different Rects to each other. - optional int64 rect_id = 6; -} - -// A rectangle with rotation in normalized coordinates. The values of box center -// location and size are within [0, 1]. -message NormalizedRect { - // Location of the center of the rectangle in image coordinates. - // The (0.0, 0.0) point is at the (top, left) corner. - required float x_center = 1; - required float y_center = 2; - - // Size of the rectangle. - required float height = 3; - required float width = 4; - - // Rotation angle is clockwise in radians. - optional float rotation = 5 [default = 0.0]; - - // Optional unique id to help associate different NormalizedRects to each - // other. - optional int64 rect_id = 6; -} diff --git a/protofiles/framework/mediapipe_options.proto b/protofiles/framework/mediapipe_options.proto deleted file mode 100644 index be0c5e3..0000000 --- a/protofiles/framework/mediapipe_options.proto +++ /dev/null @@ -1,26 +0,0 @@ -// 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. -// -// Forked from mediapipe/framework/mediapipe_options.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -// Options used by a MediaPipe object. -message MediaPipeOptions { - extensions 20000 to max; -} diff --git a/protofiles/framework/packet_factory.proto b/protofiles/framework/packet_factory.proto deleted file mode 100644 index 3006415..0000000 --- a/protofiles/framework/packet_factory.proto +++ /dev/null @@ -1,48 +0,0 @@ -// 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. -// -// Forked from mediapipe/framework/packet_factory.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. -// -// Messages for PacketFactory and PacketManager. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -// Options used by a PacketFactory to create the Packet. -message PacketFactoryOptions { - extensions 20000 to max; -} - -// A PacketFactory creates a side packet. -message PacketFactoryConfig { - // The name of the registered packet factory class. - optional string packet_factory = 1; - - // The name of the output side packet that this packet factory creates. - optional string output_side_packet = 2; - - // DEPRECATED: The old name for output_side_packet. - optional string external_output = 1002; - - // The options for the packet factory. - optional PacketFactoryOptions options = 3; -} - -// The configuration for a PacketManager. -message PacketManagerConfig { - repeated PacketFactoryConfig packet = 1; -} diff --git a/protofiles/framework/packet_generator.proto b/protofiles/framework/packet_generator.proto deleted file mode 100644 index 6c11730..0000000 --- a/protofiles/framework/packet_generator.proto +++ /dev/null @@ -1,50 +0,0 @@ -// 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. -// -// Forked from mediapipe/framework/packet_generator.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. -// -// Messages for specifying PacketGenerators. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -// Options used by a PacketGenerator. -message PacketGeneratorOptions { - extensions 20000 to max; -} - -// The settings specifying a packet generator and how it is connected. -message PacketGeneratorConfig { - // The name of the registered packet generator class. - optional string packet_generator = 1; - - // The names of the input side packets. The PacketGenerator can choose - // to access its input side packets either by index or by tag. - repeated string input_side_packet = 2; - // DEPRECATED(mgeorg) The old name for input_side_packet. - repeated string external_input = 1002; - - // The names of the output side packets that this generator produces. - // The PacketGenerator can choose to access its output side packets - // either by index or by tag. - repeated string output_side_packet = 3; - // DEPRECATED(mgeorg) The old name for output_side_packet. - repeated string external_output = 1003; - - // The options for the packet generator. - optional PacketGeneratorOptions options = 4; -} diff --git a/protofiles/framework/packet_test.proto b/protofiles/framework/packet_test.proto deleted file mode 100644 index ec60f08..0000000 --- a/protofiles/framework/packet_test.proto +++ /dev/null @@ -1,47 +0,0 @@ -// 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. -// -// Proto for testing the Packet. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -message PacketTestProto { - // Tests that the tags used to encode the timestamp do not interfere with - // proto tags. - repeated int32 x = 1777; - // The tag below = 1777 | (1 << 28). - repeated int32 y = 268437233; -} - -// A proto like InputCollection::Inputs which has embedded strings -// within it. -message SimpleProto { - repeated bytes value = 1; -} - -// A proto that acts as the proxy of SerializationProxyTestClass for -// serialization. -message SerializationProxyProto { - optional bool bool_value = 1; - repeated float float_value = 2; - repeated string string_value = 3; -} - -// This proto should be used only as an input to a calculator, to verify that -// that case is covered. -message InputOnlyProto { - optional int32 x = 1; -} diff --git a/protofiles/framework/status_handler.proto b/protofiles/framework/status_handler.proto deleted file mode 100644 index 5acffc9..0000000 --- a/protofiles/framework/status_handler.proto +++ /dev/null @@ -1,43 +0,0 @@ -// 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. -// -// Forked from status_handler.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. -// -// Messages for specifying StatusHandlers. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -import "protofiles/framework/mediapipe_options.proto"; - -// The settings specifying a status handler and its required external inputs. -message StatusHandlerConfig { - // The name of the registered status handler class. - optional string status_handler = 1; // required - - // The name of the input side packets. The StatusHandler can access its - // input side packets by index or by tag. A StatusHandler will only - // be called if all of its requested input side packets are available - // (and won't be called if a PacketFactory or PacketGenerator which - // produces one fails). - repeated string input_side_packet = 2; - // DEPRECATED(mgeorg) The old name for input_side_packet. - repeated string external_input = 1002; - - // The options for the status handler. - optional MediaPipeOptions options = 3; -} diff --git a/protofiles/framework/stream_handler.proto b/protofiles/framework/stream_handler.proto deleted file mode 100644 index 41915d3..0000000 --- a/protofiles/framework/stream_handler.proto +++ /dev/null @@ -1,49 +0,0 @@ -// 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. -// -// Forked from stream_handler.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -import "protofiles/framework/mediapipe_options.proto"; - -option objc_class_prefix = "Mediapipe"; - -// Settings specifying an input stream handler. -message InputStreamHandlerConfig { - // Name of the registered input stream handler class. - optional string input_stream_handler = 1 - [default = "DefaultInputStreamHandler"]; - - // Options for the input stream handler. - optional MediaPipeOptions options = 3; -} - -// Settings specifying an output stream handler. -message OutputStreamHandlerConfig { - // Name of the registered output stream handler class. - optional string output_stream_handler = 1 - [default = "InOrderOutputStreamHandler"]; - - // Names of the input side packets for the handler specifically and distinct - // from the side packets for the calculator (but could be shared). - repeated string input_side_packet = 2; - - // Options for the output stream handler. - optional MediaPipeOptions options = 3; -} diff --git a/protofiles/framework/test_calculators.proto b/protofiles/framework/test_calculators.proto deleted file mode 100644 index ef4dd45..0000000 --- a/protofiles/framework/test_calculators.proto +++ /dev/null @@ -1,34 +0,0 @@ -// 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. -// -// Forked from test_calculators.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -import "protofiles/framework/calculator.proto"; - -message RandomMatrixCalculatorOptions { - extend CalculatorOptions { - optional RandomMatrixCalculatorOptions ext = 52056136; - } - optional int32 rows = 1; - optional int32 cols = 2; - optional int64 start_timestamp = 3; - optional int64 limit_timestamp = 4; - optional int64 timestamp_step = 5; -} diff --git a/protofiles/framework/thread_pool_executor.proto b/protofiles/framework/thread_pool_executor.proto deleted file mode 100644 index 71f31b2..0000000 --- a/protofiles/framework/thread_pool_executor.proto +++ /dev/null @@ -1,59 +0,0 @@ -// 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. -// -// Forked from thread_pool_executor.proto. -// The forked proto must remain identical to the original proto and should be -// ONLY used by mediapipe open source project. - -syntax = "proto2"; - -package akihabara.framework.protobuf; - -import "protofiles/framework/mediapipe_options.proto"; - -message ThreadPoolExecutorOptions { - extend MediaPipeOptions { - optional ThreadPoolExecutorOptions ext = 157116819; - } - // Number of threads for running calculators in multithreaded mode. - // - // When ThreadPoolExecutorOptions is used in the ExecutorOptions for the - // default executor with the executor type unspecified, the num_threads - // field is allowed to be -1 or 0. If not specified or -1, the scheduler - // will pick an appropriate number of threads depending on the number of - // available processors. - optional int32 num_threads = 1; - // Make all worker threads have the specified stack size (in bytes). - // NOTE: The stack_size option may not be implemented on some platforms. - optional int32 stack_size = 2; - // The nice priority level of the worker threads. - // The nice priority level is 0 by default, and lower value means higher - // priority. The valid thread nice priority level value range varies by OS. - // Refer to system documentation for more details. - optional int32 nice_priority_level = 3; - // Processor performance enum. - enum ProcessorPerformance { - NORMAL = 0; - LOW = 1; - HIGH = 2; - } - // The performance hint of the processor(s) that the threads will be bound to. - // Framework will make the best effort to run the threads on the specific - // processors based on the performance hint. - // The attempt may fail for various reasons. Success isn't guaranteed. - optional ProcessorPerformance require_processor_performance = 4; - // Name prefix for worker threads, which can be useful for debugging - // multithreaded applications. - optional string thread_name_prefix = 5; -} diff --git a/protofiles/graphs/instant_motion_tracking/sticker_buffer.proto b/protofiles/graphs/instant_motion_tracking/sticker_buffer.proto deleted file mode 100644 index 3a73812..0000000 --- a/protofiles/graphs/instant_motion_tracking/sticker_buffer.proto +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2020 Google LLC -// -// 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. - -syntax = "proto2"; - -package akihabara.graphs.instant_motion_tracking.protobuf; - -message Sticker { - optional int32 id = 1; - optional float x = 2; - optional float y = 3; - optional float rotation = 4; - optional float scale = 5; - optional int32 render_id = 6; -} - -message StickerRoll { - repeated Sticker sticker = 1; -} diff --git a/protofiles/graphs/object_detection_3d/model_matrix.proto b/protofiles/graphs/object_detection_3d/model_matrix.proto deleted file mode 100644 index 3eaa858..0000000 --- a/protofiles/graphs/object_detection_3d/model_matrix.proto +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020 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. - -syntax = "proto2"; - -package akihabara.graphs.object_detection_3d.protobuf; - -message TimedModelMatrixProto { - // 4x4 model matrix stored in ROW major order. - repeated float matrix_entries = 1 [packed = true]; - // Timestamp of this model matrix in milliseconds. - optional int64 time_msec = 2 [default = 0]; - // Unique per object id - optional int32 id = 3 [default = -1]; -} - -message TimedModelMatrixProtoList { - repeated TimedModelMatrixProto model_matrix = 1; -} - -// For convenience, when the desired information or transformation can be -// encoded into vectors (e.g. when the matrix represents a scale or Euler-angle- -// based rotation operation.) -message TimedVectorProto { - // The vector values themselves. - repeated float vector_entries = 1 [packed = true]; - - // Timestamp of this vector in milliseconds. - optional int64 time_msec = 2 [default = 0]; - - // Unique per object id - optional int32 id = 3 [default = -1]; -} - -message TimedVectorProtoList { - repeated TimedVectorProto vector_list = 1; -} diff --git a/protofiles/modules/face_geometry/face_geometry.proto b/protofiles/modules/face_geometry/face_geometry.proto deleted file mode 100644 index 5d122f3..0000000 --- a/protofiles/modules/face_geometry/face_geometry.proto +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2020 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. - -syntax = "proto2"; - -package akihabara.modules.face_geometry.protobuf; - -import "protofiles/framework/formats/matrix_data.proto"; -import "protofiles/modules/face_geometry/mesh_3d.proto"; - -// Defines the face geometry pipeline estimation result format. -message FaceGeometry { - // Defines a mesh surface for a face. The face mesh vertex IDs are the same as - // the face landmark IDs. - // - // XYZ coordinates exist in the right-handed Metric 3D space configured by an - // environment. UV coodinates are taken from the canonical face mesh model. - // - // XY coordinates are guaranteed to match the screen positions of - // the input face landmarks after (1) being multiplied by the face pose - // transformation matrix and then (2) being projected with a perspective - // camera matrix of the same environment. - // - // NOTE: the triangular topology of the face mesh is only useful when derived - // from the 468 face landmarks, not from the 6 face detection landmarks - // (keypoints). The former don't cover the entire face and this mesh is - // defined here only to comply with the API. It should be considered as - // a placeholder and/or for debugging purposes. - // - // Use the face geometry derived from the face detection landmarks - // (keypoints) for the face pose transformation matrix, not the mesh. - optional Mesh3d mesh = 1; - - // Defines a face pose transformation matrix, which provides mapping from - // the static canonical face model to the runtime face. Tries to distinguish - // a head pose change from a facial expression change and to only reflect the - // former. - // - // Is a 4x4 matrix and contains only the following components: - // * Uniform scale - // * Rotation - // * Translation - // - // The last row is guaranteed to be `[0 0 0 1]`. - optional MatrixData pose_transform_matrix = 2; -} diff --git a/protofiles/modules/face_geometry/mesh_3d.proto b/protofiles/modules/face_geometry/mesh_3d.proto deleted file mode 100644 index a6dc108..0000000 --- a/protofiles/modules/face_geometry/mesh_3d.proto +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2020 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. - -syntax = "proto2"; - -package akihabara.modules.face_geometry.protobuf; - -message Mesh3d { - enum VertexType { - // Is defined by 5 coordinates: Position (XYZ) + Texture coordinate (UV). - VERTEX_PT = 0; - } - - enum PrimitiveType { - // Is defined by 3 indices: triangle vertex IDs. - TRIANGLE = 0; - } - - optional VertexType vertex_type = 1; - optional PrimitiveType primitive_type = 2; - // Vertex buffer size is a multiple of the vertex size (e.g., 5 for - // VERTEX_PT). - repeated float vertex_buffer = 3; - // Index buffer size is a multiple of the primitive size (e.g., 3 for - // TRIANGLE). - repeated uint32 index_buffer = 4; -} diff --git a/src/Akihabara.Tests/Framework/ImageFormat/ImageFrameTest.cs b/src/Akihabara.Tests/Framework/ImageFormat/ImageFrameTest.cs index 8224c46..f8612fb 100644 --- a/src/Akihabara.Tests/Framework/ImageFormat/ImageFrameTest.cs +++ b/src/Akihabara.Tests/Framework/ImageFormat/ImageFrameTest.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using Akihabara.Core; +using Akihabara.External; using Akihabara.Framework.ImageFormat; using NUnit.Framework; using UnmanageUtility; @@ -17,51 +18,54 @@ public class ImageFrameTest [Test, SignalAbort] public void Ctor_ShouldInstantiateImageFrame_When_CalledWithNoArguments() { - var imageFrame = new ImageFrame(); - - Assert.AreEqual(imageFrame.Format(), ImageFormat.Format.Unknown); - Assert.AreEqual(imageFrame.Width(), 0); - Assert.AreEqual(imageFrame.Height(), 0); - Assert.Throws(() => { imageFrame.ChannelSize(); }); - Assert.Throws(() => { imageFrame.NumberOfChannels(); }); - Assert.Throws(() => { imageFrame.ByteDepth(); }); - Assert.AreEqual(imageFrame.WidthStep(), 0); - Assert.AreEqual(imageFrame.PixelDataSize(), 0); - Assert.Throws(() => { imageFrame.PixelDataSizeStoredContiguously(); }); - Assert.True(imageFrame.IsEmpty()); - Assert.False(imageFrame.IsContiguous()); - Assert.False(imageFrame.IsAligned(16)); - Assert.AreEqual(imageFrame.MutablePixelData(), IntPtr.Zero); + using (var imageFrame = new ImageFrame()) + { + Assert.AreEqual(imageFrame.Format(), ImageFormat.Format.Unknown); + Assert.AreEqual(imageFrame.Width(), 0); + Assert.AreEqual(imageFrame.Height(), 0); + Assert.Throws(() => { imageFrame.ChannelSize(); }); + Assert.Throws(() => { imageFrame.NumberOfChannels(); }); + Assert.Throws(() => { imageFrame.ByteDepth(); }); + Assert.AreEqual(imageFrame.WidthStep(), 0); + Assert.AreEqual(imageFrame.PixelDataSize(), 0); + Assert.Throws(() => { imageFrame.PixelDataSizeStoredContiguously(); }); + Assert.True(imageFrame.IsEmpty()); + Assert.False(imageFrame.IsContiguous()); + Assert.False(imageFrame.IsAligned(16)); + Assert.AreEqual(imageFrame.MutablePixelData(), IntPtr.Zero); + } } [Test] public void Ctor_ShouldInstantiateImageFrame_When_CalledWithFormat() { - var imageFrame = new ImageFrame(ImageFormat.Format.Sbgra, 640, 480); - - Assert.AreEqual(imageFrame.Format(), ImageFormat.Format.Sbgra); - Assert.AreEqual(imageFrame.Width(), 640); - Assert.AreEqual(imageFrame.Height(), 480); - Assert.AreEqual(imageFrame.ChannelSize(), 1); - Assert.AreEqual(imageFrame.NumberOfChannels(), 4); - Assert.AreEqual(imageFrame.ByteDepth(), 1); - Assert.AreEqual(imageFrame.WidthStep(), 640 * 4); - Assert.AreEqual(imageFrame.PixelDataSize(), 640 * 480 * 4); - Assert.AreEqual(imageFrame.PixelDataSizeStoredContiguously(), 640 * 480 * 4); - Assert.False(imageFrame.IsEmpty()); - Assert.True(imageFrame.IsContiguous()); - Assert.True(imageFrame.IsAligned(16)); - Assert.AreNotEqual(imageFrame.MutablePixelData(), IntPtr.Zero); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Sbgra, 640, 480)) + { + Assert.AreEqual(imageFrame.Format(), ImageFormat.Format.Sbgra); + Assert.AreEqual(imageFrame.Width(), 640); + Assert.AreEqual(imageFrame.Height(), 480); + Assert.AreEqual(imageFrame.ChannelSize(), 1); + Assert.AreEqual(imageFrame.NumberOfChannels(), 4); + Assert.AreEqual(imageFrame.ByteDepth(), 1); + Assert.AreEqual(imageFrame.WidthStep(), 640 * 4); + Assert.AreEqual(imageFrame.PixelDataSize(), 640 * 480 * 4); + Assert.AreEqual(imageFrame.PixelDataSizeStoredContiguously(), 640 * 480 * 4); + Assert.False(imageFrame.IsEmpty()); + Assert.True(imageFrame.IsContiguous()); + Assert.True(imageFrame.IsAligned(16)); + Assert.AreNotEqual(imageFrame.MutablePixelData(), IntPtr.Zero); + } } [Test] public void Ctor_ShouldInstantiateImageFrame_When_CalledWithFormatAndAlignmentBoundary() { - var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 100, 100, 8); - - Assert.AreEqual(imageFrame.Width(), 100); - Assert.AreEqual(imageFrame.NumberOfChannels(), 1); - Assert.AreEqual(imageFrame.WidthStep(), 104); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 100, 100, 8)) + { + Assert.AreEqual(imageFrame.Width(), 100); + Assert.AreEqual(imageFrame.NumberOfChannels(), 1); + Assert.AreEqual(imageFrame.WidthStep(), 104); + } } [Test] @@ -74,14 +78,15 @@ public void Ctor_ShouldInstantiateImageFrame_When_CalledWithPixelData() }; pixelData.CopyFrom(srcBytes); - var imageFrame = new ImageFrame(ImageFormat.Format.Sbgra, 4, 2, 16, pixelData); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Sbgra, 4, 2, 16, pixelData)) + { + Assert.AreEqual(imageFrame.Width(), 4); + Assert.AreEqual(imageFrame.Height(), 2); + Assert.False(imageFrame.IsEmpty()); - Assert.AreEqual(imageFrame.Width(), 4); - Assert.AreEqual(imageFrame.Height(), 2); - Assert.False(imageFrame.IsEmpty()); - - var bytes = imageFrame.CopyToByteBuffer(32); - Assert.IsEmpty(bytes.Where((x, i) => x != srcBytes[i])); + var bytes = imageFrame.CopyToByteBuffer(32); + Assert.IsEmpty(bytes.Where((x, i) => x != srcBytes[i])); + } } [Test] @@ -95,9 +100,10 @@ public void Ctor_ShouldThrowMediaPipeException_When_CalledWithInvalidArgument() [Test] public void isDisposed_ShouldReturnFalse_When_NotDisposedYet() { - var imageFrame = new ImageFrame(); - - Assert.False(imageFrame.IsDisposed); + using (var imageFrame = new ImageFrame()) + { + Assert.False(imageFrame.IsDisposed); + } } [Test] @@ -114,13 +120,15 @@ public void isDisposed_ShouldReturnTrue_When_AlreadyDisposed() [Test] public void SetToZero_ShouldSetZeroToAllBytes() { - var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 10, 10); - var origBytes = imageFrame.CopyToByteBuffer(100); - Assert.False(origBytes.All((x) => x == 0)); - - imageFrame.SetToZero(); - var bytes = imageFrame.CopyToByteBuffer(100); - Assert.True(bytes.All((x) => x == 0)); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 10, 10)) + { + var origBytes = imageFrame.CopyToByteBuffer(100); + Assert.False(origBytes.All((x) => x == 0)); + + imageFrame.SetToZero(); + var bytes = imageFrame.CopyToByteBuffer(100); + Assert.True(bytes.All((x) => x == 0)); + } } #endregion @@ -128,9 +136,10 @@ public void SetToZero_ShouldSetZeroToAllBytes() [Test] public void SetAlignmentPaddingAreas_ShouldNotThrow() { - var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 10, 10, 16); - - Assert.DoesNotThrow(() => { imageFrame.SetAlignmentPaddingAreas(); }); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 10, 10, 16)) + { + Assert.DoesNotThrow(() => { imageFrame.SetAlignmentPaddingAreas(); }); + } } #endregion @@ -138,55 +147,64 @@ public void SetAlignmentPaddingAreas_ShouldNotThrow() [Test] public void CopyToByteBuffer_ShouldReturnByteArray_When_BufferSizeIsLargeEnough() { - var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 10, 10); - var normalBuffer = imageFrame.CopyToByteBuffer(100); - var largeBuffer = imageFrame.CopyToByteBuffer(120); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 10, 10)) + { + var normalBuffer = imageFrame.CopyToByteBuffer(100); + var largeBuffer = imageFrame.CopyToByteBuffer(120); - Assert.IsEmpty(normalBuffer.Where((x, i) => x != largeBuffer[i])); + Assert.IsEmpty(normalBuffer.Where((x, i) => x != largeBuffer[i])); + } } - [Test] + [Test, SignalAbort] public void CopyToByteBuffer_ShouldThrowException_When_BufferSizeIsTooSmall() { - var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 10, 10); - - Assert.Throws(() => { imageFrame.CopyToByteBuffer(99); }); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Gray8, 10, 10)) + { + Assert.Throws(() => { imageFrame.CopyToByteBuffer(99); }); + } } [Test] public void CopyToUshortBuffer_ShouldReturnUshortArray_When_BufferSizeIsLargeEnough() { - var imageFrame = new ImageFrame(ImageFormat.Format.Gray16, 10, 10); - var normalBuffer = imageFrame.CopyToUshortBuffer(100); - var largeBuffer = imageFrame.CopyToUshortBuffer(120); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Gray16, 10, 10)) + { + var normalBuffer = imageFrame.CopyToUshortBuffer(100); + var largeBuffer = imageFrame.CopyToUshortBuffer(120); - Assert.IsEmpty(normalBuffer.Where((x, i) => x != largeBuffer[i])); + Assert.IsEmpty(normalBuffer.Where((x, i) => x != largeBuffer[i])); + } } - [Test] + [Test, SignalAbort] public void CopyToUshortBuffer_ShouldThrowException_When_BufferSizeIsTooSmall() { - var imageFrame = new ImageFrame(ImageFormat.Format.Gray16, 10, 10); - - Assert.Throws(() => { imageFrame.CopyToUshortBuffer(99); }); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Gray16, 10, 10)) + { + Assert.Throws(() => { imageFrame.CopyToUshortBuffer(99); }); + } } [Test] public void CopyToFloatBuffer_ShouldReturnFloatArray_When_BufferSizeIsLargeEnough() { - var imageFrame = new ImageFrame(ImageFormat.Format.Vec32F1, 10, 10); - var normalBuffer = imageFrame.CopyToFloatBuffer(100); - var largeBuffer = imageFrame.CopyToFloatBuffer(120); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Vec32F1, 10, 10)) + { + var normalBuffer = imageFrame.CopyToFloatBuffer(100); + var largeBuffer = imageFrame.CopyToFloatBuffer(120); - Assert.IsEmpty(normalBuffer.Where((x, i) => Math.Abs(x - largeBuffer[i]) > 1e-9)); + Assert.IsEmpty(normalBuffer.Where((x, i) => Math.Abs(x - largeBuffer[i]) > 1e-9)); + } } - [Test] + [Test, SignalAbort] public void CopyToFloatBuffer_ShouldThrowException_When_BufferSizeIsTooSmall() { - var imageFrame = new ImageFrame(ImageFormat.Format.Vec32F1, 10, 10); - - Assert.Throws(() => { imageFrame.CopyToFloatBuffer(99); }); + using (var imageFrame = new ImageFrame(ImageFormat.Format.Vec32F1, 10, 10)) + { + Assert.Throws(() => { imageFrame.CopyToFloatBuffer(99); }); + } } #endregion } diff --git a/src/Akihabara.Tests/Framework/Port/StatusTest.cs b/src/Akihabara.Tests/Framework/Port/StatusTest.cs index 71e2c63..9807a05 100644 --- a/src/Akihabara.Tests/Framework/Port/StatusTest.cs +++ b/src/Akihabara.Tests/Framework/Port/StatusTest.cs @@ -4,6 +4,7 @@ using Akihabara.Core; using Akihabara.Framework.Port; using NUnit.Framework; +using System; namespace Tests { @@ -79,6 +80,12 @@ public void IsOk_ShouldReturnFalse_When_StatusIsFailedPrecondition() { var status = Status.FailedPrecondition(); + Console.WriteLine($"Status: {status}"); + Console.WriteLine($"status.Code: {status.Code}"); + Console.WriteLine($"status.RawCode: {status.RawCode}"); + Console.WriteLine($"status.ok: {status.ok}"); + Console.WriteLine("HOW IS IT LITERALLY CONTRADICTING ITSELF"); + Assert.False(status.ok); } #endregion diff --git a/src/Akihabara.Tests/SignalAbortAttribute.cs b/src/Akihabara.Tests/SignalAbortAttribute.cs index 3f1b8f5..be42e1e 100644 --- a/src/Akihabara.Tests/SignalAbortAttribute.cs +++ b/src/Akihabara.Tests/SignalAbortAttribute.cs @@ -5,4 +5,7 @@ using NUnit.Framework; [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -public class SignalAbortAttribute : CategoryAttribute { } +public class SignalAbortAttribute : CategoryAttribute +{ + public SignalAbortAttribute() : base("SignalAbortTest") { } +} diff --git a/src/Akihabara/Core/MpResourceHandle.cs b/src/Akihabara/Core/MpResourceHandle.cs index 20f1ec8..644fd53 100644 --- a/src/Akihabara/Core/MpResourceHandle.cs +++ b/src/Akihabara/Core/MpResourceHandle.cs @@ -49,8 +49,10 @@ protected override void DisposeUnmanaged() { if (OwnsResource()) { - ReleaseMpPtr(); + DeleteMpPtr(); } + ReleaseMpPtr(); + base.DisposeUnmanaged(); } /// diff --git a/src/Akihabara/Framework/ImageFormat/ImageFrame.cs b/src/Akihabara/Framework/ImageFormat/ImageFrame.cs index 4110a18..4136dea 100644 --- a/src/Akihabara/Framework/ImageFormat/ImageFrame.cs +++ b/src/Akihabara/Framework/ImageFormat/ImageFrame.cs @@ -21,7 +21,7 @@ public class ImageFrame : MpResourceHandle public ImageFrame() : base() { - UnsafeNativeMethods.mp_ImageFrame__(out var ptr); + UnsafeNativeMethods.mp_ImageFrame__(out var ptr).Assert(); Ptr = ptr; } @@ -31,7 +31,7 @@ public ImageFrame(ImageFormat.Format format, int width, int height) : this(forma public ImageFrame(ImageFormat.Format format, int width, int height, uint alignmentBoundary) : base() { - UnsafeNativeMethods.mp_ImageFrame__ui_i_i_ui(format, width, height, alignmentBoundary, out var ptr); + UnsafeNativeMethods.mp_ImageFrame__ui_i_i_ui(format, width, height, alignmentBoundary, out var ptr).Assert(); Ptr = ptr; } @@ -47,7 +47,7 @@ public ImageFrame(ImageFormat.Format format, int width, int height, int widthSte pixelData.Ptr, ReleasePixelData, out var ptr - ); + ).Assert(); Ptr = ptr; } @@ -76,7 +76,7 @@ public bool IsContiguous() public bool IsAligned(uint alignmentBoundary) { - SafeNativeMethods.mp_ImageFrame__IsAligned__ui(MpPtr, alignmentBoundary, out var value); + SafeNativeMethods.mp_ImageFrame__IsAligned__ui(MpPtr, alignmentBoundary, out var value).Assert(); GC.KeepAlive(this); return value; @@ -99,28 +99,26 @@ public int Height() public int ChannelSize() { - SafeNativeMethods.mp_ImageFrame__ChannelSize(MpPtr, out var val); + var code = SafeNativeMethods.mp_ImageFrame__ChannelSize(MpPtr, out var val); - // This is supposed to have a ValueOrFormatException() Function but we don't know - // what it implements. GC.KeepAlive(this); - return val; + return ValueOrFormatException(code, val); } public int NumberOfChannels() { - SafeNativeMethods.mp_ImageFrame__NumberOfChannels(MpPtr, out var val).Assert(); + var code = SafeNativeMethods.mp_ImageFrame__NumberOfChannels(MpPtr, out var val); GC.KeepAlive(this); - return val; + return ValueOrFormatException(code, val); } public int ByteDepth() { - SafeNativeMethods.mp_ImageFrame__ByteDepth(MpPtr, out var val).Assert(); + var code = SafeNativeMethods.mp_ImageFrame__ByteDepth(MpPtr, out var val); GC.KeepAlive(this); - return val; + return ValueOrFormatException(code, val); } public int WidthStep() @@ -128,9 +126,9 @@ public int WidthStep() return SafeNativeMethods.mp_ImageFrame__WidthStep(MpPtr); } - public int MutablePixelData() + public IntPtr MutablePixelData() { - return (int)SafeNativeMethods.mp_ImageFrame__MutablePixelData(MpPtr); + return SafeNativeMethods.mp_ImageFrame__MutablePixelData(MpPtr); } public int PixelDataSize() @@ -140,10 +138,10 @@ public int PixelDataSize() public int PixelDataSizeStoredContiguously() { - SafeNativeMethods.mp_ImageFrame__PixelDataSizeStoredContiguously(MpPtr, out var val); + var code = SafeNativeMethods.mp_ImageFrame__PixelDataSizeStoredContiguously(MpPtr, out var val); GC.KeepAlive(this); - return val; + return ValueOrFormatException(code, val); } public void SetToZero() @@ -184,7 +182,7 @@ private T[] CopyToBuffer(CopyToBufferHandler handler, int bufferSize) where T { fixed (T* bufferPtr = buffer) { - handler(MpPtr, (IntPtr)bufferPtr, bufferSize); + handler(MpPtr, (IntPtr)bufferPtr, bufferSize).Assert(); } } diff --git a/src/Akihabara/Framework/Port/Status.cs b/src/Akihabara/Framework/Port/Status.cs index 5644163..b49fca0 100644 --- a/src/Akihabara/Framework/Port/Status.cs +++ b/src/Akihabara/Framework/Port/Status.cs @@ -36,7 +36,7 @@ public Status(IntPtr ptr, bool isOwner = true) : base(ptr, isOwner) protected override void DeleteMpPtr() => UnsafeNativeMethods.absl_Status__delete(Ptr); - public bool ok => SafeNativeMethods.absl_Status__ok(Ptr); + public bool ok => SafeNativeMethods.absl_Status__ok(MpPtr); public void AssertOk() { diff --git a/src/Akihabara/Gpu/GpuResources.cs b/src/Akihabara/Gpu/GpuResources.cs index f5846ef..cecfdc5 100644 --- a/src/Akihabara/Gpu/GpuResources.cs +++ b/src/Akihabara/Gpu/GpuResources.cs @@ -65,7 +65,7 @@ public GpuResourceSharedPtr(IntPtr ptr) : base(ptr) { } protected override void DeleteMpPtr() { - UnsafeNativeMethods.mp_StatusOrGpuResources__delete(MpPtr); + UnsafeNativeMethods.mp_StatusOrGpuResources__delete(Ptr); } public override IntPtr Get() diff --git a/src/Akihabara/Native/MpReturnCode.cs b/src/Akihabara/Native/MpReturnCode.cs index 02f4f1f..1cb9cbe 100644 --- a/src/Akihabara/Native/MpReturnCode.cs +++ b/src/Akihabara/Native/MpReturnCode.cs @@ -7,10 +7,11 @@ namespace Akihabara.Native { public enum MpReturnCode : int { + Success = 0, /// /// A standard Exception is thrown /// - Success = 0, + StandardError = 1, /// /// An error beyond standard Exception is thrown /// @@ -33,7 +34,7 @@ public static void Assert(this MpReturnCode code) { case MpReturnCode.Success: return; case MpReturnCode.Aborted: - throw new MediapipeException("MediaPipe has aborted. See Glog files for details."); + throw new MediapipeException("Mediapipe has aborted. See Glog files for details."); default: throw new MediapipePluginException($"Failed to call a native function (code={code})"); } diff --git a/src/Akihabara/Native/UnsafeNativeMethods.cs b/src/Akihabara/Native/UnsafeNativeMethods.cs index 332902c..48fe073 100644 --- a/src/Akihabara/Native/UnsafeNativeMethods.cs +++ b/src/Akihabara/Native/UnsafeNativeMethods.cs @@ -17,7 +17,7 @@ public partial class UnsafeNativeMethods : NativeMethods { #region ABSL - [DllImport(MediaPipeLibrary, ExactSpelling = true, CharSet = CharSet.Unicode)] + [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode absl_Status__i_PKc(int code, string message, out IntPtr status); [DllImport(MediaPipeLibrary, ExactSpelling = true)] @@ -30,22 +30,22 @@ public partial class UnsafeNativeMethods : NativeMethods #region GoogleLogging - [DllImport(MediaPipeLibrary, ExactSpelling = true, CharSet = CharSet.Unicode)] + [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode google_InitGoogleLogging__PKc(string name, string logDir); [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode google_ShutdownGoogleLogging(); - [DllImport(MediaPipeLibrary, ExactSpelling = true, CharSet = CharSet.Unicode)] + [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode glog_LOG_INFO__PKc(string str); - [DllImport(MediaPipeLibrary, ExactSpelling = true, CharSet = CharSet.Unicode)] + [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode glog_LOG_WARNING__PKc(string str); - [DllImport(MediaPipeLibrary, ExactSpelling = true, CharSet = CharSet.Unicode)] + [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode glog_LOG_ERROR__PKc(string str); - [DllImport(MediaPipeLibrary, ExactSpelling = true, CharSet = CharSet.Unicode)] + [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode glog_LOG_FATAL__PKc(string str); [DllImport(MediaPipeLibrary, ExactSpelling = true)] diff --git a/third_party/opencv_linux.BUILD b/third_party/opencv_linux.BUILD index 72b1425..5839bff 100644 --- a/third_party/opencv_linux.BUILD +++ b/third_party/opencv_linux.BUILD @@ -29,14 +29,14 @@ cc_library( name = "opencv", srcs = glob( [ - "lib64/libopencv_core.so", - "lib64/libopencv_calib3d.so", - "lib64/libopencv_features2d.so", - "lib64/libopencv_highgui.so", - "lib64/libopencv_imgcodecs.so", - "lib64/libopencv_imgproc.so", - "lib64/libopencv_video.so", - "lib64/libopencv_videoio.so", + "lib/libopencv_core.so", + "lib/libopencv_calib3d.so", + "lib/libopencv_features2d.so", + "lib/libopencv_highgui.so", + "lib/libopencv_imgcodecs.so", + "lib/libopencv_imgproc.so", + "lib/libopencv_video.so", + "lib/libopencv_videoio.so", ], ), hdrs = glob([ @@ -58,14 +58,14 @@ cc_library( filegroup( name = "opencv_libs", srcs = [ - "lib64/libopencv_core.so", - "lib64/libopencv_calib3d.so", - "lib64/libopencv_features2d.so", - "lib64/libopencv_highgui.so", - "lib64/libopencv_imgcodecs.so", - "lib64/libopencv_imgproc.so", - "lib64/libopencv_video.so", - "lib64/libopencv_videoio.so", + "lib/libopencv_core.so", + "lib/libopencv_calib3d.so", + "lib/libopencv_features2d.so", + "lib/libopencv_highgui.so", + "lib/libopencv_imgcodecs.so", + "lib/libopencv_imgproc.so", + "lib/libopencv_video.so", + "lib/libopencv_videoio.so", ], visibility = ["//visibility:public"], )