|
|
|
@ -3,6 +3,8 @@ |
|
|
|
|
#include <cassert> |
|
|
|
|
#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; |
|
|
|
|
} |
|
|
|
|