Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 75 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ OPTION(BUILD_OPENNI2_DRIVER "Build OpenNI2 driver" ON)
OPTION(ENABLE_CXX11 "Enable C++11 support" OFF)
OPTION(ENABLE_OPENCL "Enable OpenCL support" ON)
OPTION(ENABLE_OPENGL "Enable OpenGL support" ON)
OPTION(ENABLE_VAAPI "Enable VA-API support" ON)

IF(MSVC)
# suppress several "possible loss of data" warnings, and
Expand All @@ -44,16 +45,20 @@ ELSE()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
ENDIF()

SET(HAVE_CXX11 disabled)
IF(ENABLE_CXX11)
INCLUDE(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
IF(COMPILER_SUPPORTS_CXX11)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
SET(LIBFREENECT2_WITH_CXX11_SUPPORT 1)
SET(HAVE_CXX11 yes)
ELSEIF(COMPILER_SUPPORTS_CXX0X)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
SET(HAVE_CXX11 c++0x)
ELSE()
SET(HAVE_CXX11 no)
MESSAGE(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
ENDIF()
ENDIF(ENABLE_CXX11)
Expand Down Expand Up @@ -103,7 +108,7 @@ SET(SOURCES
include/internal/libfreenect2/async_packet_processor.h
include/internal/libfreenect2/depth_packet_processor.h
include/internal/libfreenect2/depth_packet_stream_parser.h
include/internal/libfreenect2/double_buffer.h
include/internal/libfreenect2/allocator.h
include/libfreenect2/frame_listener.hpp
include/libfreenect2/frame_listener_impl.h
include/libfreenect2/libfreenect2.hpp
Expand All @@ -118,7 +123,7 @@ SET(SOURCES
src/transfer_pool.cpp
src/event_loop.cpp
src/usb_control.cpp
src/double_buffer.cpp
src/allocator.cpp
src/frame_listener_impl.cpp
src/packet_pipeline.cpp
src/rgb_packet_stream_parser.cpp
Expand Down Expand Up @@ -147,11 +152,14 @@ SET(LIBFREENECT2_DLLS
${LibUSB_DLL}
)

SET(HAVE_VideoToolbox "no (Apple only)")
IF(APPLE)
FIND_LIBRARY(VIDEOTOOLBOX_LIBRARY VideoToolbox)

SET(HAVE_VideoToolbox no)
IF(VIDEOTOOLBOX_LIBRARY)
SET(LIBFREENECT2_WITH_VT_SUPPORT 1)
SET(HAVE_VideoToolbox yes)

FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation REQUIRED)
FIND_LIBRARY(COREMEDIA_LIBRARY CoreMedia REQUIRED)
Expand All @@ -170,14 +178,41 @@ IF(APPLE)
ENDIF(VIDEOTOOLBOX_LIBRARY)
ENDIF(APPLE)

SET(HAVE_VAAPI disabled)
IF(ENABLE_VAAPI)
IF(PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(VAAPI libva libva-drm)
ENDIF()
FIND_PACKAGE(JPEG)

SET(HAVE_VAAPI no)
IF(VAAPI_FOUND AND JPEG_FOUND)
SET(LIBFREENECT2_WITH_VAAPI_SUPPORT 1)
SET(HAVE_VAAPI yes)

INCLUDE_DIRECTORIES(${VAAPI_INCLUDE_DIRS})

LIST(APPEND SOURCES
src/vaapi_rgb_packet_processor.cpp
)
LIST(APPEND LIBRARIES
${VAAPI_LIBRARIES}
${JPEG_LIBRARY}
)
ENDIF()
ENDIF(ENABLE_VAAPI)

IF(LIBFREENECT2_WITH_VT_SUPPORT)
FIND_PACKAGE(TurboJPEG)
ELSE()
# VAAPI can fail to start at runtime. It must have a fallback.
FIND_PACKAGE(TurboJPEG REQUIRED)
ENDIF()

SET(HAVE_TurboJPEG no)
IF(TurboJPEG_FOUND)
SET(LIBFREENECT2_WITH_TURBOJPEG_SUPPORT 1)
SET(HAVE_TurboJPEG yes)

INCLUDE_DIRECTORIES(${TurboJPEG_INCLUDE_DIRS})

Expand All @@ -192,49 +227,57 @@ IF(TurboJPEG_FOUND)
LIST(APPEND LIBFREENECT2_DLLS
${TurboJPEG_DLL}
)

ENDIF()

SET(HAVE_OpenGL disablsed)
IF(ENABLE_OPENGL)
FIND_PACKAGE(GLFW3)
FIND_PACKAGE(OpenGL)
IF(GLFW3_FOUND)
SET(HAVE_OpenGL no)
IF(GLFW3_FOUND AND OPENGL_FOUND)
SET(LIBFREENECT2_WITH_OPENGL_SUPPORT 1)
SET(HAVE_OpenGL yes)

INCLUDE_DIRECTORIES(${GLFW3_INCLUDE_DIRS})

LIST(APPEND LIBFREENECT2_DLLS ${GLFW3_DLL})
LIST(APPEND LIBRARIES
${GLFW3_LIBRARIES}
${OPENGL_gl_LIBRARY}
)
SET(LIBFREENECT2_WITH_OPENGL_SUPPORT 1)
LIST(APPEND SOURCES
src/flextGL.cpp
src/opengl_depth_packet_processor.cpp
)
LIST(APPEND SOURCES
src/flextGL.cpp
src/opengl_depth_packet_processor.cpp
)

LIST(APPEND RESOURCES
src/shader/debug.fs
src/shader/default.vs
src/shader/filter1.fs
src/shader/filter2.fs
src/shader/stage1.fs
src/shader/stage2.fs
)
LIST(APPEND RESOURCES
src/shader/debug.fs
src/shader/default.vs
src/shader/filter1.fs
src/shader/filter2.fs
src/shader/stage1.fs
src/shader/stage2.fs
)
ENDIF()
ENDIF(ENABLE_OPENGL)

SET(HAVE_OpenCL disablsed)
IF(ENABLE_OPENCL)
FIND_PACKAGE(OpenCL)

SET(HAVE_OpenCL no)
IF(OpenCL_FOUND)
SET(LIBFREENECT2_WITH_OPENCL_SUPPORT 1)
SET(HAVE_OpenCL yes)

IF(UNIX AND NOT APPLE)
INCLUDE(CheckOpenCLICDLoader)
IF(OpenCL_C_WORKS AND NOT OpenCL_CXX_WORKS)
SET(LIBFREENECT2_OPENCL_ICD_LOADER_IS_OLD 1)
SET(HAVE_OpenCL "yes but buggy")
MESSAGE(WARNING "Your libOpenCL.so is incompatible with CL/cl.h. Install ocl-icd-opencl-dev to update libOpenCL.so?")
ENDIF()
ENDIF()
SET(LIBFREENECT2_WITH_OPENCL_SUPPORT 1)
INCLUDE_DIRECTORIES(${OpenCL_INCLUDE_DIRS})

LIST(APPEND SOURCES
Expand Down Expand Up @@ -312,14 +355,19 @@ INSTALL(FILES "${PROJECT_BINARY_DIR}/freenect2.pc" DESTINATION lib/pkgconfig/)

ADD_SUBDIRECTORY(${MY_DIR}/doc)

SET(HAVE_Examples disablsed)
IF(BUILD_EXAMPLES)
SET(HAVE_Examples yes)
MESSAGE(STATUS "Configurating examples")
ADD_SUBDIRECTORY(${MY_DIR}/examples)
ENDIF()

SET(HAVE_OpenNI2 disablsed)
IF(BUILD_OPENNI2_DRIVER)
FIND_PACKAGE(OpenNI2)
SET(HAVE_OpenNI2 no)
IF(OpenNI2_FOUND)
SET(HAVE_OpenNI2 yes)
FILE(GLOB OPENNI2_DRIVER_SOURCES src/openni2/*.cpp)
ADD_LIBRARY(freenect2-openni2 ${OPENNI2_DRIVER_SOURCES} ${LIBFREENECT2_THREADING_SOURCE})
TARGET_INCLUDE_DIRECTORIES(freenect2-openni2 PRIVATE ${OpenNI2_INCLUDE_DIRS})
Expand All @@ -336,3 +384,12 @@ IF(BUILD_OPENNI2_DRIVER)
)
ENDIF()
ENDIF()

GET_CMAKE_PROPERTY(vars VARIABLES)
MESSAGE(STATUS "Feature list:")
FOREACH(var ${vars})
IF(var MATCHES ^HAVE_)
STRING(REPLACE HAVE_ "" feature ${var})
MESSAGE(STATUS " ${feature} ${${var}}")
ENDIF()
ENDFOREACH()
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ It has been reported to work for up to 5 devices on a high-end PC using multiple

* OpenGL depth processing: OpenGL 3.1 (Windows, Linux, Mac OS X). OpenGL ES is not supported at the moment.
* OpenCL depth processing: OpenCL 1.1
* VAAPI JPEG decoding: Intel and Linux only
* OpenNI2 integration: OpenNI2 2.2.0.33

## Troubleshooting and reporting bugs
Expand Down Expand Up @@ -216,6 +217,10 @@ sudo apt-get install build-essential cmake pkg-config
- Nvidia discrete/Intel integrated GPUs: this gets tricky, but the rule of thumb is to make sure the actually used OpenCL headers and the driver libraries have matching versions.
- Mali GPU (e.g. Odroid XU4): (with root) `mkdir -p /etc/OpenCL/vendors; echo /usr/lib/arm-linux-gnueabihf/mali-egl/libmali.so >/etc/OpenCL/vendors/mali.icd; apt-get install opencl-headers`.
- Verify: You can install `clinfo` to verify if you have correctly set up the OpenCL stack.
* Install VAAPI (optional, Intel only)
1. (Ubuntu 14.04 only) `sudo dpkg -i debs/{libva,i965}*deb; sudo apt-get install -f`
2. (Other) `sudo apt-get install libva-dev libjpeg-dev`
3. Linux kernels 4.1 to 4.3 have performance regression. Use 4.0 and earlier or 4.4 and later (Though Ubuntu kernel 4.2.0-28.33~14.04.1 has backported the fix).
* Install OpenNI2 (optional)
1. (Ubuntu 14.04 only) `sudo apt-add-repository ppa:deb-rob/ros-trusty && sudo apt-get update` (You don't need this if you have ROS repos), then `sudo apt-get install libopenni2-dev`
2. (Other) `sudo apt-get install libopenni2-dev`.
Expand Down
2 changes: 2 additions & 0 deletions cmake_modules/SetupLibfreenect2Threading.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ IF(LIBFREENECT2_THREADING_STDLIB)
SET(LIBFREENECT2_THREADING_SOURCE "")
SET(LIBFREENECT2_THREADING_LIBRARIES "")
SET(LIBFREENECT2_THREADING_STDLIB 1)
SET(HAVE_Threading std::thread)
ELSE(LIBFREENECT2_THREADING_STDLIB)
SET(LIBFREENECT2_THREADING "tinythread")
SET(LIBFREENECT2_THREADING_INCLUDE_DIR "src/tinythread/")
Expand All @@ -37,6 +38,7 @@ ELSE(LIBFREENECT2_THREADING_STDLIB)
SET(LIBFREENECT2_THREADING_LIBRARIES "")
ENDIF(NOT WIN32)
SET(LIBFREENECT2_THREADING_TINYTHREAD 1)
SET(HAVE_Threading tinythread)
ENDIF(LIBFREENECT2_THREADING_STDLIB)

MESSAGE(STATUS "using ${LIBFREENECT2_THREADING} as threading library")
96 changes: 96 additions & 0 deletions include/internal/libfreenect2/allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* 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.
*/

/** @file allocator.h Allocator definitions. */

#ifndef ALLOCATOR_H_
#define ALLOCATOR_H_

#include <cstddef>

namespace libfreenect2
{

class Buffer
{
public:
size_t capacity; ///< Capacity of the buffer.
size_t length; ///< Used length of the buffer.
unsigned char* data; ///< Start address of the buffer.
};

class Allocator
{
public:
/* If the inner allocator fails to allocate, it MUST not return NULL.
* Instead it MUST return a Buffer with data being NULL.
* The stdlib will throw std::bad_alloc if new Buffer fails.
*/
virtual Buffer *allocate(size_t size) = 0;
virtual void free(Buffer *b) = 0;
virtual ~Allocator() {}
};

class PoolAllocatorImpl;

class PoolAllocator: public Allocator
{
public:
/* Use new as the inner allocator. */
PoolAllocator();

/* This inner allocator will be freed by PoolAllocator. */
PoolAllocator(Allocator *inner);

virtual ~PoolAllocator();

/* allocate() will block until an allocation is possible.
* It should be called as late as possible before the memory is required
* for write access.
*
* This allocate() never returns NULL as required by Allocator.
*
* All calls to allocate() MUST have the same size.
*
* allocate() MUST be called from the same thread.
*/
virtual Buffer *allocate(size_t size);

/* free() will unblock pending allocation.
* It should be called as early as possible after the memory is no longer
* required for read access.
*
* The inner free() can be called with NULL.
*
* free() can be called from different threads than allocate().
*/
virtual void free(Buffer *b);
private:
PoolAllocatorImpl *impl_;
};

} /* namespace libfreenect2 */
#endif /* ALLOCATOR_H_ */
25 changes: 25 additions & 0 deletions include/internal/libfreenect2/async_packet_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ class AsyncPacketProcessor : public PacketProcessor<PacketT>
return locked;
}

virtual bool good()
{
return processor_->good();
}

virtual void process(const PacketT &packet)
{
{
Expand All @@ -87,6 +92,17 @@ class AsyncPacketProcessor : public PacketProcessor<PacketT>
}
packet_condition_.notify_one();
}

virtual void allocateBuffer(PacketT &p, size_t size)
{
processor_->allocateBuffer(p, size);
}

virtual void releaseBuffer(PacketT &p)
{
processor_->releaseBuffer(p);
}

private:
PacketProcessorPtr processor_; ///< The processing routine, executed in the asynchronous thread.
bool current_packet_available_; ///< Whether #current_packet_ still needs processing.
Expand Down Expand Up @@ -119,6 +135,15 @@ class AsyncPacketProcessor : public PacketProcessor<PacketT>
{
// invoke process impl
processor_->process(current_packet_);
/*
* The stream parser passes the buffer asynchronously to processors so
* it can not wait after process() finishes and free the buffer. In
* theory releaseBuffer() should be called as soon as the access to it
* is finished, but right now no new allocateBuffer() will be called
* before ready() becomes true, so releaseBuffer() in the main loop of
* the async processor is OK.
*/
releaseBuffer(current_packet_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you call releaseBuffer here? shouldn't the stream parser do this? otherwise you assume that every packetprocessor is wrapped with an asyncpacketprocessor, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stream parser passes the buffer asynchronously so it can not wait after process() finishes and free the buffer.

I have assumed, or found very packet processor is wrapped in the async one, yes, and reduced multiple copies of releaseBuffer() to just this one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so basically every packetprocessor should call releaseBuffer at the end of process?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. In theory releaseBuffer should be called as soon as the access to it is finished, but right now no new allocateBuffer will be called before processor->ready() becomes true, so putting it in the main loop of async processor is OK.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, maybe add a comment mentioning what we discussed here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.


current_packet_available_ = false;
}
Expand Down
2 changes: 2 additions & 0 deletions include/internal/libfreenect2/depth_packet_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ struct DepthPacket
uint32_t timestamp;
unsigned char *buffer; ///< Depth data.
size_t buffer_length; ///< Size of depth data.

Buffer *memory;
};

/** Class for processing depth information. */
Expand Down
Loading