#include "Rs2Driver.h" #include "Rs2Commands.h" #include "XnDepthShiftTables.h" #include namespace oni { namespace driver { Rs2Stream::Rs2Stream(OniSensorType sensorType) : m_rsType(convertStreamType(sensorType)), m_oniType(sensorType), m_device(nullptr), m_sensor(nullptr), m_sensorId(-1), m_streamId(-1), m_enabled(false), m_depthScale(0), m_fovX(0), m_fovY(0) { rsLogDebug("+Rs2Stream type=%d", (int)m_rsType); } Rs2Stream::~Rs2Stream() { rsLogDebug("~Rs2Stream type=%d", (int)m_rsType); shutdown(); } OniStatus Rs2Stream::initialize(class Rs2Device* device, rs2_sensor* sensor, int sensorId, int streamId, std::vector* profiles) { rsTraceFunc("type=%d sensorId=%d streamId=%d", (int)m_rsType, sensorId, streamId); m_device = device; m_sensor = sensor; m_sensorId = sensorId; m_streamId = streamId; m_profiles = *profiles; memset(&m_videoMode, 0, sizeof(m_videoMode)); memset(&m_intrinsics, 0, sizeof(m_intrinsics)); memset(&m_extrinsicsDepthToColor, 0, sizeof(m_extrinsicsDepthToColor)); m_depthScale = 0; m_fovX = 0; m_fovY = 0; if (m_oniType == ONI_SENSOR_DEPTH) m_videoMode.pixelFormat = ONI_PIXEL_FORMAT_DEPTH_1_MM; else if (m_oniType == ONI_SENSOR_COLOR) m_videoMode.pixelFormat = ONI_PIXEL_FORMAT_RGB888; else m_videoMode.pixelFormat = ONI_PIXEL_FORMAT_GRAY8; // TODO: maybe use default sensor mode? m_videoMode.resolutionX = 640; m_videoMode.resolutionY = 480; m_videoMode.fps = 30; if (m_oniType == ONI_SENSOR_DEPTH) { // TODO: these tables should be calculated depending on sensor parameters, using hardcoded values as workaround for NITE setTable(S2D, sizeof(S2D), m_s2d); // XN_STREAM_PROPERTY_S2D_TABLE setTable(D2S, sizeof(D2S), m_d2s); // XN_STREAM_PROPERTY_D2S_TABLE } updateIntrinsics(); return ONI_STATUS_OK; } void Rs2Stream::shutdown() { if (m_sensor) { rsTraceFunc("type=%d sensorId=%d streamId=%d", (int)m_rsType, m_sensorId, m_streamId); } stop(); if (m_sensor) { rs2_delete_sensor(m_sensor); m_sensor = nullptr; } } //============================================================================= // StreamBase overrides //============================================================================= OniStatus Rs2Stream::start() { if(!m_enabled) { rsTraceFunc("type=%d sensorId=%d streamId=%d", (int)m_rsType, m_sensorId, m_streamId); m_enabled = true; getDevice()->updateConfiguration(); } return ONI_STATUS_OK; } void Rs2Stream::stop() { if (m_enabled) { rsTraceFunc("type=%d sensorId=%d streamId=%d", (int)m_rsType, m_sensorId, m_streamId); m_enabled = false; getDevice()->updateConfiguration(); } } OniStatus Rs2Stream::invoke(int commandId, void* data, int dataSize) { if (commandId == RS2_PROJECT_POINT_TO_PIXEL && data && dataSize == sizeof(Rs2PointPixel)) { auto pp = (Rs2PointPixel*)data; rs2_project_point_to_pixel(pp->pixel, &m_intrinsics, pp->point); return ONI_STATUS_OK; } #if defined(RS2_TRACE_NOT_SUPPORTED_CMDS) rsTraceError("Not supported: commandId=%d", commandId); #endif return ONI_STATUS_NOT_SUPPORTED; } OniBool Rs2Stream::isCommandSupported(int commandId) { switch (commandId) { case RS2_PROJECT_POINT_TO_PIXEL: return true; } return false; } OniStatus Rs2Stream::convertDepthToColorCoordinates(StreamBase* colorStream, int depthX, int depthY, OniDepthPixel depthZ, int* pColorX, int* pColorY) { SCOPED_PROFILER; if (m_oniType != ONI_SENSOR_DEPTH) { rsTraceError("Invalid oniType=%d", (int)m_oniType); return ONI_STATUS_ERROR; } if (!colorStream || ((Rs2Stream*)colorStream)->getOniType() != ONI_SENSOR_COLOR) { rsTraceError("Invalid colorStream"); return ONI_STATUS_ERROR; } if (getDevice()->getRegistrationMode() == ONI_IMAGE_REGISTRATION_DEPTH_TO_COLOR) { *pColorX = depthX; *pColorY = depthY; } else { float pixel[2]; float point[3] = {0, 0, 0}; float transformed_point[3] = { 0 }; if (m_needUpdateExtrinsicsDepthToColor) { Rs2StreamProfileInfo* spiDepth = getCurrentProfile(); Rs2StreamProfileInfo* spiColor = ((Rs2Stream*)colorStream)->getCurrentProfile(); rs2_get_extrinsics(spiDepth->profile, spiColor->profile, &m_extrinsicsDepthToColor, nullptr); m_needUpdateExtrinsicsDepthToColor = false; } // depth pixel -> point pixel[0] = (float)depthX; pixel[1] = (float)depthY; rs2_deproject_pixel_to_point(point, &m_intrinsics, pixel, m_depthScale * depthZ); // depth point -> color point rs2_transform_point_to_point(transformed_point, &m_extrinsicsDepthToColor, point); // point -> color pixel rs2_project_point_to_pixel(pixel, &((Rs2Stream*)colorStream)->m_intrinsics, transformed_point); *pColorX = (int)pixel[0]; *pColorY = (int)pixel[1]; } //rsLogDebug("depth %d %d (%d) -> color %d %d", depthX, depthY, depthZ, *pColorX, *pColorY); return ONI_STATUS_OK; } //============================================================================= // Internals //============================================================================= void Rs2Stream::onStreamStarted() { updateIntrinsics(); } void Rs2Stream::onPipelineStarted() { } void Rs2Stream::updateIntrinsics() { Rs2StreamProfileInfo* spi = getCurrentProfile(); rs2_get_video_stream_intrinsics(spi->profile, &m_intrinsics, nullptr); rs2_fov(&m_intrinsics, &m_fovX); if (m_oniType == ONI_SENSOR_DEPTH) { m_depthScale = rs2_get_option((const rs2_options*)m_sensor, RS2_OPTION_DEPTH_UNITS, nullptr); } else { m_depthScale = 0; } m_needUpdateExtrinsicsDepthToColor = true; } Rs2StreamProfileInfo* Rs2Stream::getCurrentProfile() { SCOPED_PROFILER; rs2_format pixelFormat = convertPixelFormat(m_videoMode.pixelFormat); for (auto iter = m_profiles.begin(); iter != m_profiles.end(); ++iter) { Rs2StreamProfileInfo& sp = *iter; if (sp.streamType == m_rsType && sp.format == pixelFormat && sp.width == m_videoMode.resolutionX && sp.height == m_videoMode.resolutionY && sp.framerate == m_videoMode.fps) { return &sp; } } return nullptr; } bool Rs2Stream::isVideoModeSupported(OniVideoMode* reqMode) { SCOPED_PROFILER; rs2_format pixelFormat = convertPixelFormat(reqMode->pixelFormat); for (auto iter = m_profiles.begin(); iter != m_profiles.end(); ++iter) { const Rs2StreamProfileInfo& sp = *iter; if (sp.streamType == m_rsType && sp.format == pixelFormat && sp.width == reqMode->resolutionX && sp.height == reqMode->resolutionY && sp.framerate == reqMode->fps) { return true; } } return false; } bool Rs2Stream::getTable(void* dst, int* size, const std::vector& table) { const int tableSize = (int)(table.size() * sizeof(uint16_t)); if (dst && size && *size >= tableSize) { if (tableSize > 0) { memcpy(dst, &table[0], tableSize); } *size = tableSize; return true; } return false; } bool Rs2Stream::setTable(const void* src, int size, std::vector& table) { if (src && size >= 0) { const int elemCount = size / sizeof(uint16_t); if (elemCount > 0) { table.resize(elemCount); memcpy(&table[0], src, elemCount * sizeof(uint16_t)); } else { table.clear(); } return true; } return false; } }} // namespace