diff --git a/examples/protonect/CMakeLists.txt b/examples/protonect/CMakeLists.txt index 7ef31c831..4b69b17a7 100644 --- a/examples/protonect/CMakeLists.txt +++ b/examples/protonect/CMakeLists.txt @@ -101,7 +101,7 @@ SET(SOURCES src/resource.cpp src/command_transaction.cpp src/registration.cpp - src/timer.cpp + src/logging.cpp src/libfreenect2.cpp ${LIBFREENECT2_THREADING_SOURCE} @@ -166,6 +166,13 @@ IF(ENABLE_OPENCL) LIST(APPEND RESOURCES src/opencl_depth_packet_processor.cl ) + + # Major Linux distro stable releases have buggy OpenCL ICD loader. + # The workaround of disabling exceptions can only be set up during compile time. + # Diabling it for all should be harmless. The flag is the same for GCC/Clang/ICC. + IF(UNIX AND NOT APPLE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") + ENDIF() ENDIF(OPENCL_FOUND) ENDIF(ENABLE_OPENCL) diff --git a/examples/protonect/Protonect.cpp b/examples/protonect/Protonect.cpp index a3b3df992..e69c1b529 100644 --- a/examples/protonect/Protonect.cpp +++ b/examples/protonect/Protonect.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef LIBFREENECT2_WITH_OPENGL_SUPPORT #include "viewer.h" #endif @@ -45,6 +46,29 @@ void sigint_handler(int s) protonect_shutdown = true; } +//The following demostrates how to create a custom logger +#include +#include +class MyFileLogger: public libfreenect2::Logger +{ +private: + std::ofstream logfile_; +public: + MyFileLogger(const char *filename) + : logfile_(filename) + { + level_ = Debug; + } + bool good() + { + return logfile_.good(); + } + virtual void log(Level level, const std::string &message) + { + logfile_ << "[" << libfreenect2::Logger::level2str(level) << "] " << message << std::endl; + } +}; + int main(int argc, char *argv[]) { std::string program_path(argv[0]); @@ -58,6 +82,12 @@ int main(int argc, char *argv[]) } libfreenect2::Freenect2 freenect2; + // create a console logger with debug level (default is console logger with info level) + libfreenect2::setGlobalLogger(libfreenect2::createConsoleLogger(libfreenect2::Logger::Debug)); + MyFileLogger *filelogger = new MyFileLogger(getenv("LOGFILE")); + if (filelogger->good()) + libfreenect2::setGlobalLogger(filelogger); + libfreenect2::Freenect2Device *dev = 0; libfreenect2::PacketPipeline *pipeline = 0; @@ -69,6 +99,8 @@ int main(int argc, char *argv[]) std::string serial = freenect2.getDefaultDeviceSerialNumber(); + bool viewer_enabled = true; + for(int argI = 1; argI < argc; ++argI) { const std::string arg(argv[argI]); @@ -100,6 +132,10 @@ int main(int argc, char *argv[]) { serial = arg; } + else if(arg == "-noviewer") + { + viewer_enabled = false; + } else { std::cout << "Unknown argument: " << arg << std::endl; @@ -137,9 +173,13 @@ int main(int argc, char *argv[]) libfreenect2::Registration* registration = new libfreenect2::Registration(dev->getIrCameraParams(), dev->getColorCameraParams()); + size_t framecount = 0; #ifdef LIBFREENECT2_WITH_OPENGL_SUPPORT Viewer viewer; - viewer.initialize(); + if (viewer_enabled) + viewer.initialize(); +#else + viewer_enabled = false; #endif while(!protonect_shutdown) @@ -151,15 +191,22 @@ int main(int argc, char *argv[]) registration->apply(rgb, depth, &undistorted, ®istered); + framecount++; + if (!viewer_enabled) + { + if (framecount % 100 == 0) + std::cout << "The viewer is turned off. Received " << framecount << " frames. Ctrl-C to stop." << std::endl; + listener.release(frames); + continue; + } + #ifdef LIBFREENECT2_WITH_OPENGL_SUPPORT viewer.addFrame("RGB", rgb); viewer.addFrame("ir", ir); viewer.addFrame("depth", depth); viewer.addFrame("registered", ®istered); - protonect_shutdown = viewer.render(); -#else - protonect_shutdown = true; + protonect_shutdown = protonect_shutdown || viewer.render(); #endif listener.release(frames); diff --git a/examples/protonect/include/libfreenect2/timer.h b/examples/protonect/include/libfreenect2/logger.h similarity index 60% rename from examples/protonect/include/libfreenect2/timer.h rename to examples/protonect/include/libfreenect2/logger.h index 00ce33d6f..10af9c8d3 100644 --- a/examples/protonect/include/libfreenect2/timer.h +++ b/examples/protonect/include/libfreenect2/logger.h @@ -24,28 +24,46 @@ * either License. */ -#ifndef TIMER_H_ -#define TIMER_H_ +#ifndef LIBFREENECT2_LOGGER_H_ +#define LIBFREENECT2_LOGGER_H_ + +#include +#include #include namespace libfreenect2 { -class TimerImpl; +class LIBFREENECT2_API Logger +{ +public: + enum Level + { + None = 0, + Error = 1, + Warning = 2, + Info = 3, + Debug = 4, + }; + static Level getDefaultLevel(); + static std::string level2str(Level level); -class Timer { - public: - Timer(); - virtual ~Timer(); + virtual ~Logger(); - void start(); - double stop(); + virtual Level level() const; - private: - TimerImpl *impl_; + virtual void log(Level level, const std::string &message) = 0; +protected: + Level level_; }; -} /* namespace libfreenect2 */ +LIBFREENECT2_API Logger *createConsoleLogger(Logger::Level level); +LIBFREENECT2_API Logger *createConsoleLoggerWithDefaultLevel(); -#endif /* TIMER_H_ */ +//libfreenect2 frees the memory of the logger passed in. +LIBFREENECT2_API Logger *getGlobalLogger(); +LIBFREENECT2_API void setGlobalLogger(Logger *logger); + +} /* namespace libfreenect2 */ +#endif /* LIBFREENECT2_LOGGER_H_ */ diff --git a/examples/protonect/include/libfreenect2/logging.h b/examples/protonect/include/libfreenect2/logging.h new file mode 100644 index 000000000..fe362b772 --- /dev/null +++ b/examples/protonect/include/libfreenect2/logging.h @@ -0,0 +1,83 @@ +/* + * 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 +#include + +namespace libfreenect2 +{ + +class WithPerfLoggingImpl; + +class WithPerfLogging +{ +public: + WithPerfLogging(); + virtual ~WithPerfLogging(); + void startTiming(); + std::ostream &stopTiming(std::ostream &stream); +private: + WithPerfLoggingImpl *impl_; +}; + +class LogMessage +{ +private: + Logger *logger_; + Logger::Level level_; + std::ostringstream stream_; +public: + LogMessage(Logger *logger, Logger::Level level); + ~LogMessage(); + + std::ostream &stream(); +}; + +std::string getShortName(const char *func); + +} /* namespace libfreenect2 */ + +#if defined(__GNUC__) or defined(__clang__) +#define LOG_SOURCE ::libfreenect2::getShortName(__PRETTY_FUNCTION__) +#elif defined(_MSC_VER) +#define LOG_SOURCE ::libfreenect2::getShortName(__FUNCSIG__) +#else +#define LOG_SOURCE "" +#endif + +#define LOG(LEVEL) (::libfreenect2::LogMessage(::libfreenect2::getGlobalLogger(), ::libfreenect2::Logger::LEVEL).stream() << "[" << LOG_SOURCE << "] ") +#define LOG_DEBUG LOG(Debug) +#define LOG_INFO LOG(Info) +#define LOG_WARNING LOG(Warning) +#define LOG_ERROR LOG(Error) + +#endif /* LOGGING_H_ */ diff --git a/examples/protonect/include/libfreenect2/packet_processor.h b/examples/protonect/include/libfreenect2/packet_processor.h index 9d151cf2c..ea21b9d8a 100644 --- a/examples/protonect/include/libfreenect2/packet_processor.h +++ b/examples/protonect/include/libfreenect2/packet_processor.h @@ -27,8 +27,6 @@ #ifndef PACKET_PROCESSOR_H_ #define PACKET_PROCESSOR_H_ -#include - namespace libfreenect2 { diff --git a/examples/protonect/src/command_transaction.cpp b/examples/protonect/src/command_transaction.cpp index b1b6efe84..716dd32e2 100644 --- a/examples/protonect/src/command_transaction.cpp +++ b/examples/protonect/src/command_transaction.cpp @@ -25,9 +25,9 @@ */ #include +#include #include -#include namespace libfreenect2 { @@ -106,7 +106,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 +119,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 +135,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 +157,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 +176,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/cpu_depth_packet_processor.cpp b/examples/protonect/src/cpu_depth_packet_processor.cpp index f0517f7bf..56e55cc9a 100644 --- a/examples/protonect/src/cpu_depth_packet_processor.cpp +++ b/examples/protonect/src/cpu_depth_packet_processor.cpp @@ -27,8 +27,8 @@ #include #include #include +#include -#include #include #include @@ -202,7 +202,7 @@ inline int bfi(int width, int offset, int src2, int src3) return ((src2 << offset) & bitmask) | (src3 & ~bitmask); } -class CpuDepthPacketProcessorImpl +class CpuDepthPacketProcessorImpl: public WithPerfLogging { public: Mat p0_table0, p0_table1, p0_table2; @@ -214,11 +214,6 @@ class CpuDepthPacketProcessorImpl float trig_table1[512*424][6]; float trig_table2[512*424][6]; - double timing_acc; - double timing_acc_n; - - Timer timer; - bool enable_bilateral_filter, enable_edge_filter; DepthPacketProcessor::Parameters params; @@ -231,34 +226,12 @@ class CpuDepthPacketProcessorImpl newIrFrame(); newDepthFrame(); - timing_acc = 0.0; - timing_acc_n = 0.0; - enable_bilateral_filter = true; enable_edge_filter = true; flip_ptables = true; } - void startTiming() - { - timer.start(); - } - - void stopTiming() - { - timing_acc += timer.stop(); - timing_acc_n += 1.0; - - if(timing_acc_n >= 100.0) - { - double avg = (timing_acc / timing_acc_n); - std::cout << "[CpuDepthPacketProcessor] avg. time: " << (avg * 1000) << "ms -> ~" << (1.0/avg) << "Hz" << std::endl; - timing_acc = 0.0; - timing_acc_n = 0.0; - } - } - void newIrFrame() { ir_frame = new Frame(512, 424, 4); @@ -774,7 +747,7 @@ void CpuDepthPacketProcessor::loadP0TablesFromCommandResponse(unsigned char* buf if(buffer_length < sizeof(libfreenect2::protocol::P0TablesResponse)) { - std::cerr << "[CpuDepthPacketProcessor::loadP0TablesFromCommandResponse] P0Table response too short!" << std::endl; + LOG_ERROR << "P0Table response too short!"; return; } @@ -801,19 +774,19 @@ void CpuDepthPacketProcessor::loadP0TablesFromFiles(const char* p0_filename, con Mat p0_table0(424, 512); if(!loadBufferFromFile2(p0_filename, p0_table0.buffer(), p0_table0.sizeInBytes())) { - std::cerr << "[CpuDepthPacketProcessor::loadP0TablesFromFiles] Loading p0table 0 from '" << p0_filename << "' failed!" << std::endl; + LOG_ERROR << "Loading p0table 0 from '" << p0_filename << "' failed!"; } Mat p0_table1(424, 512); if(!loadBufferFromFile2(p1_filename, p0_table1.buffer(), p0_table1.sizeInBytes())) { - std::cerr << "[CpuDepthPacketProcessor::loadP0TablesFromFiles] Loading p0table 1 from '" << p1_filename << "' failed!" << std::endl; + LOG_ERROR << "Loading p0table 1 from '" << p1_filename << "' failed!"; } Mat p0_table2(424, 512); if(!loadBufferFromFile2(p2_filename, p0_table2.buffer(), p0_table2.sizeInBytes())) { - std::cerr << "[CpuDepthPacketProcessor::loadP0TablesFromFiles] Loading p0table 2 from '" << p2_filename << "' failed!" << std::endl; + LOG_ERROR << "Loading p0table 2 from '" << p2_filename << "' failed!"; } if(impl_->flip_ptables) @@ -846,7 +819,7 @@ void CpuDepthPacketProcessor::loadXTableFromFile(const char* filename) } else { - std::cerr << "[CpuDepthPacketProcessor::loadXTableFromFile] Loading xtable from resource 'xTable.bin' failed!" << std::endl; + LOG_ERROR << "Loading xtable from resource 'xTable.bin' failed!"; } } @@ -863,7 +836,7 @@ void CpuDepthPacketProcessor::loadZTableFromFile(const char* filename) } else { - std::cerr << "[CpuDepthPacketProcessor::loadZTableFromFile] Loading ztable from resource 'zTable.bin' failed!" << std::endl; + LOG_ERROR << "Loading ztable from resource 'zTable.bin' failed!"; } } @@ -878,7 +851,7 @@ void CpuDepthPacketProcessor::load11To16LutFromFile(const char* filename) } else { - std::cerr << "[CpuDepthPacketProcessor::load11To16LutFromFile] Loading 11to16 lut from resource '11to16.bin' failed!" << std::endl; + LOG_ERROR << "Loading 11to16 lut from resource '11to16.bin' failed!"; } } @@ -975,7 +948,7 @@ void CpuDepthPacketProcessor::process(const DepthPacket &packet) impl_->newDepthFrame(); } - impl_->stopTiming(); + impl_->stopTiming(LOG_INFO); } } /* namespace libfreenect2 */ diff --git a/examples/protonect/src/depth_packet_stream_parser.cpp b/examples/protonect/src/depth_packet_stream_parser.cpp index 3a03c44ea..a90f1ed70 100644 --- a/examples/protonect/src/depth_packet_stream_parser.cpp +++ b/examples/protonect/src/depth_packet_stream_parser.cpp @@ -25,7 +25,7 @@ */ #include -#include +#include #include namespace libfreenect2 @@ -79,7 +79,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 +91,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 +113,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 +132,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..88d52b225 100644 --- a/examples/protonect/src/libfreenect2.cpp +++ b/examples/protonect/src/libfreenect2.cpp @@ -24,7 +24,7 @@ * either License. */ -#include +#include #include #include #include @@ -38,6 +38,7 @@ #include #include #include +#include namespace libfreenect2 { @@ -140,7 +141,7 @@ class Freenect2Impl // TODO: error handling if(r != 0) { - std::cout << "[Freenect2Impl] failed to create usb context!" << std::endl; + LOG_ERROR << "failed to create usb context!"; } } @@ -159,6 +160,7 @@ class Freenect2Impl libusb_exit(usb_context_); usb_context_ = 0; } + } void addDevice(Freenect2DeviceImpl *device) @@ -176,7 +178,7 @@ class Freenect2Impl } 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 +207,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 +225,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 +270,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 +295,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() @@ -397,7 +399,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 +419,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 +428,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 +446,15 @@ 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"; + LOG_DEBUG << 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 +508,16 @@ 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"; + LOG_DEBUG << 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"; + LOG_DEBUG << GenericResponse(result.data, result.length).toString(); command_tx_.execute(SetStreamEnabledCommand(nextCommandSeq()), result); @@ -536,33 +538,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 +577,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 +603,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() @@ -677,8 +679,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 +690,10 @@ 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 +701,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 +731,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 +740,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 +755,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..20dff7476 --- /dev/null +++ b/examples/protonect/src/logging.cpp @@ -0,0 +1,269 @@ +/* + * 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 + +#ifdef LIBFREENECT2_WITH_CXX11_SUPPORT +#include +#endif + +#ifdef LIBFREENECT2_WITH_OPENGL_SUPPORT +#include +#endif + +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; + else if(env_logger_level_str == "none") + l = Logger::None; + } + + return l; +} + +Logger::Level Logger::level() const +{ + return level_; +} + +std::string Logger::level2str(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; + //std::ios_base::unitbuf causes automatic flushing which access + //thread local variable via std::uncaught_exception(). + //This causes deadlock with ocl-icd until its recent update. + //Accessing TLS has a slight performance penalty. + //log() always flush the ostream so unitbuf is unnecessary anyway. + std::nounitbuf(std::cerr); + } + 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; + } +}; + +Logger *createConsoleLogger(Logger::Level level) +{ + return new ConsoleLogger(level); +} + +Logger *createConsoleLoggerWithDefaultLevel() +{ + return new ConsoleLogger(Logger::getDefaultLevel()); +} + +LogMessage::LogMessage(Logger *logger, Logger::Level level) : logger_(logger), level_(level) +{ + +} + +LogMessage::~LogMessage() +{ + if(logger_ != 0 && stream_.good()) + { + const std::string &message = stream_.str(); + if (message.size()) + logger_->log(level_, message); + } +} + +std::ostream &LogMessage::stream() +{ + return stream_; +} + +static ConsoleLogger defaultLogger_(Logger::getDefaultLevel()); +static Logger *userLogger_ = &defaultLogger_; + +Logger *getGlobalLogger() +{ + return userLogger_; +} + +void setGlobalLogger(Logger *logger) +{ + if (userLogger_ != &defaultLogger_) + delete userLogger_; + userLogger_ = logger; +} + +class Timer +{ + public: + double duration; + size_t count; + + Timer() + { + reset(); + } + + void reset() + { + duration = 0; + count = 0; + } + +#ifdef LIBFREENECT2_WITH_CXX11_SUPPORT + std::chrono::time_point time_start; + + void start() + { + time_start = std::chrono::high_resolution_clock::now(); + } + + void stop() + { + duration += std::chrono::duration_cast>(std::chrono::high_resolution_clock::now() - time_start).count(); + count++; + } +#elif defined(LIBFREENECT2_WITH_OPENGL_SUPPORT) + double time_start; + + void start() + { + time_start = glfwGetTime(); + } + + void stop() + { + duration += glfwGetTime() - time_start; + count++; + } +#else + void start() + { + } + + void stop() + { + } +#endif +}; + +class WithPerfLoggingImpl: public Timer +{ +public: + std::ostream &stop(std::ostream &stream) + { + Timer::stop(); + if (count < 100) + { + stream.setstate(std::ios::eofbit); + return stream; + } + double avg = duration / count; + reset(); + stream << "avg. time: " << (avg * 1000) << "ms -> ~" << (1.0/avg) << "Hz"; + return stream; + } +}; + +WithPerfLogging::WithPerfLogging() + :impl_(new WithPerfLoggingImpl) +{ +} + +WithPerfLogging::~WithPerfLogging() +{ + delete impl_; +} + +void WithPerfLogging::startTiming() +{ + impl_->start(); +} + +std::ostream &WithPerfLogging::stopTiming(std::ostream &stream) +{ + impl_->stop(stream); +} + +std::string getShortName(const char *func) +{ + std::string src(func); + size_t end = src.rfind('('); + if (end == std::string::npos) + end = src.size(); + size_t begin = 1 + src.rfind(' ', end); + size_t first_ns = src.find("::", begin); + if (first_ns != std::string::npos) + begin = first_ns + 2; + size_t last_ns = src.rfind("::", end); + if (last_ns != std::string::npos) + end = last_ns; + return src.substr(begin, end - begin); +} + +} /* namespace libfreenect2 */ diff --git a/examples/protonect/src/opencl_depth_packet_processor.cpp b/examples/protonect/src/opencl_depth_packet_processor.cpp index 822bfb06f..91a8e7ad5 100644 --- a/examples/protonect/src/opencl_depth_packet_processor.cpp +++ b/examples/protonect/src/opencl_depth_packet_processor.cpp @@ -27,15 +27,13 @@ #include #include #include +#include -#include -#include #include #define _USE_MATH_DEFINES #include -#define __CL_ENABLE_EXCEPTIONS #ifdef __APPLE__ #include #else @@ -49,8 +47,6 @@ #define REG_OPENCL_FILE "" #endif -#define OUT_NAME(FUNCTION) "[OpenCLDepthPacketProcessor::" FUNCTION "] " - namespace libfreenect2 { @@ -61,14 +57,14 @@ std::string loadCLSource(const std::string &filename) if(!loadResource(filename, &data, &length)) { - std::cerr << OUT_NAME("loadCLSource") "failed to load cl source!" << std::endl; + LOG_ERROR << "failed to load cl source!"; return ""; } return std::string(reinterpret_cast(data), length); } -class OpenCLDepthPacketProcessorImpl +class OpenCLDepthPacketProcessorImpl: public WithPerfLogging { public: cl_short lut11to16[2048]; @@ -78,11 +74,6 @@ class OpenCLDepthPacketProcessorImpl libfreenect2::DepthPacketProcessor::Config config; DepthPacketProcessor::Parameters params; - double timing_acc; - double timing_acc_n; - - Timer timer; - Frame *ir_frame, *depth_frame; cl::Context context; @@ -147,11 +138,22 @@ class OpenCLDepthPacketProcessorImpl newIrFrame(); newDepthFrame(); - timing_acc = 0.0; - timing_acc_n = 0.0; image_size = 512 * 424; deviceInitialized = initDevice(deviceId); + + const int CL_ICDL_VERSION = 2; + typedef cl_int (*icdloader_func)(int, size_t, void*, size_t*); + icdloader_func clGetICDLoaderInfoOCLICD = (icdloader_func)clGetExtensionFunctionAddress("clGetICDLoaderInfoOCLICD"); + if (clGetICDLoaderInfoOCLICD != NULL) + { + char buf[16]; + if (clGetICDLoaderInfoOCLICD(CL_ICDL_VERSION, sizeof(buf), buf, NULL) == CL_SUCCESS) + { + if (strcmp(buf, "2.2.4") < 0) + LOG_WARNING << "Your ocl-icd has deadlock bugs. Update to 2.2.4+ is recommended."; + } + } } void generateOptions(std::string &options) const @@ -224,37 +226,41 @@ class OpenCLDepthPacketProcessorImpl } } - void listDevice(std::vector &devices) + std::string deviceString(cl::Device &dev) { - std::cout << OUT_NAME("listDevice") " devices:" << std::endl; - for(size_t i = 0; i < devices.size(); ++i) + std::string devName, devVendor, devType; + cl_device_type devTypeID; + dev.getInfo(CL_DEVICE_NAME, &devName); + dev.getInfo(CL_DEVICE_VENDOR, &devVendor); + dev.getInfo(CL_DEVICE_TYPE, &devTypeID); + + switch(devTypeID) { - cl::Device &dev = devices[i]; - std::string devName, devVendor, devType; - cl_device_type devTypeID; - dev.getInfo(CL_DEVICE_NAME, &devName); - dev.getInfo(CL_DEVICE_VENDOR, &devVendor); - dev.getInfo(CL_DEVICE_TYPE, &devTypeID); + case CL_DEVICE_TYPE_CPU: + devType = "CPU"; + break; + case CL_DEVICE_TYPE_GPU: + devType = "GPU"; + break; + case CL_DEVICE_TYPE_ACCELERATOR: + devType = "ACCELERATOR"; + break; + case CL_DEVICE_TYPE_CUSTOM: + devType = "CUSTOM"; + break; + default: + devType = "UNKNOWN"; + } - switch(devTypeID) - { - case CL_DEVICE_TYPE_CPU: - devType = "CPU"; - break; - case CL_DEVICE_TYPE_GPU: - devType = "GPU"; - break; - case CL_DEVICE_TYPE_ACCELERATOR: - devType = "ACCELERATOR"; - break; - case CL_DEVICE_TYPE_CUSTOM: - devType = "CUSTOM"; - break; - default: - devType = "UNKNOWN"; - } + return devName + " (" + devType + ")[" + devVendor + ']'; + } - std::cout << " " << i << ": " << devName << " (" << devType << ")[" << devVendor << ']' << std::endl; + void listDevice(std::vector &devices) + { + LOG_INFO << " devices:"; + for(size_t i = 0; i < devices.size(); ++i) + { + LOG_INFO << " " << i << ": " << deviceString(devices[i]); } } @@ -272,7 +278,7 @@ class OpenCLDepthPacketProcessorImpl for(size_t i = 0; i < devices.size(); ++i) { cl::Device &dev = devices[i]; - cl_device_type devTypeID; + cl_device_type devTypeID = 0; dev.getInfo(CL_DEVICE_TYPE, &devTypeID); if(!selected || (selectedType != CL_DEVICE_TYPE_GPU && devTypeID == CL_DEVICE_TYPE_GPU)) @@ -285,6 +291,8 @@ class OpenCLDepthPacketProcessorImpl return selected; } +#define CHECK_CL_ERROR(err, str) do {if (err != CL_SUCCESS) {LOG_ERROR << str << " failed: " << err; return false; } } while(0) + bool initDevice(const int deviceId) { if(!readProgram(sourceCode)) @@ -293,62 +301,29 @@ class OpenCLDepthPacketProcessorImpl } cl_int err = CL_SUCCESS; - try { std::vector platforms; - if(cl::Platform::get(&platforms) != CL_SUCCESS) - { - std::cerr << OUT_NAME("init") "error while getting opencl platforms." << std::endl; - return false; - } + err = cl::Platform::get(&platforms); + CHECK_CL_ERROR(err, "cl::Platform::get"); + if(platforms.empty()) { - std::cerr << OUT_NAME("init") "no opencl platforms found." << std::endl; + LOG_ERROR << "no opencl platforms found."; return false; } std::vector devices; getDevices(platforms, devices); listDevice(devices); - if(selectDevice(devices, deviceId)) + if(!selectDevice(devices, deviceId)) { - std::string devName, devVendor, devType; - cl_device_type devTypeID; - device.getInfo(CL_DEVICE_NAME, &devName); - device.getInfo(CL_DEVICE_VENDOR, &devVendor); - device.getInfo(CL_DEVICE_TYPE, &devTypeID); - - switch(devTypeID) - { - case CL_DEVICE_TYPE_CPU: - devType = "CPU"; - break; - case CL_DEVICE_TYPE_GPU: - devType = "GPU"; - break; - case CL_DEVICE_TYPE_ACCELERATOR: - devType = "ACCELERATOR"; - break; - case CL_DEVICE_TYPE_CUSTOM: - devType = "CUSTOM"; - break; - default: - devType = "UNKNOWN"; - } - std::cout << OUT_NAME("init") " selected device: " << devName << " (" << devType << ")[" << devVendor << ']' << std::endl; - } - else - { - std::cerr << OUT_NAME("init") "could not find any suitable device" << std::endl; + LOG_ERROR << "could not find any suitable device"; return false; } + LOG_INFO << "selected device: " << deviceString(device); - context = cl::Context(device); - } - catch(const cl::Error &err) - { - std::cerr << OUT_NAME("init") "ERROR: " << err.what() << "(" << err.err() << ")" << std::endl; - throw; + context = cl::Context(device, NULL, NULL, NULL, &err); + CHECK_CL_ERROR(err, "cl::Context"); } return buildProgram(sourceCode); @@ -366,9 +341,9 @@ class OpenCLDepthPacketProcessorImpl return false; cl_int err = CL_SUCCESS; - try { queue = cl::CommandQueue(context, device, 0, &err); + CHECK_CL_ERROR(err, "cl::CommandQueue"); //Read only buf_lut11to16_size = 2048 * sizeof(cl_short); @@ -378,10 +353,15 @@ class OpenCLDepthPacketProcessorImpl buf_packet_size = ((image_size * 11) / 16) * 10 * sizeof(cl_ushort); buf_lut11to16 = cl::Buffer(context, CL_READ_ONLY_CACHE, buf_lut11to16_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_p0_table = cl::Buffer(context, CL_READ_ONLY_CACHE, buf_p0_table_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_x_table = cl::Buffer(context, CL_READ_ONLY_CACHE, buf_x_table_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_z_table = cl::Buffer(context, CL_READ_ONLY_CACHE, buf_z_table_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_packet = cl::Buffer(context, CL_READ_ONLY_CACHE, buf_packet_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); //Read-Write buf_a_size = image_size * sizeof(cl_float3); @@ -396,109 +376,156 @@ class OpenCLDepthPacketProcessorImpl buf_filtered_size = image_size * sizeof(cl_float); buf_a = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_a_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_b = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_b_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_n = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_n_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_ir = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_ir_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_a_filtered = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_a_filtered_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_b_filtered = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_b_filtered_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_edge_test = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_edge_test_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_depth = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_depth_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_ir_sum = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_ir_sum_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); buf_filtered = cl::Buffer(context, CL_READ_WRITE_CACHE, buf_filtered_size, NULL, &err); + CHECK_CL_ERROR(err, "cl::Buffer"); kernel_processPixelStage1 = cl::Kernel(program, "processPixelStage1", &err); - kernel_processPixelStage1.setArg(0, buf_lut11to16); - kernel_processPixelStage1.setArg(1, buf_z_table); - kernel_processPixelStage1.setArg(2, buf_p0_table); - kernel_processPixelStage1.setArg(3, buf_packet); - kernel_processPixelStage1.setArg(4, buf_a); - kernel_processPixelStage1.setArg(5, buf_b); - kernel_processPixelStage1.setArg(6, buf_n); - kernel_processPixelStage1.setArg(7, buf_ir); + CHECK_CL_ERROR(err, "cl::Kernel"); + err = kernel_processPixelStage1.setArg(0, buf_lut11to16); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage1.setArg(1, buf_z_table); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage1.setArg(2, buf_p0_table); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage1.setArg(3, buf_packet); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage1.setArg(4, buf_a); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage1.setArg(5, buf_b); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage1.setArg(6, buf_n); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage1.setArg(7, buf_ir); + CHECK_CL_ERROR(err, "setArg"); kernel_filterPixelStage1 = cl::Kernel(program, "filterPixelStage1", &err); - kernel_filterPixelStage1.setArg(0, buf_a); - kernel_filterPixelStage1.setArg(1, buf_b); - kernel_filterPixelStage1.setArg(2, buf_n); - kernel_filterPixelStage1.setArg(3, buf_a_filtered); - kernel_filterPixelStage1.setArg(4, buf_b_filtered); - kernel_filterPixelStage1.setArg(5, buf_edge_test); + CHECK_CL_ERROR(err, "cl::Kernel"); + err = kernel_filterPixelStage1.setArg(0, buf_a); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_filterPixelStage1.setArg(1, buf_b); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_filterPixelStage1.setArg(2, buf_n); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_filterPixelStage1.setArg(3, buf_a_filtered); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_filterPixelStage1.setArg(4, buf_b_filtered); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_filterPixelStage1.setArg(5, buf_edge_test); + CHECK_CL_ERROR(err, "setArg"); kernel_processPixelStage2 = cl::Kernel(program, "processPixelStage2", &err); - kernel_processPixelStage2.setArg(0, config.EnableBilateralFilter ? buf_a_filtered : buf_a); - kernel_processPixelStage2.setArg(1, config.EnableBilateralFilter ? buf_b_filtered : buf_b); - kernel_processPixelStage2.setArg(2, buf_x_table); - kernel_processPixelStage2.setArg(3, buf_z_table); - kernel_processPixelStage2.setArg(4, buf_depth); - kernel_processPixelStage2.setArg(5, buf_ir_sum); + CHECK_CL_ERROR(err, "cl::Kernel"); + err = kernel_processPixelStage2.setArg(0, config.EnableBilateralFilter ? buf_a_filtered : buf_a); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage2.setArg(1, config.EnableBilateralFilter ? buf_b_filtered : buf_b); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage2.setArg(2, buf_x_table); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage2.setArg(3, buf_z_table); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage2.setArg(4, buf_depth); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_processPixelStage2.setArg(5, buf_ir_sum); + CHECK_CL_ERROR(err, "setArg"); kernel_filterPixelStage2 = cl::Kernel(program, "filterPixelStage2", &err); - kernel_filterPixelStage2.setArg(0, buf_depth); - kernel_filterPixelStage2.setArg(1, buf_ir_sum); - kernel_filterPixelStage2.setArg(2, buf_edge_test); - kernel_filterPixelStage2.setArg(3, buf_filtered); + CHECK_CL_ERROR(err, "cl::Kernel"); + err = kernel_filterPixelStage2.setArg(0, buf_depth); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_filterPixelStage2.setArg(1, buf_ir_sum); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_filterPixelStage2.setArg(2, buf_edge_test); + CHECK_CL_ERROR(err, "setArg"); + err = kernel_filterPixelStage2.setArg(3, buf_filtered); + CHECK_CL_ERROR(err, "setArg"); cl::Event event0, event1, event2, event3; - queue.enqueueWriteBuffer(buf_lut11to16, CL_FALSE, 0, buf_lut11to16_size, lut11to16, NULL, &event0); - queue.enqueueWriteBuffer(buf_p0_table, CL_FALSE, 0, buf_p0_table_size, p0_table, NULL, &event1); - queue.enqueueWriteBuffer(buf_x_table, CL_FALSE, 0, buf_x_table_size, x_table, NULL, &event2); - queue.enqueueWriteBuffer(buf_z_table, CL_FALSE, 0, buf_z_table_size, z_table, NULL, &event3); - - event0.wait(); - event1.wait(); - event2.wait(); - event3.wait(); - } - catch(const cl::Error &err) - { - std::cerr << OUT_NAME("init") "ERROR: " << err.what() << "(" << err.err() << ")" << std::endl; - throw; + err = queue.enqueueWriteBuffer(buf_lut11to16, CL_FALSE, 0, buf_lut11to16_size, lut11to16, NULL, &event0); + CHECK_CL_ERROR(err, "enqueueWriteBuffer"); + err = queue.enqueueWriteBuffer(buf_p0_table, CL_FALSE, 0, buf_p0_table_size, p0_table, NULL, &event1); + CHECK_CL_ERROR(err, "enqueueWriteBuffer"); + err = queue.enqueueWriteBuffer(buf_x_table, CL_FALSE, 0, buf_x_table_size, x_table, NULL, &event2); + CHECK_CL_ERROR(err, "enqueueWriteBuffer"); + err = queue.enqueueWriteBuffer(buf_z_table, CL_FALSE, 0, buf_z_table_size, z_table, NULL, &event3); + CHECK_CL_ERROR(err, "enqueueWriteBuffer"); + + err = event0.wait(); + CHECK_CL_ERROR(err, "wait"); + err = event1.wait(); + CHECK_CL_ERROR(err, "wait"); + err = event2.wait(); + CHECK_CL_ERROR(err, "wait"); + err = event3.wait(); + CHECK_CL_ERROR(err, "wait"); } + programInitialized = true; return true; } - void run(const DepthPacket &packet) + bool run(const DepthPacket &packet) { - try + cl_int err; { std::vector eventWrite(1), eventPPS1(1), eventFPS1(1), eventPPS2(1), eventFPS2(1); cl::Event event0, event1; - queue.enqueueWriteBuffer(buf_packet, CL_FALSE, 0, buf_packet_size, packet.buffer, NULL, &eventWrite[0]); + err = queue.enqueueWriteBuffer(buf_packet, CL_FALSE, 0, buf_packet_size, packet.buffer, NULL, &eventWrite[0]); + CHECK_CL_ERROR(err, "enqueueWriteBuffer"); - queue.enqueueNDRangeKernel(kernel_processPixelStage1, cl::NullRange, cl::NDRange(image_size), cl::NullRange, &eventWrite, &eventPPS1[0]); - queue.enqueueReadBuffer(buf_ir, CL_FALSE, 0, buf_ir_size, ir_frame->data, &eventPPS1, &event0); + err = queue.enqueueNDRangeKernel(kernel_processPixelStage1, cl::NullRange, cl::NDRange(image_size), cl::NullRange, &eventWrite, &eventPPS1[0]); + CHECK_CL_ERROR(err, "enqueueNDRangeKernel"); + err = queue.enqueueReadBuffer(buf_ir, CL_FALSE, 0, buf_ir_size, ir_frame->data, &eventPPS1, &event0); + CHECK_CL_ERROR(err, "enqueueReadBuffer"); if(config.EnableBilateralFilter) { - queue.enqueueNDRangeKernel(kernel_filterPixelStage1, cl::NullRange, cl::NDRange(image_size), cl::NullRange, &eventPPS1, &eventFPS1[0]); + err = queue.enqueueNDRangeKernel(kernel_filterPixelStage1, cl::NullRange, cl::NDRange(image_size), cl::NullRange, &eventPPS1, &eventFPS1[0]); + CHECK_CL_ERROR(err, "enqueueNDRangeKernel"); } else { eventFPS1[0] = eventPPS1[0]; } - queue.enqueueNDRangeKernel(kernel_processPixelStage2, cl::NullRange, cl::NDRange(image_size), cl::NullRange, &eventFPS1, &eventPPS2[0]); + err = queue.enqueueNDRangeKernel(kernel_processPixelStage2, cl::NullRange, cl::NDRange(image_size), cl::NullRange, &eventFPS1, &eventPPS2[0]); + CHECK_CL_ERROR(err, "enqueueNDRangeKernel"); if(config.EnableEdgeAwareFilter) { - queue.enqueueNDRangeKernel(kernel_filterPixelStage2, cl::NullRange, cl::NDRange(image_size), cl::NullRange, &eventPPS2, &eventFPS2[0]); + err = queue.enqueueNDRangeKernel(kernel_filterPixelStage2, cl::NullRange, cl::NDRange(image_size), cl::NullRange, &eventPPS2, &eventFPS2[0]); + CHECK_CL_ERROR(err, "enqueueWriteBuffer"); } else { eventFPS2[0] = eventPPS2[0]; } - queue.enqueueReadBuffer(config.EnableEdgeAwareFilter ? buf_filtered : buf_depth, CL_FALSE, 0, buf_depth_size, depth_frame->data, &eventFPS2, &event1); - event0.wait(); - event1.wait(); - } - catch(const cl::Error &err) - { - std::cerr << OUT_NAME("run") "ERROR: " << err.what() << " (" << err.err() << ")" << std::endl; - throw; + err = queue.enqueueReadBuffer(config.EnableEdgeAwareFilter ? buf_filtered : buf_depth, CL_FALSE, 0, buf_depth_size, depth_frame->data, &eventFPS2, &event1); + CHECK_CL_ERROR(err, "enqueueReadBuffer"); + err = event0.wait(); + CHECK_CL_ERROR(err, "wait"); + err = event1.wait(); + CHECK_CL_ERROR(err, "wait"); } + return true; } bool readProgram(std::string &source) const @@ -509,55 +536,34 @@ class OpenCLDepthPacketProcessorImpl bool buildProgram(const std::string& sources) { - try + cl_int err; { - std::cout<< OUT_NAME("buildProgram") "building OpenCL program..." <(device) << std::endl; - std::cout << OUT_NAME("buildProgram") "Build Options:\t" << program.getBuildInfo(device) << std::endl; - std::cout << OUT_NAME("buildProgram") "Build Log:\t " << program.getBuildInfo(device) << std::endl; + LOG_ERROR << "failed to build program: " << err; + LOG_ERROR << "Build Status: " << program.getBuildInfo(device); + LOG_ERROR << "Build Options:\t" << program.getBuildInfo(device); + LOG_ERROR << "Build Log:\t " << program.getBuildInfo(device); + programBuilt = false; + return false; } - - programBuilt = false; - return false; } + + LOG_INFO << "OpenCL program built successfully"; programBuilt = true; return true; } - void startTiming() - { - timer.start(); - } - - void stopTiming() - { - timing_acc += timer.stop(); - timing_acc_n += 1.0; - - if(timing_acc_n >= 100.0) - { - double avg = (timing_acc / timing_acc_n); - std::cout << "[OpenCLDepthPacketProcessor] avg. time: " << (avg * 1000) << "ms -> ~" << (1.0 / avg) << "Hz" << std::endl; - timing_acc = 0.0; - timing_acc_n = 0.0; - } - } - void newIrFrame() { ir_frame = new Frame(512, 424, 4); @@ -626,7 +632,7 @@ void OpenCLDepthPacketProcessor::loadP0TablesFromCommandResponse(unsigned char * if(buffer_length < sizeof(libfreenect2::protocol::P0TablesResponse)) { - std::cerr << OUT_NAME("loadP0TablesFromCommandResponse") "P0Table response too short!" << std::endl; + LOG_ERROR << "P0Table response too short!"; return; } @@ -637,7 +643,7 @@ void OpenCLDepthPacketProcessor::loadXTableFromFile(const char *filename) { if(!loadBufferFromResources(filename, (unsigned char *)impl_->x_table, impl_->image_size * sizeof(float))) { - std::cerr << OUT_NAME("loadXTableFromFile") "could not load x table from: " << filename << std::endl; + LOG_ERROR << "could not load x table from: " << filename; } } @@ -645,7 +651,7 @@ void OpenCLDepthPacketProcessor::loadZTableFromFile(const char *filename) { if(!loadBufferFromResources(filename, (unsigned char *)impl_->z_table, impl_->image_size * sizeof(float))) { - std::cerr << OUT_NAME("loadZTableFromFile") "could not load z table from: " << filename << std::endl; + LOG_ERROR << "could not load z table from: " << filename; } } @@ -653,7 +659,7 @@ void OpenCLDepthPacketProcessor::load11To16LutFromFile(const char *filename) { if(!loadBufferFromResources(filename, (unsigned char *)impl_->lut11to16, 2048 * sizeof(cl_ushort))) { - std::cerr << OUT_NAME("load11To16LutFromFile") "could not load lut table from: " << filename << std::endl; + LOG_ERROR << "could not load lut table from: " << filename; } } @@ -663,7 +669,7 @@ void OpenCLDepthPacketProcessor::process(const DepthPacket &packet) if(!impl_->programInitialized && !impl_->initProgram()) { - std::cerr << OUT_NAME("process") "could not initialize OpenCLDepthPacketProcessor" << std::endl; + LOG_ERROR << "could not initialize OpenCLDepthPacketProcessor"; return; } @@ -674,11 +680,11 @@ void OpenCLDepthPacketProcessor::process(const DepthPacket &packet) impl_->ir_frame->sequence = packet.sequence; impl_->depth_frame->sequence = packet.sequence; - impl_->run(packet); + bool r = impl_->run(packet); - impl_->stopTiming(); + impl_->stopTiming(LOG_INFO); - if(has_listener) + if(has_listener && r) { if(this->listener_->onNewFrame(Frame::Ir, impl_->ir_frame)) { diff --git a/examples/protonect/src/opengl_depth_packet_processor.cpp b/examples/protonect/src/opengl_depth_packet_processor.cpp index e069ce8bf..e42b0f73b 100644 --- a/examples/protonect/src/opengl_depth_packet_processor.cpp +++ b/examples/protonect/src/opengl_depth_packet_processor.cpp @@ -27,10 +27,10 @@ #include #include #include +#include #include "flextGL.h" #include -#include #include @@ -55,7 +55,7 @@ ChangeCurrentOpenGLContext::ChangeCurrentOpenGLContext(GLFWwindow *new_context) ChangeCurrentOpenGLContext::~ChangeCurrentOpenGLContext() { - //std::cerr << "[ChangeCurrentOpenGLContext] restoring context!" << std::endl; + //LOG_INFO << "restoring context!"; if(last_ctx != 0) { glfwMakeContextCurrent(last_ctx); @@ -95,7 +95,7 @@ std::string loadShaderSource(const std::string& filename) if(!loadResource(filename, &data, &length)) { - std::cerr << "[loadShaderSource] failed to load shader source!" << std::endl; + LOG_ERROR << "failed to load shader source!"; return ""; } @@ -155,8 +155,7 @@ struct ShaderProgram : public WithOpenGLBindings { gl()->glGetShaderInfoLog(vertex_shader, sizeof(error_buffer), NULL, error_buffer); - std::cerr << "[ShaderProgram::build] failed to compile vertex shader!" << std::endl; - std::cerr << error_buffer << std::endl; + LOG_ERROR << "failed to compile vertex shader!" << std::endl << error_buffer; } gl()->glCompileShader(fragment_shader); @@ -166,8 +165,7 @@ struct ShaderProgram : public WithOpenGLBindings { gl()->glGetShaderInfoLog(fragment_shader, sizeof(error_buffer), NULL, error_buffer); - std::cerr << "[ShaderProgram::build] failed to compile fragment shader!" << std::endl; - std::cerr << error_buffer << std::endl; + LOG_ERROR << "failed to compile fragment shader!" << std::endl << error_buffer; } program = gl()->glCreateProgram(); @@ -181,8 +179,7 @@ struct ShaderProgram : public WithOpenGLBindings if(status != GL_TRUE) { gl()->glGetProgramInfoLog(program, sizeof(error_buffer), NULL, error_buffer); - std::cerr << "[ShaderProgram::build] failed to link shader program!" << std::endl; - std::cerr << error_buffer << std::endl; + LOG_ERROR << "failed to link shader program!" << std::endl << error_buffer; } } @@ -333,7 +330,7 @@ struct Texture : public WithOpenGLBindings } }; -struct OpenGLDepthPacketProcessorImpl : public WithOpenGLBindings +struct OpenGLDepthPacketProcessorImpl : public WithOpenGLBindings, public WithPerfLogging { GLFWwindow *opengl_context_ptr; std::string shader_folder; @@ -367,11 +364,6 @@ struct OpenGLDepthPacketProcessorImpl : public WithOpenGLBindings DepthPacketProcessor::Parameters params; bool params_need_update; - double timing_acc; - double timing_acc_n; - - Timer timer; - bool do_debug; struct Vertex @@ -390,8 +382,6 @@ struct OpenGLDepthPacketProcessorImpl : public WithOpenGLBindings stage2_framebuffer(0), filter2_framebuffer(0), params_need_update(true), - timing_acc(0), - timing_acc_n(0), do_debug(debug) { } @@ -444,25 +434,6 @@ struct OpenGLDepthPacketProcessorImpl : public WithOpenGLBindings debug.gl(b); } - void startTiming() - { - timer.start(); - } - - void stopTiming() - { - timing_acc += timer.stop(); - timing_acc_n += 1.0; - - if(timing_acc_n >= 100.0) - { - double avg = (timing_acc / timing_acc_n); - std::cout << "[OpenGLDepthPacketProcessor] avg. time: " << (avg * 1000) << "ms -> ~" << (1.0/avg) << "Hz" << std::endl; - timing_acc = 0.0; - timing_acc_n = 0.0; - } - } - void initialize() { ChangeCurrentOpenGLContext ctx(opengl_context_ptr); @@ -470,7 +441,7 @@ struct OpenGLDepthPacketProcessorImpl : public WithOpenGLBindings OpenGLBindings *b = new OpenGLBindings(); if (flextInit(opengl_context_ptr, b) == 0) { - std::cerr << "[OpenGLDepthPacketProcessor] Failed to initialize flextGL."; + LOG_ERROR << "Failed to initialize flextGL."; exit(-1); } gl(b); @@ -773,7 +744,7 @@ OpenGLDepthPacketProcessor::OpenGLDepthPacketProcessor(void *parent_opengl_conte // init glfw - if already initialized nothing happens if (glfwInit() == GL_FALSE) { - std::cerr << "[OpenGLDepthPacketProcessor] Failed to initialize GLFW."; + LOG_ERROR << "Failed to initialize GLFW."; exit(-1); } @@ -791,7 +762,7 @@ OpenGLDepthPacketProcessor::OpenGLDepthPacketProcessor(void *parent_opengl_conte if (window == NULL) { - std::cerr << "[OpenGLDepthPacketProcessor] Failed to create opengl window."; + LOG_ERROR << "Failed to create opengl window."; exit(-1); } @@ -851,7 +822,7 @@ void OpenGLDepthPacketProcessor::loadP0TablesFromFiles(const char* p0_filename, } else { - std::cerr << "[OpenGLDepthPacketProcessor::loadP0TablesFromFiles] Loading p0table 0 from '" << p0_filename << "' failed!" << std::endl; + LOG_ERROR << "Loading p0table 0 from '" << p0_filename << "' failed!"; } impl_->p0table[1].allocate(512, 424); @@ -861,7 +832,7 @@ void OpenGLDepthPacketProcessor::loadP0TablesFromFiles(const char* p0_filename, } else { - std::cerr << "[OpenGLDepthPacketProcessor::loadP0TablesFromFiles] Loading p0table 1 from '" << p1_filename << "' failed!" << std::endl; + LOG_ERROR << "Loading p0table 1 from '" << p1_filename << "' failed!"; } impl_->p0table[2].allocate(512, 424); @@ -871,7 +842,7 @@ void OpenGLDepthPacketProcessor::loadP0TablesFromFiles(const char* p0_filename, } else { - std::cerr << "[OpenGLDepthPacketProcessor::loadP0TablesFromFiles] Loading p0table 2 from '" << p2_filename << "' failed!" << std::endl; + LOG_ERROR << "Loading p0table 2 from '" << p2_filename << "' failed!"; } } @@ -890,7 +861,7 @@ void OpenGLDepthPacketProcessor::loadXTableFromFile(const char* filename) } else { - std::cerr << "[OpenGLDepthPacketProcessor::loadXTableFromFile] Loading xtable from resource 'xTable.bin' failed!" << std::endl; + LOG_ERROR << "Loading xtable from resource 'xTable.bin' failed!"; } } @@ -910,7 +881,7 @@ void OpenGLDepthPacketProcessor::loadZTableFromFile(const char* filename) } else { - std::cerr << "[OpenGLDepthPacketProcessor::loadZTableFromFile] Loading ztable from resource 'zTable.bin' failed!" << std::endl; + LOG_ERROR << "Loading ztable from resource 'zTable.bin' failed!"; } } @@ -930,7 +901,7 @@ void OpenGLDepthPacketProcessor::load11To16LutFromFile(const char* filename) } else { - std::cerr << "[OpenGLDepthPacketProcessor::load11To16LutFromFile] Loading 11to16 lut from resource '11to16.bin' failed!" << std::endl; + LOG_ERROR << "Loading 11to16 lut from resource '11to16.bin' failed!"; } } @@ -949,7 +920,7 @@ void OpenGLDepthPacketProcessor::process(const DepthPacket &packet) if(impl_->do_debug) glfwSwapBuffers(impl_->opengl_context_ptr); - impl_->stopTiming(); + impl_->stopTiming(LOG_INFO); if(has_listener) { diff --git a/examples/protonect/src/resource.cpp b/examples/protonect/src/resource.cpp index 1c3d24caf..b78d78d0d 100644 --- a/examples/protonect/src/resource.cpp +++ b/examples/protonect/src/resource.cpp @@ -25,9 +25,9 @@ */ #include +#include #include #include -#include namespace libfreenect2 { @@ -69,13 +69,13 @@ bool loadBufferFromResources(const std::string &filename, unsigned char *buffer, if(!loadResource(filename, &data, &length)) { - std::cerr << "loadBufferFromResources: failed to load resource: " << filename << std::endl; + LOG_ERROR << "failed to load resource: " << filename; return false; } if(length != n) { - std::cerr << "loadBufferFromResources: wrong size of resource: " << filename << std::endl; + LOG_ERROR << "wrong size of resource: " << filename; return false; } diff --git a/examples/protonect/src/rgb_packet_stream_parser.cpp b/examples/protonect/src/rgb_packet_stream_parser.cpp index 4eaaf49c5..199514f09 100644 --- a/examples/protonect/src/rgb_packet_stream_parser.cpp +++ b/examples/protonect/src/rgb_packet_stream_parser.cpp @@ -26,8 +26,8 @@ #include #include +#include #include -#include namespace libfreenect2 { @@ -88,7 +88,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 +105,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 +132,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 +155,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/timer.cpp b/examples/protonect/src/timer.cpp deleted file mode 100644 index f53901df9..000000000 --- a/examples/protonect/src/timer.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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 - -#ifdef LIBFREENECT2_WITH_CXX11_SUPPORT -#include -#endif - -#ifdef LIBFREENECT2_WITH_OPENGL_SUPPORT -#include -#endif - -namespace libfreenect2 { - -#ifdef LIBFREENECT2_WITH_CXX11_SUPPORT -class TimerImpl { - public: - void start() { - time_start = std::chrono::high_resolution_clock::now(); - } - - double stop() { - return std::chrono::duration_cast>(std::chrono::high_resolution_clock::now() - time_start).count(); - } - - std::chrono::time_point time_start; -}; -#elif defined(LIBFREENECT2_WITH_OPENGL_SUPPORT) -class TimerImpl { - public: - void start() { - time_start = glfwGetTime(); - } - - double stop() { - return glfwGetTime() - time_start; - } - - double time_start; -}; -#else -class TimerImpl { - public: - void start() { - } - - double stop() { - return 0; - } -}; -#endif - -Timer::Timer() : - impl_(new TimerImpl()) { -} - -Timer::~Timer() { - delete impl_; -} - -void Timer::start() { - impl_->start(); -} - -double Timer::stop() { - return impl_->stop(); -} - -} /* namespace libfreenect2 */ \ No newline at end of file diff --git a/examples/protonect/src/tinythread/tinythread.cpp b/examples/protonect/src/tinythread/tinythread.cpp index 690eceea1..60308facc 100644 --- a/examples/protonect/src/tinythread/tinythread.cpp +++ b/examples/protonect/src/tinythread/tinythread.cpp @@ -163,17 +163,8 @@ void * thread::wrapper_function(void * aArg) // Get thread startup information _thread_start_info * ti = (_thread_start_info *) aArg; - try - { // Call the actual client thread function ti->mFunction(ti->mArg); - } - catch(...) - { - // Uncaught exceptions will terminate the application (default behavior - // according to C++11) - std::terminate(); - } // The thread is no longer executing lock_guard guard(ti->mThread->mDataMutex); diff --git a/examples/protonect/src/transfer_pool.cpp b/examples/protonect/src/transfer_pool.cpp index b324659a4..dfe70921e 100644 --- a/examples/protonect/src/transfer_pool.cpp +++ b/examples/protonect/src/transfer_pool.cpp @@ -25,7 +25,7 @@ */ #include -#include +#include namespace libfreenect2 { @@ -77,13 +77,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 +95,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 +109,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 +121,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 +186,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/turbo_jpeg_rgb_packet_processor.cpp b/examples/protonect/src/turbo_jpeg_rgb_packet_processor.cpp index b35037533..c5c0a77cb 100644 --- a/examples/protonect/src/turbo_jpeg_rgb_packet_processor.cpp +++ b/examples/protonect/src/turbo_jpeg_rgb_packet_processor.cpp @@ -25,13 +25,13 @@ */ #include +#include #include -#include namespace libfreenect2 { -class TurboJpegRgbPacketProcessorImpl +class TurboJpegRgbPacketProcessorImpl: public WithPerfLogging { public: @@ -39,23 +39,15 @@ class TurboJpegRgbPacketProcessorImpl Frame *frame; - double timing_acc; - double timing_acc_n; - - Timer timer; - TurboJpegRgbPacketProcessorImpl() { decompressor = tjInitDecompress(); if(decompressor == 0) { - std::cerr << "[TurboJpegRgbPacketProcessorImpl] Failed to initialize TurboJPEG decompressor! TurboJPEG error: '" << tjGetErrorStr() << "'" << std::endl; + LOG_ERROR << "Failed to initialize TurboJPEG decompressor! TurboJPEG error: '" << tjGetErrorStr() << "'"; } newFrame(); - - timing_acc = 0.0; - timing_acc_n = 0.0; } ~TurboJpegRgbPacketProcessorImpl() @@ -64,7 +56,7 @@ class TurboJpegRgbPacketProcessorImpl { if(tjDestroy(decompressor) == -1) { - std::cerr << "[~TurboJpegRgbPacketProcessorImpl] Failed to destroy TurboJPEG decompressor! TurboJPEG error: '" << tjGetErrorStr() << "'" << std::endl; + LOG_ERROR << "Failed to destroy TurboJPEG decompressor! TurboJPEG error: '" << tjGetErrorStr() << "'"; } } } @@ -73,25 +65,6 @@ class TurboJpegRgbPacketProcessorImpl { frame = new Frame(1920, 1080, tjPixelSize[TJPF_BGRX]); } - - void startTiming() - { - timer.start(); - } - - void stopTiming() - { - timing_acc += timer.stop(); - timing_acc_n += 1.0; - - if(timing_acc_n >= 100.0) - { - double avg = (timing_acc / timing_acc_n); - std::cout << "[TurboJpegRgbPacketProcessor] avg. time: " << (avg * 1000) << "ms -> ~" << (1.0/avg) << "Hz" << std::endl; - timing_acc = 0.0; - timing_acc_n = 0.0; - } - } }; TurboJpegRgbPacketProcessor::TurboJpegRgbPacketProcessor() : @@ -124,10 +97,10 @@ void TurboJpegRgbPacketProcessor::process(const RgbPacket &packet) } else { - std::cerr << "[TurboJpegRgbPacketProcessor::doProcess] Failed to decompress rgb image! TurboJPEG error: '" << tjGetErrorStr() << "'" << std::endl; + LOG_ERROR << "Failed to decompress rgb image! TurboJPEG error: '" << tjGetErrorStr() << "'"; } - impl_->stopTiming(); + impl_->stopTiming(LOG_INFO); } } diff --git a/examples/protonect/src/usb_control.cpp b/examples/protonect/src/usb_control.cpp index 360b96b09..00e3e5da6 100644 --- a/examples/protonect/src/usb_control.cpp +++ b/examples/protonect/src/usb_control.cpp @@ -25,9 +25,9 @@ */ #include +#include #include -#include namespace libfreenect2 { @@ -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 */ diff --git a/examples/protonect/viewer.cpp b/examples/protonect/viewer.cpp index 5e41e668d..71801f702 100644 --- a/examples/protonect/viewer.cpp +++ b/examples/protonect/viewer.cpp @@ -5,6 +5,10 @@ Viewer::Viewer() : shader_folder("src/shader/") // init glfw - if already initialized nothing happens int init = glfwInit(); +} + +void Viewer::initialize() +{ // setup context glfwDefaultWindowHints(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); @@ -16,10 +20,6 @@ Viewer::Viewer() : shader_folder("src/shader/") //glfwWindowHint(GLFW_VISIBLE, debug ? GL_TRUE : GL_FALSE); window = glfwCreateWindow(1280, 800, "Viewer", 0, NULL); -} - -void Viewer::initialize() -{ glfwMakeContextCurrent(window); OpenGLBindings *b = new OpenGLBindings(); flextInit(window, b); @@ -190,4 +190,4 @@ bool Viewer::render() void Viewer::addFrame(std::string id, libfreenect2::Frame* frame) { frames[id] = frame; -} \ No newline at end of file +} diff --git a/examples/protonect/viewer.h b/examples/protonect/viewer.h index 306ee6a36..e85e4cc6f 100644 --- a/examples/protonect/viewer.h +++ b/examples/protonect/viewer.h @@ -1,10 +1,9 @@ #ifndef VIEWER_H #define VIEWER_H -#include - #include #include +#include #include #include @@ -190,8 +189,7 @@ struct ShaderProgram : public WithOpenGLBindings { gl()->glGetShaderInfoLog(vertex_shader, sizeof(error_buffer), NULL, error_buffer); - std::cerr << "[ShaderProgram::build] failed to compile vertex shader!" << std::endl; - std::cerr << error_buffer << std::endl; + LOG_ERROR << "failed to compile vertex shader!" << std::endl << error_buffer; } gl()->glCompileShader(fragment_shader); @@ -201,8 +199,7 @@ struct ShaderProgram : public WithOpenGLBindings { gl()->glGetShaderInfoLog(fragment_shader, sizeof(error_buffer), NULL, error_buffer); - std::cerr << "[ShaderProgram::build] failed to compile fragment shader!" << std::endl; - std::cerr << error_buffer << std::endl; + LOG_ERROR << "failed to compile fragment shader!" << std::endl << error_buffer; } program = gl()->glCreateProgram(); @@ -216,8 +213,7 @@ struct ShaderProgram : public WithOpenGLBindings if (status != GL_TRUE) { gl()->glGetProgramInfoLog(program, sizeof(error_buffer), NULL, error_buffer); - std::cerr << "[ShaderProgram::build] failed to link shader program!" << std::endl; - std::cerr << error_buffer << std::endl; + LOG_ERROR << "failed to link shader program!" << std::endl << error_buffer; } } @@ -285,4 +281,4 @@ class Viewer : WithOpenGLBindings { static void key_callbackstatic(GLFWwindow* window, int key, int scancode, int action, int mods); }; -#endif \ No newline at end of file +#endif