You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.2 KiB
68 lines
2.2 KiB
4 years ago
|
#include "selfdrive/ui/replay/camera.h"
|
||
|
|
||
|
#include <cassert>
|
||
|
#include <iostream>
|
||
|
|
||
|
const int YUV_BUF_COUNT = 50;
|
||
|
|
||
|
CameraServer::CameraServer() {
|
||
|
device_id_ = cl_get_device_id(CL_DEVICE_TYPE_DEFAULT);
|
||
|
context_ = CL_CHECK_ERR(clCreateContext(nullptr, 1, &device_id_, nullptr, nullptr, &err));
|
||
|
camera_thread_ = std::thread(&CameraServer::thread, this);
|
||
|
}
|
||
|
|
||
|
CameraServer::~CameraServer() {
|
||
|
queue_.push({});
|
||
|
camera_thread_.join();
|
||
|
vipc_server_.reset(nullptr);
|
||
|
CL_CHECK(clReleaseContext(context_));
|
||
|
}
|
||
|
|
||
|
void CameraServer::startVipcServer() {
|
||
|
std::cout << (vipc_server_ ? "start" : "restart") << " vipc server" << std::endl;
|
||
|
vipc_server_.reset(new VisionIpcServer("camerad", device_id_, context_));
|
||
|
for (auto &cam : cameras_) {
|
||
|
if (cam.width > 0 && cam.height > 0) {
|
||
|
vipc_server_->create_buffers(cam.rgb_type, UI_BUF_COUNT, true, cam.width, cam.height);
|
||
|
vipc_server_->create_buffers(cam.yuv_type, YUV_BUF_COUNT, false, cam.width, cam.height);
|
||
|
}
|
||
|
}
|
||
|
vipc_server_->start_listener();
|
||
|
}
|
||
|
|
||
|
void CameraServer::thread() {
|
||
|
while (true) {
|
||
|
const auto [type, fr, eidx] = queue_.pop();
|
||
|
if (!fr) break;
|
||
|
|
||
|
auto &cam = cameras_[type];
|
||
|
// start|restart the vipc server if frame size changed
|
||
|
if (cam.width != fr->width || cam.height != fr->height) {
|
||
|
cam.width = fr->width;
|
||
|
cam.height = fr->height;
|
||
|
std::cout << "camera[" << type << "] frame size " << cam.width << "x" << cam.height << std::endl;
|
||
|
startVipcServer();
|
||
|
}
|
||
|
|
||
|
// send frame
|
||
|
if (auto dat = fr->get(eidx.getSegmentId())) {
|
||
|
auto [rgb_dat, yuv_dat] = *dat;
|
||
|
VisionIpcBufExtra extra = {
|
||
|
.frame_id = eidx.getFrameId(),
|
||
|
.timestamp_sof = eidx.getTimestampSof(),
|
||
|
.timestamp_eof = eidx.getTimestampEof(),
|
||
|
};
|
||
|
|
||
|
VisionBuf *rgb_buf = vipc_server_->get_buffer(cam.rgb_type);
|
||
|
memcpy(rgb_buf->addr, rgb_dat, fr->getRGBSize());
|
||
|
VisionBuf *yuv_buf = vipc_server_->get_buffer(cam.yuv_type);
|
||
|
memcpy(yuv_buf->addr, yuv_dat, fr->getYUVSize());
|
||
|
|
||
|
vipc_server_->send(rgb_buf, &extra, false);
|
||
|
vipc_server_->send(yuv_buf, &extra, false);
|
||
|
} else {
|
||
|
std::cout << "camera[" << type << "] failed to get frame:" << eidx.getSegmentId() << std::endl;
|
||
|
}
|
||
|
}
|
||
|
}
|