c++ replay: publish all frames in CameraServer (#22378)
* cameraserver * support yuv * init camera server in start() * trigger cipull/22430/head
parent
fd801c454a
commit
1eb79d7a59
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