使用uint16_t' s

时间:2015-08-04 09:48:30

标签: c++11 vector copy uint16

我正在寻找输入原因。有关上下文信息,请参阅附录,但我并不认为它是相关的。

我有std::vector<uint16_t> depth_buffer初始化为640 * 480个元素。这意味着占用的总空间为640*480*sizeof(uint16_t) = 614400

破解的代码:

void Kinect360::DepthCallback(void* _depth, uint32_t timestamp) {
    lock_guard<mutex> depth_data_lock(depth_mutex);

    uint16_t* depth = static_cast<uint16_t*>(_depth);
    std::copy(depth, depth + depthBufferSize(), depth_buffer.begin());/// the error
    new_depth_frame = true;
}

其中depthBufferSize()将返回614400(我已经多次验证了这一点)。

我对std::copy(first, amount, out)的理解是first指定了开始复制的内存地址,amount复制的字节数,以及{ {1}}是开始复制到的内存地址。

当然,可以通过

等手动完成
out

而不是对#pragma unroll for(auto i = 0; i < 640*480; ++i) depth_buffer[i] = depth[i]; 的调用,但我真的很困惑为什么std::copy在这里失败了。任何想法???

附录:上下文是我正在编写一个派生类,它继承自std::copy以使用Kinect 360.正式错误是FreenectDevice,但我几乎可以肯定这一点是因为libfreenect将Bus Error中的错误解释为DepthCallback。单步执行Bus Error,它是从lldb抛出的标准runtime_error。如果我手动输入std::copy它会崩溃,但如果我有depth + 614400它将会突然出现。在这个阶段,我没有对深度数据做一些有意义的事情(使用OpenGL正确渲染原始深度 是一个单独的问题xD),因此很难判断是否所有被复制,或只是一部分。也就是说,我几乎是肯定的,它并没有抓住它。

与相应的depth + (640*480)VideoCallback内部的调用相比,我不明白为什么上述情况会崩溃。如果我对copy(video, video + videoBufferSize(), video_buffer.begin())的理解是错误的,那么这应该会崩溃,因为std::copy将返回videoBufferSize()640*480*3*sizeof(uint8_t) = 640*480*3 = 921600来自于每个像素有3 *3个RGB RGB(无A)这一事实。 uint8_t游戏工作,正如OpenGL验证的那样(事实上它与libfreenect提供的样本基本相同......)。仅供参考我发现的样本中没有一个实际上直接使用原始深度数据,所有样本都会着色深度并使用带有RGB通道的VideoCallback,这不符合我对此项目的需求。

我很高兴只是忽略它并在某种意义上继续前进,因为我可以让它发挥作用,但我真的很困惑为什么这会破坏。谢谢你的任何想法!

1 个答案:

答案 0 :(得分:1)

std::copy的工作方式是提供输入序列的起点和终点以及开始复制的位置。您提供的结束点不在序列的末尾,因为您的depthBufferSize函数提供了以字节为单位的偏移量,而不是序列中的元素数量。

如果您将乘以sizeof(uint16_t),则会有效。此时,您可能还会考虑调用std::copy_n,这需要复制元素的数量。

编辑:我刚才意识到我没有直接回答这个问题。 根据我对std::copy的理解,它不应该通过您提供的输入抛出异常。该代码中唯一可以抛出runtime_error的是锁定互斥锁。 考虑到你的缓冲区结束后你有未定义的行为,我很想说它与它有关。