diff --git a/examples/protonect/CMakeLists.txt b/examples/protonect/CMakeLists.txt index ba93a6715..804353155 100644 --- a/examples/protonect/CMakeLists.txt +++ b/examples/protonect/CMakeLists.txt @@ -96,6 +96,7 @@ SET(SOURCES src/resource.cpp src/command_transaction.cpp src/registration.cpp + src/logging.cpp src/libfreenect2.cpp ${LIBFREENECT2_THREADING_SOURCE} diff --git a/examples/protonect/Protonect.cpp b/examples/protonect/Protonect.cpp index 3308fd0f7..c3305658e 100644 --- a/examples/protonect/Protonect.cpp +++ b/examples/protonect/Protonect.cpp @@ -56,6 +56,9 @@ int main(int argc, char *argv[]) } libfreenect2::Freenect2 freenect2; + // create a console logger with debug level (default is console logger with info level) + freenect2.setLogger(libfreenect2::createConsoleLogger(libfreenect2::Logger::Debug)); + libfreenect2::Freenect2Device *dev = 0; libfreenect2::PacketPipeline *pipeline = 0; diff --git a/examples/protonect/include/libfreenect2/depth_packet_stream_parser.h b/examples/protonect/include/libfreenect2/depth_packet_stream_parser.h index 7773cadc4..8086ae903 100644 --- a/examples/protonect/include/libfreenect2/depth_packet_stream_parser.h +++ b/examples/protonect/include/libfreenect2/depth_packet_stream_parser.h @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -51,7 +52,7 @@ LIBFREENECT2_PACK(struct LIBFREENECT2_API DepthSubPacketFooter uint32_t fields[32]; }); -class LIBFREENECT2_API DepthPacketStreamParser : public DataCallback +class LIBFREENECT2_API DepthPacketStreamParser : public DataCallback, public WithLoggerImpl { public: DepthPacketStreamParser(); diff --git a/examples/protonect/include/libfreenect2/libfreenect2.hpp b/examples/protonect/include/libfreenect2/libfreenect2.hpp index 38f36728a..d5b876b01 100644 --- a/examples/protonect/include/libfreenect2/libfreenect2.hpp +++ b/examples/protonect/include/libfreenect2/libfreenect2.hpp @@ -29,6 +29,7 @@ #include #include +#include namespace libfreenect2 { @@ -95,12 +96,15 @@ class LIBFREENECT2_API Freenect2Device class Freenect2Impl; -class LIBFREENECT2_API Freenect2 +class LIBFREENECT2_API Freenect2 : public WithLogger { public: Freenect2(void *usb_context = 0); virtual ~Freenect2(); + virtual void setLogger(Logger *logger); + virtual Logger *logger(); + int enumerateDevices(); std::string getDeviceSerialNumber(int idx); diff --git a/examples/protonect/include/libfreenect2/logging.h b/examples/protonect/include/libfreenect2/logging.h new file mode 100644 index 000000000..f71a386af --- /dev/null +++ b/examples/protonect/include/libfreenect2/logging.h @@ -0,0 +1,122 @@ +/* + * This file is part of the OpenKinect Project. http://www.openkinect.org + * + * Copyright (c) 2014 individual OpenKinect contributors. See the CONTRIB file + * for details. + * + * This code is licensed to you under the terms of the Apache License, version + * 2.0, or, at your option, the terms of the GNU General Public License, + * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses, + * or the following URLs: + * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.gnu.org/licenses/gpl-2.0.txt + * + * If you redistribute this file in source form, modified or unmodified, you + * may: + * 1) Leave this header intact and distribute it under the same terms, + * accompanying it with the APACHE20 and GPL20 files, or + * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or + * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file + * In all cases you must keep the copyright notice intact and include a copy + * of the CONTRIB file. + * + * Binary distributions must follow the binary distribution requirements of + * either License. + */ + +#ifndef LOGGING_H_ +#define LOGGING_H_ + +#include +#include + +#include + +namespace libfreenect2 +{ + +class LIBFREENECT2_API Logger +{ +public: + enum Level + { + Debug = 1, + Info = 2, + Warning = 3, + Error = 4, + }; + static Level getDefaultLevel(); + + virtual ~Logger(); + + virtual Level level() const; + + virtual void log(Level level, const std::string &message) = 0; +protected: + Level level_; +}; + +LIBFREENECT2_API Logger *createConsoleLogger(Logger::Level level); +LIBFREENECT2_API Logger *createConsoleLoggerWithDefaultLevel(); +LIBFREENECT2_API Logger *createNoopLogger(); + +class LIBFREENECT2_API LogMessage +{ +private: + Logger *logger_; + Logger::Level level_; + std::ostringstream stream_; +public: + LogMessage(Logger *logger, Logger::Level level); + ~LogMessage(); + + std::ostream &stream(); +}; + +class LIBFREENECT2_API WithLogger +{ +public: + virtual ~WithLogger(); + virtual void setLogger(Logger *logger) = 0; + virtual Logger *logger() = 0; +}; + +template +void trySetLogger(T *obj, Logger *logger) +{ + WithLogger *obj_with_logger = dynamic_cast(obj); + if(obj_with_logger != 0) + { + obj_with_logger->setLogger(logger); + } +} + +class LIBFREENECT2_API WithLoggerImpl : public WithLogger +{ +protected: + Logger *logger_; + + virtual void onLoggerChanged(Logger *logger); +public: + WithLoggerImpl(); + virtual ~WithLoggerImpl(); + virtual void setLogger(Logger *logger); + virtual Logger *logger(); +}; + +} /* namespace libfreenect2 */ + +#if defined(__GNUC__) or defined(__clang__) +#define LIBFREENECT2_LOG_SOURCE __PRETTY_FUNCTION__ +#elif defined(_MSC_VER) +#define LIBFREENECT2_LOG_SOURCE __FUNCSIG__ +#else +#define LIBFREENECT2_LOG_SOURCE "" +#endif + +#define LOG_DEBUG (::libfreenect2::LogMessage(logger(), ::libfreenect2::Logger::Debug).stream() << "[" << LIBFREENECT2_LOG_SOURCE << "] ") +#define LOG_INFO (::libfreenect2::LogMessage(logger(), ::libfreenect2::Logger::Info).stream() << "[" << LIBFREENECT2_LOG_SOURCE << "] ") +#define LOG_WARNING (::libfreenect2::LogMessage(logger(), ::libfreenect2::Logger::Warning).stream() << "[" << LIBFREENECT2_LOG_SOURCE << "] ") +#define LOG_ERROR (::libfreenect2::LogMessage(logger(), ::libfreenect2::Logger::Error).stream() << "[" << LIBFREENECT2_LOG_SOURCE << "] ") + +#endif /* LOGGING_H_ */ diff --git a/examples/protonect/include/libfreenect2/packet_pipeline.h b/examples/protonect/include/libfreenect2/packet_pipeline.h index b1bf467c2..2d6003138 100644 --- a/examples/protonect/include/libfreenect2/packet_pipeline.h +++ b/examples/protonect/include/libfreenect2/packet_pipeline.h @@ -28,6 +28,7 @@ #define PACKET_PIPELINE_H_ #include +#include #include #include #include @@ -50,7 +51,7 @@ class LIBFREENECT2_API PacketPipeline virtual DepthPacketProcessor *getDepthPacketProcessor() const = 0; }; -class LIBFREENECT2_API BasePacketPipeline : public PacketPipeline +class LIBFREENECT2_API BasePacketPipeline : public PacketPipeline, public WithLoggerImpl { protected: RgbPacketStreamParser *rgb_parser_; @@ -63,6 +64,8 @@ class LIBFREENECT2_API BasePacketPipeline : public PacketPipeline virtual void initialize(); virtual DepthPacketProcessor *createDepthPacketProcessor() = 0; + + virtual void onLoggerChanged(Logger *logger); public: virtual ~BasePacketPipeline(); diff --git a/examples/protonect/include/libfreenect2/protocol/command_transaction.h b/examples/protonect/include/libfreenect2/protocol/command_transaction.h index 6994c9104..56bd0b38a 100644 --- a/examples/protonect/include/libfreenect2/protocol/command_transaction.h +++ b/examples/protonect/include/libfreenect2/protocol/command_transaction.h @@ -28,6 +28,7 @@ #define COMMAND_TRANSACTION_H_ #include +#include #include namespace libfreenect2 @@ -35,7 +36,7 @@ namespace libfreenect2 namespace protocol { -class CommandTransaction +class CommandTransaction : public WithLoggerImpl { public: static const int ResponseCompleteLength = 16; @@ -63,7 +64,7 @@ class CommandTransaction }; CommandTransaction(libusb_device_handle *handle, int inbound_endpoint, int outbound_endpoint); - ~CommandTransaction(); + virtual ~CommandTransaction(); void execute(const CommandBase& command, Result& result); private: diff --git a/examples/protonect/include/libfreenect2/protocol/usb_control.h b/examples/protonect/include/libfreenect2/protocol/usb_control.h index f42cafed0..d4ffeb2eb 100644 --- a/examples/protonect/include/libfreenect2/protocol/usb_control.h +++ b/examples/protonect/include/libfreenect2/protocol/usb_control.h @@ -28,6 +28,7 @@ #define USB_CONTROL_H_ #include +#include namespace libfreenect2 { @@ -61,7 +62,7 @@ namespace protocol * * The 2. interface can be enabled/disabled by changing its alternate setting to 1/0 */ -class UsbControl +class UsbControl : public WithLoggerImpl { public: UsbControl(libusb_device_handle *handle); diff --git a/examples/protonect/include/libfreenect2/rgb_packet_stream_parser.h b/examples/protonect/include/libfreenect2/rgb_packet_stream_parser.h index ac1cd0caf..090d7cc1e 100644 --- a/examples/protonect/include/libfreenect2/rgb_packet_stream_parser.h +++ b/examples/protonect/include/libfreenect2/rgb_packet_stream_parser.h @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -38,7 +39,7 @@ namespace libfreenect2 { -class LIBFREENECT2_API RgbPacketStreamParser : public DataCallback +class LIBFREENECT2_API RgbPacketStreamParser : public DataCallback, public WithLoggerImpl { public: RgbPacketStreamParser(); diff --git a/examples/protonect/include/libfreenect2/usb/transfer_pool.h b/examples/protonect/include/libfreenect2/usb/transfer_pool.h index e4091a97a..8d54fbde4 100644 --- a/examples/protonect/include/libfreenect2/usb/transfer_pool.h +++ b/examples/protonect/include/libfreenect2/usb/transfer_pool.h @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -39,7 +40,7 @@ namespace libfreenect2 namespace usb { -class TransferPool +class TransferPool : public WithLoggerImpl { public: TransferPool(libusb_device_handle *device_handle, unsigned char device_endpoint); diff --git a/examples/protonect/src/command_transaction.cpp b/examples/protonect/src/command_transaction.cpp index b1b6efe84..90e4ac481 100644 --- a/examples/protonect/src/command_transaction.cpp +++ b/examples/protonect/src/command_transaction.cpp @@ -27,7 +27,6 @@ #include #include -#include namespace libfreenect2 { @@ -106,7 +105,7 @@ void CommandTransaction::execute(const CommandBase& command, Result& result) if(complete) { - std::cerr << "[CommandTransaction::execute] received premature response complete!" << std::endl; + LOG_ERROR << "received premature response complete!"; result.code = Error; } @@ -119,7 +118,7 @@ void CommandTransaction::execute(const CommandBase& command, Result& result) if(!complete) { - std::cerr << "[CommandTransaction::execute] missing response complete!" << std::endl; + LOG_ERROR << "missing response complete!"; result.code = Error; } @@ -135,13 +134,13 @@ CommandTransaction::ResultCode CommandTransaction::send(const CommandBase& comma if(r != LIBUSB_SUCCESS) { - std::cerr << "[CommandTransaction::send] bulk transfer failed! libusb error " << r << ": " << libusb_error_name(r) << std::endl; + LOG_ERROR << "bulk transfer failed! libusb error " << r << ": " << libusb_error_name(r); code = Error; } if(transferred_bytes != command.size()) { - std::cerr << "[CommandTransaction::send] sent number of bytes differs from expected number! expected: " << command.size() << " got: " << transferred_bytes << std::endl; + LOG_ERROR << "sent number of bytes differs from expected number! expected: " << command.size() << " got: " << transferred_bytes; code = Error; } @@ -157,7 +156,7 @@ void CommandTransaction::receive(CommandTransaction::Result& result) if(r != LIBUSB_SUCCESS) { - std::cerr << "[CommandTransaction::receive] bulk transfer failed! libusb error " << r << ": " << libusb_error_name(r) << std::endl; + LOG_ERROR << "bulk transfer failed! libusb error " << r << ": " << libusb_error_name(r); result.code = Error; } } @@ -176,7 +175,7 @@ bool CommandTransaction::isResponseCompleteResult(CommandTransaction::Result& re if(data[1] != sequence) { - std::cerr << "[CommandTransaction::isResponseCompleteResult] response complete with wrong sequence number! expected: " << sequence << " got: " << data[1]<< std::endl; + LOG_ERROR << "response complete with wrong sequence number! expected: " << sequence << " got: " << data[1]; } } } diff --git a/examples/protonect/src/depth_packet_stream_parser.cpp b/examples/protonect/src/depth_packet_stream_parser.cpp index 3a03c44ea..29c299f94 100644 --- a/examples/protonect/src/depth_packet_stream_parser.cpp +++ b/examples/protonect/src/depth_packet_stream_parser.cpp @@ -25,7 +25,6 @@ */ #include -#include #include namespace libfreenect2 @@ -79,7 +78,7 @@ void DepthPacketStreamParser::onDataReceived(unsigned char* buffer, size_t in_le if(wb.length + in_length > wb.capacity) { - std::cerr << "[DepthPacketStreamParser::onDataReceived] subpacket too large" << std::endl; + LOG_ERROR << "subpacket too large"; wb.length = 0; return; } @@ -91,7 +90,7 @@ void DepthPacketStreamParser::onDataReceived(unsigned char* buffer, size_t in_le { if(footer->length != wb.length) { - std::cerr << "[DepthPacketStreamParser::onDataReceived] image data too short!" << std::endl; + LOG_ERROR << "image data too short!"; } else { @@ -113,12 +112,12 @@ void DepthPacketStreamParser::onDataReceived(unsigned char* buffer, size_t in_le } else { - std::cerr << "[DepthPacketStreamParser::onDataReceived] skipping depth packet" << std::endl; + LOG_WARNING << "skipping depth packet"; } } else { - std::cerr << "[DepthPacketStreamParser::onDataReceived] not all subsequences received " << current_subsequence_ << std::endl; + LOG_ERROR << "not all subsequences received " << current_subsequence_; } current_sequence_ = footer->sequence; @@ -132,7 +131,7 @@ void DepthPacketStreamParser::onDataReceived(unsigned char* buffer, size_t in_le if(footer->subsequence * footer->length > fb.length) { - std::cerr << "[DepthPacketStreamParser::onDataReceived] front buffer too short! subsequence number is " << footer->subsequence << std::endl; + LOG_ERROR << "front buffer too short! subsequence number is " << footer->subsequence; } else { diff --git a/examples/protonect/src/libfreenect2.cpp b/examples/protonect/src/libfreenect2.cpp index e34da1b1b..45f6b5678 100644 --- a/examples/protonect/src/libfreenect2.cpp +++ b/examples/protonect/src/libfreenect2.cpp @@ -45,7 +45,7 @@ using namespace libfreenect2; using namespace libfreenect2::usb; using namespace libfreenect2::protocol; -class Freenect2DeviceImpl : public Freenect2Device +class Freenect2DeviceImpl : public Freenect2Device, public WithLoggerImpl { private: enum State @@ -74,6 +74,8 @@ class Freenect2DeviceImpl : public Freenect2Device std::string serial_, firmware_; Freenect2Device::IrCameraParams ir_camera_params_; Freenect2Device::ColorCameraParams rgb_camera_params_; +protected: + virtual void onLoggerChanged(Logger *logger); public: Freenect2DeviceImpl(Freenect2Impl *context, const PacketPipeline *pipeline, libusb_device *usb_device, libusb_device_handle *usb_device_handle, const std::string &serial); virtual ~Freenect2DeviceImpl(); @@ -110,7 +112,7 @@ std::ostream &operator<<(std::ostream &out, const PrintBusAndDevice& dev) return out; } -class Freenect2Impl +class Freenect2Impl : public WithLoggerImpl { private: bool managed_usb_context_; @@ -134,20 +136,22 @@ class Freenect2Impl usb_context_(reinterpret_cast(usb_context)), has_device_enumeration_(false) { + logger_ = createConsoleLoggerWithDefaultLevel(); + if(managed_usb_context_) { int r = libusb_init(&usb_context_); // TODO: error handling if(r != 0) { - std::cout << "[Freenect2Impl] failed to create usb context!" << std::endl; + LOG_ERROR << "failed to create usb context!"; } } usb_event_loop_.start(usb_context_); } - ~Freenect2Impl() + virtual ~Freenect2Impl() { clearDevices(); clearDeviceEnumeration(); @@ -159,10 +163,33 @@ class Freenect2Impl libusb_exit(usb_context_); usb_context_ = 0; } + + setLoggerInternal(0); + } + + void setLoggerInternal(Logger *logger) + { + Logger *old_logger = logger_; + WithLoggerImpl::setLogger(logger); + delete old_logger; + } + + virtual void setLogger(Logger *logger) + { + setLoggerInternal(logger != 0 ? logger : createNoopLogger()); + } + + virtual void onLoggerChanged(Logger *logger) + { + for(DeviceVector::iterator it = devices_.begin(); it != devices_.end(); ++it) + { + (*it)->setLogger(logger); + } } void addDevice(Freenect2DeviceImpl *device) { + device->setLogger(logger_); devices_.push_back(device); } @@ -173,10 +200,11 @@ class Freenect2Impl if(it != devices_.end()) { devices_.erase(it); + device->setLogger(0); } else { - std::cout << "[Freenect2Impl] tried to remove device, which is not in the internal device list!" << std::endl; + LOG_WARNING << "tried to remove device, which is not in the internal device list!"; } } @@ -205,7 +233,7 @@ class Freenect2Impl if(!devices_.empty()) { - std::cout << "[Freenect2Impl] after deleting all devices the internal device list should be empty!" << std::endl; + LOG_WARNING << "after deleting all devices the internal device list should be empty!"; } } @@ -223,11 +251,11 @@ class Freenect2Impl void enumerateDevices() { - std::cout << "[Freenect2Impl] enumerating devices..." << std::endl; + LOG_INFO << "enumerating devices..."; libusb_device **device_list; int num_devices = libusb_get_device_list(usb_context_, &device_list); - std::cout << "[Freenect2Impl] " << num_devices << " usb devices connected" << std::endl; + LOG_INFO << num_devices << " usb devices connected"; if(num_devices > 0) { @@ -268,21 +296,21 @@ class Freenect2Impl dev_with_serial.dev = dev; dev_with_serial.serial = std::string(reinterpret_cast(buffer), size_t(r)); - std::cout << "[Freenect2Impl] found valid Kinect v2 " << PrintBusAndDevice(dev) << " with serial " << dev_with_serial.serial << std::endl; + LOG_INFO << "found valid Kinect v2 " << PrintBusAndDevice(dev) << " with serial " << dev_with_serial.serial; // valid Kinect v2 enumerated_devices_.push_back(dev_with_serial); continue; } else { - std::cout << "[Freenect2Impl] failed to get serial number of Kinect v2 " << PrintBusAndDevice(dev) << "!" << std::endl; + LOG_ERROR << "failed to get serial number of Kinect v2 " << PrintBusAndDevice(dev) << "!"; } libusb_close(dev_handle); } else { - std::cout << "[Freenect2Impl] failed to open Kinect v2 " << PrintBusAndDevice(dev) << "!" << std::endl; + LOG_ERROR << "failed to open Kinect v2 " << PrintBusAndDevice(dev) << "!"; } } } @@ -293,7 +321,7 @@ class Freenect2Impl libusb_free_device_list(device_list, 0); has_device_enumeration_ = true; - std::cout << "[Freenect2Impl] found " << enumerated_devices_.size() << " devices" << std::endl; + LOG_INFO << "found " << enumerated_devices_.size() << " devices"; } int getNumDevices() @@ -338,6 +366,17 @@ Freenect2DeviceImpl::~Freenect2DeviceImpl() delete pipeline_; } +void Freenect2DeviceImpl::onLoggerChanged(Logger *logger) +{ + rgb_transfer_pool_.setLogger(logger); + ir_transfer_pool_.setLogger(logger); + usb_control_.setLogger(logger); + command_tx_.setLogger(logger); + + // TODO: is this ok? + trySetLogger(const_cast(pipeline_), logger); +} + int Freenect2DeviceImpl::nextCommandSeq() { return command_seq_++; @@ -397,7 +436,7 @@ void Freenect2DeviceImpl::setIrAndDepthFrameListener(libfreenect2::FrameListener bool Freenect2DeviceImpl::open() { - std::cout << "[Freenect2DeviceImpl] opening..." << std::endl; + LOG_INFO << "opening..."; if(state_ != Created) return false; @@ -417,7 +456,7 @@ bool Freenect2DeviceImpl::open() if(max_iso_packet_size < 0x8400) { - std::cout << "[Freenect2DeviceImpl] max iso packet size for endpoint 0x84 too small! (expected: " << 0x8400 << " got: " << max_iso_packet_size << ")" << std::endl; + LOG_ERROR << "max iso packet size for endpoint 0x84 too small! (expected: " << 0x8400 << " got: " << max_iso_packet_size << ")"; return false; } @@ -426,14 +465,14 @@ bool Freenect2DeviceImpl::open() state_ = Open; - std::cout << "[Freenect2DeviceImpl] opened" << std::endl; + LOG_INFO << "opened"; return true; } void Freenect2DeviceImpl::start() { - std::cout << "[Freenect2DeviceImpl] starting..." << std::endl; + LOG_INFO << "starting..."; if(state_ != Open) return; CommandTransaction::Result serial_result, firmware_result, result; @@ -444,15 +483,16 @@ void Freenect2DeviceImpl::start() firmware_ = FirmwareVersionResponse(firmware_result.data, firmware_result.length).toString(); command_tx_.execute(ReadData0x14Command(nextCommandSeq()), result); - std::cout << "[Freenect2DeviceImpl] ReadData0x14 response" << std::endl; - std::cout << GenericResponse(result.data, result.length).toString() << std::endl; + LOG_DEBUG + << "ReadData0x14 response" << std::endl + << GenericResponse(result.data, result.length).toString(); command_tx_.execute(ReadSerialNumberCommand(nextCommandSeq()), serial_result); std::string new_serial = SerialNumberResponse(serial_result.data, serial_result.length).toString(); if(serial_ != new_serial) { - std::cout << "[Freenect2DeviceImpl] serial number reported by libusb " << serial_ << " differs from serial number " << new_serial << " in device protocol! " << std::endl; + LOG_WARNING << "serial number reported by libusb " << serial_ << " differs from serial number " << new_serial << " in device protocol! "; } command_tx_.execute(ReadDepthCameraParametersCommand(nextCommandSeq()), result); @@ -506,16 +546,18 @@ void Freenect2DeviceImpl::start() rgb_camera_params_.my_x0y0 = rgb_p->my_x0y0; // 1 command_tx_.execute(ReadStatus0x090000Command(nextCommandSeq()), result); - std::cout << "[Freenect2DeviceImpl] ReadStatus0x090000 response" << std::endl; - std::cout << GenericResponse(result.data, result.length).toString() << std::endl; + LOG_DEBUG + << "ReadStatus0x090000 response" << std::endl + << GenericResponse(result.data, result.length).toString(); command_tx_.execute(InitStreamsCommand(nextCommandSeq()), result); usb_control_.setIrInterfaceState(UsbControl::Enabled); command_tx_.execute(ReadStatus0x090000Command(nextCommandSeq()), result); - std::cout << "[Freenect2DeviceImpl] ReadStatus0x090000 response" << std::endl; - std::cout << GenericResponse(result.data, result.length).toString() << std::endl; + LOG_DEBUG + << "ReadStatus0x090000 response" << std::endl + << GenericResponse(result.data, result.length).toString(); command_tx_.execute(SetStreamEnabledCommand(nextCommandSeq()), result); @@ -536,33 +578,33 @@ void Freenect2DeviceImpl::start() command_tx_.execute(ReadData0x26Command(nextCommandSeq()), result); command_tx_.execute(ReadData0x26Command(nextCommandSeq()), result); */ - std::cout << "[Freenect2DeviceImpl] enabling usb transfer submission..." << std::endl; + LOG_INFO << "enabling usb transfer submission..."; rgb_transfer_pool_.enableSubmission(); ir_transfer_pool_.enableSubmission(); - std::cout << "[Freenect2DeviceImpl] submitting usb transfers..." << std::endl; + LOG_INFO << "submitting usb transfers..."; rgb_transfer_pool_.submit(20); ir_transfer_pool_.submit(60); state_ = Streaming; - std::cout << "[Freenect2DeviceImpl] started" << std::endl; + LOG_INFO << "started"; } void Freenect2DeviceImpl::stop() { - std::cout << "[Freenect2DeviceImpl] stopping..." << std::endl; + LOG_INFO << "stopping..."; if(state_ != Streaming) { - std::cout << "[Freenect2DeviceImpl] already stopped, doing nothing" << std::endl; + LOG_INFO << "already stopped, doing nothing"; return; } - std::cout << "[Freenect2DeviceImpl] disabling usb transfer submission..." << std::endl; + LOG_INFO << "disabling usb transfer submission..."; rgb_transfer_pool_.disableSubmission(); ir_transfer_pool_.disableSubmission(); - std::cout << "[Freenect2DeviceImpl] canceling usb transfers..." << std::endl; + LOG_INFO << "canceling usb transfers..."; rgb_transfer_pool_.cancel(); ir_transfer_pool_.cancel(); @@ -575,16 +617,16 @@ void Freenect2DeviceImpl::stop() usb_control_.setVideoTransferFunctionState(UsbControl::Disabled); state_ = Open; - std::cout << "[Freenect2DeviceImpl] stopped" << std::endl; + LOG_INFO << "stopped"; } void Freenect2DeviceImpl::close() { - std::cout << "[Freenect2DeviceImpl] closing..." << std::endl; + LOG_INFO << "closing..."; if(state_ == Closed) { - std::cout << "[Freenect2DeviceImpl] already closed, doing nothing" << std::endl; + LOG_INFO << "already closed, doing nothing"; return; } @@ -601,24 +643,24 @@ void Freenect2DeviceImpl::close() if(has_usb_interfaces_) { - std::cout << "[Freenect2DeviceImpl] releasing usb interfaces..." << std::endl; + LOG_INFO << "releasing usb interfaces..."; usb_control_.releaseInterfaces(); has_usb_interfaces_ = false; } - std::cout << "[Freenect2DeviceImpl] deallocating usb transfer pools..." << std::endl; + LOG_INFO << "deallocating usb transfer pools..."; rgb_transfer_pool_.deallocate(); ir_transfer_pool_.deallocate(); - std::cout << "[Freenect2DeviceImpl] closing usb device..." << std::endl; + LOG_INFO << "closing usb device..."; libusb_close(usb_device_handle_); usb_device_handle_ = 0; usb_device_ = 0; state_ = Closed; - std::cout << "[Freenect2DeviceImpl] closed" << std::endl; + LOG_INFO << "closed"; } PacketPipeline *createDefaultPacketPipeline() @@ -644,6 +686,16 @@ Freenect2::~Freenect2() delete impl_; } +void Freenect2::setLogger(Logger *logger) +{ + impl_->setLogger(logger); +} + +Logger *Freenect2::logger() +{ + return impl_->logger(); +} + int Freenect2::enumerateDevices() { impl_->clearDeviceEnumeration(); @@ -677,8 +729,9 @@ Freenect2Device *Freenect2::openDevice(int idx, const PacketPipeline *pipeline, if(idx >= num_devices) { - std::cout << "[Freenect2Impl] requested device " << idx << " is not connected!" << std::endl; + LOG_ERROR << "requested device " << idx << " is not connected!"; delete pipeline; + return device; } @@ -687,9 +740,9 @@ Freenect2Device *Freenect2::openDevice(int idx, const PacketPipeline *pipeline, if(impl_->tryGetDevice(dev.dev, &device)) { - std::cout << "[Freenect2Impl] failed to get device " << PrintBusAndDevice(dev.dev) - << " (the device may already be open)" << std::endl; + LOG_WARNING << "device " << PrintBusAndDevice(dev.dev) << " is already be open!"; delete pipeline; + return device; } @@ -697,8 +750,9 @@ Freenect2Device *Freenect2::openDevice(int idx, const PacketPipeline *pipeline, if(r != LIBUSB_SUCCESS) { - std::cout << "[Freenect2Impl] failed to open Kinect v2 " << PrintBusAndDevice(dev.dev) << "!" << std::endl; + LOG_ERROR << "failed to open Kinect v2 " << PrintBusAndDevice(dev.dev) << "!"; delete pipeline; + return device; } @@ -726,7 +780,7 @@ Freenect2Device *Freenect2::openDevice(int idx, const PacketPipeline *pipeline, libfreenect2::this_thread::sleep_for(libfreenect2::chrono::milliseconds(1000)); // reenumerate devices - std::cout << "[Freenect2Impl] re-enumerating devices after reset" << std::endl; + LOG_INFO << "re-enumerating devices after reset"; impl_->clearDeviceEnumeration(); impl_->enumerateDevices(); @@ -735,8 +789,9 @@ Freenect2Device *Freenect2::openDevice(int idx, const PacketPipeline *pipeline, } else if(r != LIBUSB_SUCCESS) { - std::cout << "[Freenect2Impl] failed to reset Kinect v2 " << PrintBusAndDevice(dev.dev) << "!" << std::endl; + LOG_ERROR << "failed to reset Kinect v2 " << PrintBusAndDevice(dev.dev) << "!"; delete pipeline; + return device; } } @@ -749,7 +804,7 @@ Freenect2Device *Freenect2::openDevice(int idx, const PacketPipeline *pipeline, delete device; device = 0; - std::cout << "[Freenect2DeviceImpl] failed to open Kinect v2 " << PrintBusAndDevice(dev.dev) << "!" << std::endl; + LOG_ERROR << "failed to open Kinect v2 " << PrintBusAndDevice(dev.dev) << "!"; } return device; diff --git a/examples/protonect/src/logging.cpp b/examples/protonect/src/logging.cpp new file mode 100644 index 000000000..ef1ad986e --- /dev/null +++ b/examples/protonect/src/logging.cpp @@ -0,0 +1,164 @@ +/* + * This file is part of the OpenKinect Project. http://www.openkinect.org + * + * Copyright (c) 2015 individual OpenKinect contributors. See the CONTRIB file + * for details. + * + * This code is licensed to you under the terms of the Apache License, version + * 2.0, or, at your option, the terms of the GNU General Public License, + * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses, + * or the following URLs: + * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.gnu.org/licenses/gpl-2.0.txt + * + * If you redistribute this file in source form, modified or unmodified, you + * may: + * 1) Leave this header intact and distribute it under the same terms, + * accompanying it with the APACHE20 and GPL20 files, or + * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or + * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file + * In all cases you must keep the copyright notice intact and include a copy + * of the CONTRIB file. + * + * Binary distributions must follow the binary distribution requirements of + * either License. + */ + +#include +#include +#include +#include +#include + +namespace libfreenect2 +{ +Logger::~Logger() {} + + +Logger::Level Logger::getDefaultLevel() +{ + Logger::Level l = Logger::Info; + + char *env_logger_level_c_str = getenv("LIBFREENECT2_LOGGER_LEVEL"); + + if(env_logger_level_c_str != 0) + { + std::string env_logger_level_str(env_logger_level_c_str); + std::transform(env_logger_level_str.begin(), env_logger_level_str.end(), env_logger_level_str.begin(), ::tolower); + + if(env_logger_level_str == "debug") + l = Logger::Debug; + else if(env_logger_level_str == "info") + l = Logger::Info; + else if(env_logger_level_str == "warning") + l = Logger::Warning; + else if(env_logger_level_str == "error") + l = Logger::Error; + } + + return l; +} + +Logger::Level Logger::level() const +{ + return level_; +} + +std::string level2str(const Logger::Level &l) +{ + switch(l) + { + case Logger::Debug: + return "Debug"; + case Logger::Info: + return "Info"; + case Logger::Warning: + return "Warning"; + case Logger::Error: + return "Error"; + default: + return ""; + } +} + +class ConsoleLogger : public Logger +{ +public: + ConsoleLogger(Level level) + { + level_ = level; + } + virtual ~ConsoleLogger() {} + virtual void log(Level level, const std::string &message) + { + if(level < level_) return; + + (level >= Warning ? std::cerr : std::cout) << "[" << level2str(level) << "]" << message << std::endl; + } +}; + +class NoopLogger : public Logger +{ +public: + NoopLogger() + { + level_ = Debug; + } + virtual ~NoopLogger() {} + virtual void log(Level level, const std::string &message) {} +}; + +Logger *createConsoleLogger(Logger::Level level) +{ + return new ConsoleLogger(level); +} + +Logger *createConsoleLoggerWithDefaultLevel() +{ + return new ConsoleLogger(Logger::getDefaultLevel()); +} + +Logger *createNoopLogger() +{ + return new NoopLogger(); +} + +LogMessage::LogMessage(Logger *logger, Logger::Level level) : logger_(logger), level_(level) +{ + +} + +LogMessage::~LogMessage() +{ + if(logger_ != 0) + { + logger_->log(level_, stream_.str()); + } +} + +std::ostream &LogMessage::stream() +{ + return stream_; +} + +WithLogger::~WithLogger() {} + +WithLoggerImpl::WithLoggerImpl() : logger_(0) +{ +} + +WithLoggerImpl::~WithLoggerImpl() {} +void WithLoggerImpl::onLoggerChanged(Logger *logger) {} + +void WithLoggerImpl::setLogger(Logger *logger) +{ + logger_ = logger; + onLoggerChanged(logger_); +} + +Logger *WithLoggerImpl::logger() +{ + return logger_; +} + +} /* namespace libfreenect2 */ diff --git a/examples/protonect/src/packet_pipeline.cpp b/examples/protonect/src/packet_pipeline.cpp index 1c66f66b6..9642291f9 100644 --- a/examples/protonect/src/packet_pipeline.cpp +++ b/examples/protonect/src/packet_pipeline.cpp @@ -49,6 +49,14 @@ void BasePacketPipeline::initialize() depth_parser_->setPacketProcessor(async_depth_processor_); } +void BasePacketPipeline::onLoggerChanged(Logger *logger) +{ + rgb_parser_->setLogger(logger); + depth_parser_->setLogger(logger); + trySetLogger(rgb_processor_, logger); + trySetLogger(depth_processor_, logger); +} + BasePacketPipeline::~BasePacketPipeline() { delete async_rgb_processor_; diff --git a/examples/protonect/src/rgb_packet_stream_parser.cpp b/examples/protonect/src/rgb_packet_stream_parser.cpp index 4eaaf49c5..c9805a7c1 100644 --- a/examples/protonect/src/rgb_packet_stream_parser.cpp +++ b/examples/protonect/src/rgb_packet_stream_parser.cpp @@ -27,7 +27,6 @@ #include #include #include -#include namespace libfreenect2 { @@ -88,7 +87,7 @@ void RgbPacketStreamParser::onDataReceived(unsigned char* buffer, size_t length) } else { - std::cerr << "[RgbPacketStreamParser::onDataReceived] buffer overflow!" << std::endl; + LOG_ERROR << "buffer overflow!"; fb.length = 0; return; } @@ -105,14 +104,14 @@ void RgbPacketStreamParser::onDataReceived(unsigned char* buffer, size_t length) if (fb.length != footer->packet_size || raw_packet->sequence != footer->sequence) { - std::cerr << "[RgbPacketStreamParser::onDataReceived] packetsize or sequence doesn't match!" << std::endl; + LOG_ERROR << "packetsize or sequence doesn't match!"; fb.length = 0; return; } if (fb.length - sizeof(RawRgbPacket) - sizeof(RgbPacketFooter) < footer->filler_length) { - std::cerr << "[RgbPacketStreamParser::onDataReceived] not enough space for packet filler!" << std::endl; + LOG_ERROR << "not enough space for packet filler!"; fb.length = 0; return; } @@ -132,7 +131,7 @@ void RgbPacketStreamParser::onDataReceived(unsigned char* buffer, size_t length) if (jpeg_length == 0) { - std::cerr << "[RgbPacketStreamParser::onDataReceived] no JPEG detected!" << std::endl; + LOG_ERROR << "no JPEG detected!"; fb.length = 0; return; } @@ -155,7 +154,7 @@ void RgbPacketStreamParser::onDataReceived(unsigned char* buffer, size_t length) } else { - std::cerr << "[RgbPacketStreamParser::onDataReceived] skipping rgb packet!" << std::endl; + LOG_WARNING << "skipping rgb packet!"; } // reset front buffer diff --git a/examples/protonect/src/transfer_pool.cpp b/examples/protonect/src/transfer_pool.cpp index b324659a4..b45087db1 100644 --- a/examples/protonect/src/transfer_pool.cpp +++ b/examples/protonect/src/transfer_pool.cpp @@ -25,7 +25,6 @@ */ #include -#include namespace libfreenect2 { @@ -77,13 +76,13 @@ void TransferPool::submit(size_t num_parallel_transfers) { if(!enable_submit_) { - std::cerr << "[TransferPool::submit] transfer submission disabled!" << std::endl; + LOG_WARNING << "transfer submission disabled!"; return; } if(transfers_.size() < num_parallel_transfers) { - std::cerr << "[TransferPool::submit] too few idle transfers!" << std::endl; + LOG_ERROR << "too few idle transfers!"; } for(size_t i = 0; i < num_parallel_transfers; ++i) @@ -95,7 +94,7 @@ void TransferPool::submit(size_t num_parallel_transfers) if(r != LIBUSB_SUCCESS) { - std::cerr << "[TransferPool::submit] failed to submit transfer: " << libusb_error_name(r) << std::endl; + LOG_ERROR << "failed to submit transfer: " << libusb_error_name(r); transfers_[i].setStopped(true); } } @@ -109,7 +108,7 @@ void TransferPool::cancel() if(r != LIBUSB_SUCCESS && r != LIBUSB_ERROR_NOT_FOUND) { - std::cerr << "[TransferPool::cancel] failed to cancel transfer: " << libusb_error_name(r) << std::endl; + LOG_ERROR << "failed to cancel transfer: " << libusb_error_name(r); } } @@ -121,7 +120,7 @@ void TransferPool::cancel() stopped_transfers += it->getStopped(); if (stopped_transfers == transfers_.size()) break; - std::cerr << "[TransferPool::cancel] waiting for transfer cancellation" << std::endl; + LOG_INFO << "waiting for transfer cancellation"; libfreenect2::this_thread::sleep_for(libfreenect2::chrono::milliseconds(1000)); } } @@ -186,7 +185,7 @@ void TransferPool::onTransferComplete(TransferPool::Transfer* t) if(r != LIBUSB_SUCCESS) { - std::cerr << "[TransferPool::onTransferComplete] failed to submit transfer: " << libusb_error_name(r) << std::endl; + LOG_ERROR << "failed to submit transfer: " << libusb_error_name(r); t->setStopped(true); } } diff --git a/examples/protonect/src/usb_control.cpp b/examples/protonect/src/usb_control.cpp index 360b96b09..2497e3151 100644 --- a/examples/protonect/src/usb_control.cpp +++ b/examples/protonect/src/usb_control.cpp @@ -187,18 +187,8 @@ UsbControl::~UsbControl() { } -static UsbControl::ResultCode checkLibusbResult(const char* method, int r) -{ - if(r != LIBUSB_SUCCESS) - { - std::cerr << "[UsbControl::" << method << "] failed! libusb error " << r << ": " << libusb_error_name(r) << std::endl; - return UsbControl::Error; - } - else - { - return UsbControl::Success; - } -} +#define CHECK_LIBUSB_RESULT(__CODE, __RESULT) if((__CODE = (__RESULT == LIBUSB_SUCCESS ? Success : Error)) == Error) LOG_ERROR +#define WRITE_LIBUSB_ERROR(__RESULT) "libusb error " << __RESULT << ": " << libusb_error_name(__RESULT) UsbControl::ResultCode UsbControl::setConfiguration() { @@ -208,14 +198,14 @@ UsbControl::ResultCode UsbControl::setConfiguration() int r; r = libusb_get_configuration(handle_, ¤t_config_id); - code = checkLibusbResult("setConfiguration(initial get)", r); + CHECK_LIBUSB_RESULT(code, r) << "failed to get configuration! " << WRITE_LIBUSB_ERROR(r); if(code == Success) { if(current_config_id != desired_config_id) { r = libusb_set_configuration(handle_, desired_config_id); - code = checkLibusbResult("setConfiguration(set)", r); + CHECK_LIBUSB_RESULT(code, r) << "failed to set configuration! " << WRITE_LIBUSB_ERROR(r); } } @@ -228,12 +218,12 @@ UsbControl::ResultCode UsbControl::claimInterfaces() int r; r = libusb_claim_interface(handle_, ControlAndRgbInterfaceId); - code = checkLibusbResult("claimInterfaces(ControlAndRgbInterfaceId)", r); + CHECK_LIBUSB_RESULT(code, r) << "failed to claim interface with ControlAndRgbInterfaceId(="<< ControlAndRgbInterfaceId << ")! " << WRITE_LIBUSB_ERROR(r); if(code == Success) { r = libusb_claim_interface(handle_, IrInterfaceId); - code = checkLibusbResult("claimInterfaces(IrInterfaceId)", r); + CHECK_LIBUSB_RESULT(code, r) << "failed to claim interface with IrInterfaceId(="<< IrInterfaceId << ")! " << WRITE_LIBUSB_ERROR(r); } return code; @@ -245,12 +235,12 @@ UsbControl::ResultCode UsbControl::releaseInterfaces() int r; r = libusb_release_interface(handle_, ControlAndRgbInterfaceId); - code = checkLibusbResult("releaseInterfaces(ControlAndRgbInterfaceId)", r); + CHECK_LIBUSB_RESULT(code, r) << "failed to release interface with ControlAndRgbInterfaceId(="<< ControlAndRgbInterfaceId << ")! " << WRITE_LIBUSB_ERROR(r); if(code == Success) { r = libusb_release_interface(handle_, IrInterfaceId); - code = checkLibusbResult("releaseInterfaces(IrInterfaceId)", r); + CHECK_LIBUSB_RESULT(code, r) << "failed to release interface with IrInterfaceId(="<< IrInterfaceId << ")! " << WRITE_LIBUSB_ERROR(r); } return code; @@ -260,14 +250,18 @@ UsbControl::ResultCode UsbControl::setIsochronousDelay() { int r = libusb_ext::set_isochronous_delay(handle_, timeout_); - return checkLibusbResult("setIsochronousDelay", r); + UsbControl::ResultCode code; + CHECK_LIBUSB_RESULT(code, r) << "failed to set isochronous delay! " << WRITE_LIBUSB_ERROR(r); + return code; } UsbControl::ResultCode UsbControl::setPowerStateLatencies() { int r = libusb_ext::set_sel(handle_, timeout_, 0x55, 0, 0x55, 0); - return checkLibusbResult("setPowerStateLatencies", r); + UsbControl::ResultCode code; + CHECK_LIBUSB_RESULT(code, r) << "failed to set power state latencies! " << WRITE_LIBUSB_ERROR(r); + return code; } UsbControl::ResultCode UsbControl::enablePowerStates() @@ -276,12 +270,12 @@ UsbControl::ResultCode UsbControl::enablePowerStates() int r; r = libusb_ext::set_feature(handle_, timeout_, libusb_ext::U1_ENABLE); - code = checkLibusbResult("enablePowerStates(U1)", r); + CHECK_LIBUSB_RESULT(code, r) << "failed to enable power states U1! " << WRITE_LIBUSB_ERROR(r); if(code == Success) { r = libusb_ext::set_feature(handle_, timeout_, libusb_ext::U2_ENABLE); - code = checkLibusbResult("enablePowerStates(U2)", r); + CHECK_LIBUSB_RESULT(code, r) << "failed to enable power states U2! " << WRITE_LIBUSB_ERROR(r); } return code; @@ -292,7 +286,9 @@ UsbControl::ResultCode UsbControl::setVideoTransferFunctionState(UsbControl::Sta bool suspend = state == Enabled ? false : true; int r = libusb_ext::set_feature_function_suspend(handle_, timeout_, suspend, suspend); - return checkLibusbResult("setVideoTransferFunctionState", r); + UsbControl::ResultCode code; + CHECK_LIBUSB_RESULT(code, r) << "failed to set video transfer function state! " << WRITE_LIBUSB_ERROR(r); + return code; } UsbControl::ResultCode UsbControl::setIrInterfaceState(UsbControl::State state) @@ -300,7 +296,9 @@ UsbControl::ResultCode UsbControl::setIrInterfaceState(UsbControl::State state) int alternate_setting = state == Enabled ? 1 : 0; int r = libusb_set_interface_alt_setting(handle_, IrInterfaceId, alternate_setting); - return checkLibusbResult("setIrInterfaceState", r); + UsbControl::ResultCode code; + CHECK_LIBUSB_RESULT(code, r) << "failed to set ir interface state! " << WRITE_LIBUSB_ERROR(r); + return code; } @@ -316,7 +314,9 @@ UsbControl::ResultCode UsbControl::getIrMaxIsoPacketSize(int &size) r = LIBUSB_SUCCESS; } - return checkLibusbResult("getIrMaxIsoPacketSize", r); + UsbControl::ResultCode code; + CHECK_LIBUSB_RESULT(code, r) << "failed to get max iso packet size! " << WRITE_LIBUSB_ERROR(r); + return code; } } /* namespace protocol */