c++ replay: publish all frames in CameraServer (#22378)
* cameraserver
* support yuv
* init camera server in start()
* trigger ci
old-commit-hash: 1eb79d7a59
commatwo_master
parent
2dc5a00e3d
commit
a8c5acb884
8 changed files with 180 additions and 76 deletions
@ -0,0 +1,67 @@ |
|||||||
|
#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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <unistd.h> |
||||||
|
#include "cereal/visionipc/visionipc_server.h" |
||||||
|
#include "selfdrive/common/queue.h" |
||||||
|
#include "selfdrive/ui/replay/framereader.h" |
||||||
|
#include "selfdrive/ui/replay/logreader.h" |
||||||
|
|
||||||
|
class CameraServer { |
||||||
|
public: |
||||||
|
CameraServer(); |
||||||
|
~CameraServer(); |
||||||
|
inline void pushFrame(CameraType type, FrameReader* fr, const cereal::EncodeIndex::Reader& eidx) { |
||||||
|
queue_.push({type, fr, eidx}); |
||||||
|
} |
||||||
|
inline void waitFinish() { |
||||||
|
while (!queue_.empty()) usleep(0); |
||||||
|
} |
||||||
|
|
||||||
|
protected: |
||||||
|
void startVipcServer(); |
||||||
|
void thread(); |
||||||
|
|
||||||
|
struct Camera { |
||||||
|
VisionStreamType rgb_type; |
||||||
|
VisionStreamType yuv_type; |
||||||
|
int width; |
||||||
|
int height; |
||||||
|
}; |
||||||
|
|
||||||
|
Camera cameras_[MAX_CAMERAS] = { |
||||||
|
{.rgb_type = VISION_STREAM_RGB_BACK, .yuv_type = VISION_STREAM_YUV_BACK}, |
||||||
|
{.rgb_type = VISION_STREAM_RGB_FRONT, .yuv_type = VISION_STREAM_YUV_FRONT}, |
||||||
|
{.rgb_type = VISION_STREAM_RGB_WIDE, .yuv_type = VISION_STREAM_YUV_WIDE}, |
||||||
|
}; |
||||||
|
cl_device_id device_id_; |
||||||
|
cl_context context_; |
||||||
|
std::thread camera_thread_; |
||||||
|
std::unique_ptr<VisionIpcServer> vipc_server_; |
||||||
|
SafeQueue<std::tuple<CameraType, FrameReader*, const cereal::EncodeIndex::Reader>> queue_; |
||||||
|
}; |
Loading…
Reference in new issue