// Copyright 2019 The MediaPipe Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include "mediapipe/calculators/internal/callback_packet_calculator.pb.h" // NOLINT #include "mediapipe/framework/calculator_base.h" #include "mediapipe/framework/calculator_registry.h" #include "mediapipe/framework/output_side_packet.h" namespace mediapipe { namespace { // Callback function for writing a packet to a vector. The output is before the // input since std::bind fills arguments from left to right (and only // dumped_data is filled by std::bind). void DumpToVector(std::vector* dumped_data, const Packet& packet) { dumped_data->push_back(packet); } // Callback function for saving the Timestamp::PostStream() packet. // The output is before the input since std::bind fills arguments from left to // right (and only post_stream_packet is filled by std::bind). void DumpPostStreamPacket(Packet* post_stream_packet, const Packet& packet) { if (packet.Timestamp() == Timestamp::PostStream()) { *post_stream_packet = packet; } } } // namespace // Creates a callback which takes a packet and stores it either in a // vector of packets or stores only the packet at PostStream timestamp. // The kind of callback is controlled by an option. The callback is // a std::function and is directly usable by CallbackCalculator. // Since the options for the packet generator include a serialized pointer // value, the resulting callback is only valid on the original machine // while that pointer is still alive. class CallbackPacketCalculator : public CalculatorBase { public: static absl::Status GetContract(CalculatorContract* cc) { const auto& options = cc->Options(); switch (options.type()) { case CallbackPacketCalculatorOptions::VECTOR_PACKET: case CallbackPacketCalculatorOptions::POST_STREAM_PACKET: cc->OutputSidePackets() .Index(0) .Set>(); break; default: return mediapipe::InvalidArgumentErrorBuilder(MEDIAPIPE_LOC) << "Invalid type of callback to produce."; } return absl::OkStatus(); } absl::Status Open(CalculatorContext* cc) override { const auto& options = cc->Options(); void* ptr; if (sscanf(options.pointer().c_str(), "%p", &ptr) != 1) { return mediapipe::InvalidArgumentErrorBuilder(MEDIAPIPE_LOC) << "Stored pointer value in options is invalid."; } switch (options.type()) { case CallbackPacketCalculatorOptions::VECTOR_PACKET: cc->OutputSidePackets().Index(0).Set( MakePacket>(std::bind( &DumpToVector, reinterpret_cast*>(ptr), std::placeholders::_1))); break; case CallbackPacketCalculatorOptions::POST_STREAM_PACKET: cc->OutputSidePackets().Index(0).Set( MakePacket>( std::bind(&DumpPostStreamPacket, reinterpret_cast(ptr), std::placeholders::_1))); break; default: return mediapipe::InvalidArgumentErrorBuilder(MEDIAPIPE_LOC) << "Invalid type to dump into."; } return absl::OkStatus(); } absl::Status Process(CalculatorContext* cc) override { return absl::OkStatus(); } }; REGISTER_CALCULATOR(CallbackPacketCalculator); } // namespace mediapipe