replay: fix visionbuf alignment on device (#26913)
* align visionbuf * update test case * cleanup * fix cpplint warning old-commit-hash: 3c94d953ab9fcaf8ee2371af3f269ae46d3563c6
This commit is contained in:
@@ -22,4 +22,4 @@ replay_libs = [replay_lib, 'avutil', 'avcodec', 'avformat', 'bz2', 'curl', 'yuv'
|
||||
qt_env.Program("replay", ["main.cc"], LIBS=replay_libs, FRAMEWORKS=base_frameworks)
|
||||
|
||||
if GetOption('test'):
|
||||
qt_env.Program('tests/test_replay', ['tests/test_runner.cc', 'tests/test_replay.cc'], LIBS=[replay_libs])
|
||||
qt_env.Program('tests/test_replay', ['tests/test_runner.cc', 'tests/test_replay.cc'], LIBS=[replay_libs, qt_libs])
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
#include "tools/replay/camera.h"
|
||||
#include "tools/replay/util.h"
|
||||
#include "msm_media_info.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <tuple>
|
||||
|
||||
std::tuple<size_t, size_t, size_t> get_nv12_info(int width, int height) {
|
||||
int nv12_width = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
|
||||
int nv12_height = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
|
||||
assert(nv12_width == VENUS_UV_STRIDE(COLOR_FMT_NV12, width));
|
||||
assert(nv12_height / 2 == VENUS_UV_SCANLINES(COLOR_FMT_NV12, height));
|
||||
size_t nv12_buffer_size = 2346 * nv12_width; // comes from v4l2_format.fmt.pix_mp.plane_fmt[0].sizeimage
|
||||
return {nv12_width, nv12_height, nv12_buffer_size};
|
||||
}
|
||||
|
||||
CameraServer::CameraServer(std::pair<int, int> camera_size[MAX_CAMERAS]) {
|
||||
for (int i = 0; i < MAX_CAMERAS; ++i) {
|
||||
@@ -25,7 +36,9 @@ void CameraServer::startVipcServer() {
|
||||
for (auto &cam : cameras_) {
|
||||
if (cam.width > 0 && cam.height > 0) {
|
||||
rInfo("camera[%d] frame size %dx%d", cam.type, cam.width, cam.height);
|
||||
vipc_server_->create_buffers(cam.stream_type, YUV_BUFFER_COUNT, false, cam.width, cam.height);
|
||||
auto [nv12_width, nv12_height, nv12_buffer_size] = get_nv12_info(cam.width, cam.height);
|
||||
vipc_server_->create_buffers_with_sizes(cam.stream_type, YUV_BUFFER_COUNT, false, cam.width, cam.height,
|
||||
nv12_buffer_size, nv12_width, nv12_width * nv12_height);
|
||||
if (!cam.thread.joinable()) {
|
||||
cam.thread = std::thread(&CameraServer::cameraThread, this, std::ref(cam));
|
||||
}
|
||||
@@ -38,7 +51,7 @@ void CameraServer::cameraThread(Camera &cam) {
|
||||
auto read_frame = [&](FrameReader *fr, int frame_id) {
|
||||
VisionBuf *yuv_buf = vipc_server_->get_buffer(cam.stream_type);
|
||||
assert(yuv_buf);
|
||||
bool ret = fr->get(frame_id, (uint8_t *)yuv_buf->addr);
|
||||
bool ret = fr->get(frame_id, yuv_buf);
|
||||
return ret ? yuv_buf : nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "cereal/visionipc/visionipc_server.h"
|
||||
@@ -10,6 +11,8 @@
|
||||
#include "tools/replay/framereader.h"
|
||||
#include "tools/replay/logreader.h"
|
||||
|
||||
std::tuple<size_t, size_t, size_t> get_nv12_info(int width, int height);
|
||||
|
||||
class CameraServer {
|
||||
public:
|
||||
CameraServer(std::pair<int, int> camera_size[MAX_CAMERAS] = nullptr);
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <algorithm>
|
||||
#include "libyuv.h"
|
||||
|
||||
#include "cereal/visionipc/visionbuf.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define HW_DEVICE_TYPE AV_HWDEVICE_TYPE_VIDEOTOOLBOX
|
||||
#define HW_PIX_FMT AV_PIX_FMT_VIDEOTOOLBOX
|
||||
@@ -119,7 +117,6 @@ bool FrameReader::load(const std::byte *data, size_t size, bool no_hw_decoder, s
|
||||
|
||||
width = (decoder_ctx->width + 3) & ~3;
|
||||
height = decoder_ctx->height;
|
||||
visionbuf_compute_aligned_width_and_height(width, height, &aligned_width, &aligned_height);
|
||||
|
||||
if (has_hw_decoder && !no_hw_decoder) {
|
||||
if (!initHardwareDecoder(HW_DEVICE_TYPE)) {
|
||||
@@ -178,15 +175,15 @@ bool FrameReader::initHardwareDecoder(AVHWDeviceType hw_device_type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FrameReader::get(int idx, uint8_t *yuv) {
|
||||
assert(yuv != nullptr);
|
||||
bool FrameReader::get(int idx, VisionBuf *buf) {
|
||||
assert(buf != nullptr);
|
||||
if (!valid_ || idx < 0 || idx >= packets.size()) {
|
||||
return false;
|
||||
}
|
||||
return decode(idx, yuv);
|
||||
return decode(idx, buf);
|
||||
}
|
||||
|
||||
bool FrameReader::decode(int idx, uint8_t *yuv) {
|
||||
bool FrameReader::decode(int idx, VisionBuf *buf) {
|
||||
int from_idx = idx;
|
||||
if (idx != prev_idx + 1 && key_frames_count_ > 1) {
|
||||
// seeking to the nearest key frame
|
||||
@@ -202,7 +199,7 @@ bool FrameReader::decode(int idx, uint8_t *yuv) {
|
||||
for (int i = from_idx; i <= idx; ++i) {
|
||||
AVFrame *f = decodeFrame(packets[i]);
|
||||
if (f && i == idx) {
|
||||
return copyBuffers(f, yuv);
|
||||
return copyBuffers(f, buf);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -234,22 +231,20 @@ AVFrame *FrameReader::decodeFrame(AVPacket *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
bool FrameReader::copyBuffers(AVFrame *f, uint8_t *yuv) {
|
||||
assert(f != nullptr && yuv != nullptr);
|
||||
uint8_t *y = yuv;
|
||||
uint8_t *uv = y + width * height;
|
||||
bool FrameReader::copyBuffers(AVFrame *f, VisionBuf *buf) {
|
||||
assert(f != nullptr && buf != nullptr);
|
||||
if (hw_pix_fmt == HW_PIX_FMT) {
|
||||
for (int i = 0; i < height/2; i++) {
|
||||
memcpy(y + (i*2 + 0)*width, f->data[0] + (i*2 + 0)*f->linesize[0], width);
|
||||
memcpy(y + (i*2 + 1)*width, f->data[0] + (i*2 + 1)*f->linesize[0], width);
|
||||
memcpy(uv + i*width, f->data[1] + i*f->linesize[1], width);
|
||||
memcpy(buf->y + (i*2 + 0)*buf->stride, f->data[0] + (i*2 + 0)*f->linesize[0], width);
|
||||
memcpy(buf->y + (i*2 + 1)*buf->stride, f->data[0] + (i*2 + 1)*f->linesize[0], width);
|
||||
memcpy(buf->uv + i*buf->stride, f->data[1] + i*f->linesize[1], width);
|
||||
}
|
||||
} else {
|
||||
libyuv::I420ToNV12(f->data[0], f->linesize[0],
|
||||
f->data[1], f->linesize[1],
|
||||
f->data[2], f->linesize[2],
|
||||
y, width,
|
||||
uv, width,
|
||||
buf->y, buf->stride,
|
||||
buf->uv, buf->stride,
|
||||
width, height);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cereal/visionipc/visionbuf.h"
|
||||
#include "tools/replay/filereader.h"
|
||||
|
||||
extern "C" {
|
||||
@@ -22,19 +23,18 @@ public:
|
||||
bool load(const std::string &url, bool no_hw_decoder = false, std::atomic<bool> *abort = nullptr, bool local_cache = false,
|
||||
int chunk_size = -1, int retries = 0);
|
||||
bool load(const std::byte *data, size_t size, bool no_hw_decoder = false, std::atomic<bool> *abort = nullptr);
|
||||
bool get(int idx, uint8_t *yuv);
|
||||
bool get(int idx, VisionBuf *buf);
|
||||
int getYUVSize() const { return width * height * 3 / 2; }
|
||||
size_t getFrameCount() const { return packets.size(); }
|
||||
bool valid() const { return valid_; }
|
||||
|
||||
int width = 0, height = 0;
|
||||
int aligned_width = 0, aligned_height = 0;
|
||||
|
||||
private:
|
||||
bool initHardwareDecoder(AVHWDeviceType hw_device_type);
|
||||
bool decode(int idx, uint8_t *yuv);
|
||||
bool decode(int idx, VisionBuf *buf);
|
||||
AVFrame * decodeFrame(AVPacket *pkt);
|
||||
bool copyBuffers(AVFrame *f, uint8_t *yuv);
|
||||
bool copyBuffers(AVFrame *f, VisionBuf *buf);
|
||||
|
||||
std::vector<AVPacket*> packets;
|
||||
std::unique_ptr<AVFrame, AVFrameDeleter>av_frame_, hw_frame;
|
||||
|
||||
@@ -95,10 +95,13 @@ void read_segment(int n, const SegmentFile &segment_file, uint32_t flags) {
|
||||
if (cam == RoadCam || cam == WideRoadCam) {
|
||||
REQUIRE(fr->getFrameCount() == 1200);
|
||||
}
|
||||
std::unique_ptr<uint8_t[]> yuv_buf = std::make_unique<uint8_t[]>(fr->getYUVSize());
|
||||
auto [nv12_width, nv12_height, nv12_buffer_size] = get_nv12_info(fr->width, fr->height);
|
||||
VisionBuf buf;
|
||||
buf.allocate(nv12_buffer_size);
|
||||
buf.init_yuv(fr->width, fr->height, nv12_width, nv12_width * nv12_height);
|
||||
// sequence get 100 frames
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
REQUIRE(fr->get(i, yuv_buf.get()));
|
||||
REQUIRE(fr->get(i, &buf));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user