diff --git a/selfdrive/ui/replay/framereader.cc b/selfdrive/ui/replay/framereader.cc index 32af922f1f4aa2..5955d1bfcb05a3 100644 --- a/selfdrive/ui/replay/framereader.cc +++ b/selfdrive/ui/replay/framereader.cc @@ -3,6 +3,8 @@ #include #include "libyuv.h" +#include "cereal/visionipc/visionbuf.h" + namespace { struct buffer_data { @@ -98,6 +100,7 @@ bool FrameReader::load(const std::byte *data, size_t size, bool no_cuda, std::at width = (decoder_ctx->width + 3) & ~3; height = decoder_ctx->height; + visionbuf_compute_aligned_width_and_height(width, height, &aligned_width, &aligned_height); if (has_cuda_device && !no_cuda) { if (!initHardwareDecoder(AV_HWDEVICE_TYPE_CUDA)) { @@ -218,19 +221,21 @@ bool FrameReader::copyBuffers(AVFrame *f, uint8_t *rgb, uint8_t *yuv) { libyuv::NV12ToI420(f->data[0], f->linesize[0], f->data[1], f->linesize[1], y, width, u, width / 2, v, width / 2, width, height); libyuv::I420ToRGB24(y, width, u, width / 2, v, width / 2, - rgb, width * 3, width, height); + rgb, aligned_width * 3, width, height); } else { if (yuv) { uint8_t *u = yuv + width * height; uint8_t *v = u + (width / 2) * (height / 2); - memcpy(yuv, f->data[0], width * height); - memcpy(u, f->data[1], width / 2 * height / 2); - memcpy(v, f->data[2], width / 2 * height / 2); + libyuv::I420Copy(f->data[0], f->linesize[0], + f->data[1], f->linesize[1], + f->data[2], f->linesize[2], + yuv, width, u, width / 2, v, width / 2, + width, height); } libyuv::I420ToRGB24(f->data[0], f->linesize[0], f->data[1], f->linesize[1], f->data[2], f->linesize[2], - rgb, width * 3, width, height); + rgb, aligned_width * 3, width, height); } return true; } diff --git a/selfdrive/ui/replay/framereader.h b/selfdrive/ui/replay/framereader.h index d572b727e53828..8de5c1f93eb5cb 100644 --- a/selfdrive/ui/replay/framereader.h +++ b/selfdrive/ui/replay/framereader.h @@ -22,12 +22,13 @@ class FrameReader { bool load(const std::string &url, bool no_cuda = false, std::atomic *abort = nullptr, bool local_cache = false, int chunk_size = -1, int retries = 0); bool load(const std::byte *data, size_t size, bool no_cuda = false, std::atomic *abort = nullptr); bool get(int idx, uint8_t *rgb, uint8_t *yuv); - int getRGBSize() const { return width * height * 3; } + int getRGBSize() const { return aligned_width * aligned_height * 3; } 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);