I’m creating code that uses Jetson utils to get an IP Camera stream, overlay it, and save it.
First, I implement custom Mat class(like opencv Mat), and utilized it to apply a producer-consumer pattern.
namespace rs {
class Mat {
template <typename T = uchar3>
void create(int _rows, int _cols, T* _data = nullptr) {
this->cols = _cols;
this->rows = _rows;
auto size = _cols * _rows * sizeof(uchar3);
cudaError_t res = cudaSuccess;
if (data && std::is_same<T, uchar3>::value) {
res = cudaMalloc((void**)&data, size);
res = cudaMemcpy(this->data, _data, size, cudaMemcpyDeviceToDevice);
}
else if (size > 0 && _data == nullptr) {
res = cudaMalloc((void**)&data, size);
res = cudaMemset(this->data, 0, size);
}
}
////// deep copy //////
void copyTo(Mat& dest) const
{
dest.cols = this->cols;
dest.rows = this->rows;
auto size = dest.cols * dest.rows * sizeof(uchar3);
cudaError_t res = cudaMalloc((void**)&dest.data, size);
res = cudaMemcpy(dest.data, this->data, size, cudaMemcpyDeviceToDevice); // Error !!
... // break point
}
public:
Mat() { create(0, 0); }
Mat(int _rows, int _cols) { create(_rows, _cols); }
Mat(const rs::Size& _size) { create(_size.height, _size.width); }
////// shallow copy //////
Mat(const Mat& other)
{
this->rows = other.rows;
this->cols = other.cols;
this->data = other.data;
this->ref = other.ref;
if (ref) {
(*ref)++;
}
}
};
When using the copyTo function as shown below,
only_polygon_img and only_text_img’s data is allocated in memory,
but the img’s data is not actually copied, only the 0x00 values are retrieved.
When I run Cpature on Jetson-Utils, img.data in GDB contains the values just fine.
And I know that img.data is located in the Device location.
So I used cudaMemcpyDeviceToDevice in the copyTo function.
// in grabber.cpp
rs::Mat img;
input->Capture(&img.data, &status); // videoSource capture success
grab_buffer.push(img);
grab_event.notify_one();
// in detector.cpp
rs::Mat img = grab_buffer.front();
grab_buffer.pop();
rs::Mat only_text_img;
rs::Mat only_polygon_img;
img.copyTo(only_text_img); // only_text_img.data is empty
img.copyTo(only_polygon_img); // only_polygon_img.data is empty
// (example) save image : segmentation fault (core dumped)
imageWriter* writer = imageWriter::Create("test.jpg", options);
writer->Render(only_text_img.data, only_text_img.cols, only_text_img.rows);
...
All res values will return cudaSuccess. Is there something I’m missing?
I’m spending a lot of time thinking about this.
Can someone help me with this?