diff --git a/selfdrive/ui/replay/framereader.cc b/selfdrive/ui/replay/framereader.cc index b733e71832..dd29d6363f 100644 --- a/selfdrive/ui/replay/framereader.cc +++ b/selfdrive/ui/replay/framereader.cc @@ -47,7 +47,9 @@ FrameReader::~FrameReader() { if (pFormatCtx_) avformat_close_input(&pFormatCtx_); if (av_frame_) av_frame_free(&av_frame_); if (rgb_frame_) av_frame_free(&rgb_frame_); - if (sws_ctx_) sws_freeContext(sws_ctx_); + if (yuv_frame_) av_frame_free(&yuv_frame_); + if (rgb_sws_ctx_) sws_freeContext(rgb_sws_ctx_); + if (yuv_sws_ctx_) sws_freeContext(yuv_sws_ctx_); } bool FrameReader::load(const std::string &url) { @@ -75,13 +77,19 @@ bool FrameReader::load(const std::string &url) { av_frame_ = av_frame_alloc(); rgb_frame_ = av_frame_alloc(); + yuv_frame_ = av_frame_alloc();; - width = pCodecCtxOrig->width; + width = (pCodecCtxOrig->width + 3) & ~3; height = pCodecCtxOrig->height; - sws_ctx_ = sws_getContext(width, height, AV_PIX_FMT_YUV420P, + rgb_sws_ctx_ = sws_getContext(pCodecCtxOrig->width, pCodecCtxOrig->height, AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL); - if (!sws_ctx_) return false; + if (!rgb_sws_ctx_) return false; + + yuv_sws_ctx_ = sws_getContext(pCodecCtxOrig->width, pCodecCtxOrig->height, AV_PIX_FMT_YUV420P, + width, height, AV_PIX_FMT_YUV420P, + SWS_FAST_BILINEAR, NULL, NULL, NULL); + if (!yuv_sws_ctx_) return false; frames_.reserve(60 * 20); // 20fps, one minute while (true) { @@ -143,10 +151,11 @@ bool FrameReader::decode(int idx, uint8_t *rgb, uint8_t *yuv) { bool FrameReader::decodeFrame(AVFrame *f, uint8_t *rgb, uint8_t *yuv) { // images is going to be written to output buffers, no alignment (align = 1) - int ret = av_image_copy_to_buffer(yuv, getYUVSize(), f->data, f->linesize, AV_PIX_FMT_YUV420P, f->width, f->height, 1); + av_image_fill_arrays(yuv_frame_->data, yuv_frame_->linesize, yuv, AV_PIX_FMT_YUV420P, width, height, 1); + int ret = sws_scale(yuv_sws_ctx_, (const uint8_t **)f->data, f->linesize, 0, f->height, yuv_frame_->data, yuv_frame_->linesize); if (ret < 0) return false; - av_image_fill_arrays(rgb_frame_->data, rgb_frame_->linesize, rgb, AV_PIX_FMT_BGR24, f->width, f->height, 1); - ret = sws_scale(sws_ctx_, (const uint8_t **)f->data, f->linesize, 0, f->height, rgb_frame_->data, rgb_frame_->linesize); + av_image_fill_arrays(rgb_frame_->data, rgb_frame_->linesize, rgb, AV_PIX_FMT_BGR24, width, height, 1); + ret = sws_scale(rgb_sws_ctx_, (const uint8_t **)f->data, f->linesize, 0, f->height, rgb_frame_->data, rgb_frame_->linesize); return ret >= 0; } diff --git a/selfdrive/ui/replay/framereader.h b/selfdrive/ui/replay/framereader.h index 5af8c8845b..b05336c0eb 100644 --- a/selfdrive/ui/replay/framereader.h +++ b/selfdrive/ui/replay/framereader.h @@ -33,8 +33,8 @@ private: bool failed = false; }; std::vector frames_; - SwsContext *sws_ctx_ = nullptr; - AVFrame *av_frame_, *rgb_frame_ = nullptr; + SwsContext *rgb_sws_ctx_ = nullptr, *yuv_sws_ctx_ = nullptr; + AVFrame *av_frame_, *rgb_frame_, *yuv_frame_ = nullptr; AVFormatContext *pFormatCtx_ = nullptr; AVCodecContext *pCodecCtx_ = nullptr; int key_frames_count_ = 0; diff --git a/tools/replay/lib/ui_helpers.py b/tools/replay/lib/ui_helpers.py index 8918d193bd..0573973f9f 100644 --- a/tools/replay/lib/ui_helpers.py +++ b/tools/replay/lib/ui_helpers.py @@ -30,7 +30,7 @@ _FULL_FRAME_TO_BB = {} _INTRINSICS = {} eon_f_qcam_frame_size = (480, 360) -tici_f_qcam_frame_size = (526, 330) +tici_f_qcam_frame_size = (528, 330) cams = [(eon_f_frame_size, eon_f_focal_length, eon_f_frame_size), (tici_f_frame_size, tici_f_focal_length, tici_f_frame_size),