From 920677a43375285052a98dfd46585583bb7758c7 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Thu, 29 May 2025 15:02:43 +0800 Subject: [PATCH] [fix] use black to fill the blank areas around the thumbnail --- src/single_window/render_callback_func.cpp | 18 ------ src/single_window/thumbnail.cpp | 65 ++++++++++++---------- 2 files changed, 37 insertions(+), 46 deletions(-) diff --git a/src/single_window/render_callback_func.cpp b/src/single_window/render_callback_func.cpp index dff38a5..24a1903 100644 --- a/src/single_window/render_callback_func.cpp +++ b/src/single_window/render_callback_func.cpp @@ -251,24 +251,6 @@ void Render::OnReceiveAudioBufferCb(const char *data, size_t size, SDL_QueueAudio(render->output_dev_, data, (uint32_t)size); } -std::vector restore_display_list(char **display_list, - size_t display_num) { - std::vector result; - result.reserve(display_num); // 预分配空间,提升效率 - - for (size_t i = 0; i < display_num; i++) { - if (display_list[i] != nullptr) { - // 直接用std::string构造函数复制C字符串 - result.emplace_back(display_list[i]); - } else { - // 如果遇到nullptr指针,放空字符串或者处理错误 - result.emplace_back(""); - } - } - - return result; -} - void Render::OnReceiveDataBufferCb(const char *data, size_t size, const char *user_id, size_t user_id_size, void *user_data) { diff --git a/src/single_window/thumbnail.cpp b/src/single_window/thumbnail.cpp index a778a00..3b56a64 100644 --- a/src/single_window/thumbnail.cpp +++ b/src/single_window/thumbnail.cpp @@ -82,40 +82,49 @@ bool LoadTextureFromFile(const char* file_name, SDL_Renderer* renderer, return ret; } -void ScaleNv12ToABGR(char* dst_buffer_, int video_width_, int video_height_, - int scaled_video_width_, int scaled_video_height_, - char* rgba_buffer_) { - uint8_t* src_y = reinterpret_cast(dst_buffer_); - uint8_t* src_uv = src_y + video_width_ * video_height_; - int src_uv_stride = video_width_ / 2; - int src_uv_size = src_uv_stride * (video_height_ / 2); +void ScaleNv12ToABGR(char* src, int src_w, int src_h, int dst_w, int dst_h, + char* dst_rgba) { + uint8_t* y = reinterpret_cast(src); + uint8_t* uv = y + src_w * src_h; - std::unique_ptr tmp_u(new uint8_t[src_uv_size]); - std::unique_ptr tmp_v(new uint8_t[src_uv_size]); + float src_aspect = float(src_w) / src_h; + float dst_aspect = float(dst_w) / dst_h; + int fit_w = dst_w, fit_h = dst_h; + if (src_aspect > dst_aspect) { + fit_h = int(dst_w / src_aspect); + } else { + fit_w = int(dst_h * src_aspect); + } - libyuv::NV12ToI420(src_y, video_width_, src_uv, video_width_, src_y, - video_width_, tmp_u.get(), src_uv_stride, tmp_v.get(), - src_uv_stride, video_width_, video_height_); + std::vector y_i420(src_w * src_h); + std::vector u_i420((src_w / 2) * (src_h / 2)); + std::vector v_i420((src_w / 2) * (src_h / 2)); + libyuv::NV12ToI420(y, src_w, uv, src_w, y_i420.data(), src_w, u_i420.data(), + src_w / 2, v_i420.data(), src_w / 2, src_w, src_h); - int dst_y_stride = scaled_video_width_; - int dst_uv_stride = (scaled_video_width_ + 1) / 2; - int dst_uv_size = dst_uv_stride * ((scaled_video_height_ + 1) / 2); + std::vector y_fit(fit_w * fit_h); + std::vector u_fit((fit_w + 1) / 2 * (fit_h + 1) / 2); + std::vector v_fit((fit_w + 1) / 2 * (fit_h + 1) / 2); + libyuv::I420Scale(y_i420.data(), src_w, u_i420.data(), src_w / 2, + v_i420.data(), src_w / 2, src_w, src_h, y_fit.data(), fit_w, + u_fit.data(), (fit_w + 1) / 2, v_fit.data(), + (fit_w + 1) / 2, fit_w, fit_h, libyuv::kFilterBilinear); - std::unique_ptr dst_y( - new uint8_t[dst_y_stride * scaled_video_height_]); - std::unique_ptr dst_u(new uint8_t[dst_uv_size]); - std::unique_ptr dst_v(new uint8_t[dst_uv_size]); + std::vector abgr(fit_w * fit_h * 4); + libyuv::I420ToABGR(y_fit.data(), fit_w, u_fit.data(), (fit_w + 1) / 2, + v_fit.data(), (fit_w + 1) / 2, abgr.data(), fit_w * 4, + fit_w, fit_h); - libyuv::I420Scale(src_y, video_width_, tmp_u.get(), src_uv_stride, - tmp_v.get(), src_uv_stride, video_width_, video_height_, - dst_y.get(), dst_y_stride, dst_u.get(), dst_uv_stride, - dst_v.get(), dst_uv_stride, scaled_video_width_, - scaled_video_height_, libyuv::kFilterBilinear); + memset(dst_rgba, 0, dst_w * dst_h * 4); + for (int i = 0; i < dst_w * dst_h; ++i) { + dst_rgba[i * 4 + 3] = 255; + } - libyuv::I420ToABGR( - dst_y.get(), dst_y_stride, dst_u.get(), dst_uv_stride, dst_v.get(), - dst_uv_stride, reinterpret_cast(rgba_buffer_), - scaled_video_width_ * 4, scaled_video_width_, scaled_video_height_); + for (int y = 0; y < fit_h; ++y) { + int dst_offset = + ((y + (dst_h - fit_h) / 2) * dst_w + (dst_w - fit_w) / 2) * 4; + memcpy(dst_rgba + dst_offset, abgr.data() + y * fit_w * 4, fit_w * 4); + } } Thumbnail::Thumbnail() {