mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-08-26 13:29:31 +08:00
[fix] prevent green tint during NV12 scaling
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
#include "nv12_scaler.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include "libyuv/planar_functions.h"
|
||||||
|
|
||||||
|
namespace crossdesk {
|
||||||
|
|
||||||
|
int ScaleNv12ViaI420(const uint8_t* src_y, int src_stride_y,
|
||||||
|
const uint8_t* src_uv, int src_stride_uv, int src_width,
|
||||||
|
int src_height, uint8_t* dst_y, int dst_stride_y,
|
||||||
|
uint8_t* dst_uv, int dst_stride_uv, int dst_width,
|
||||||
|
int dst_height, libyuv::FilterMode filtering,
|
||||||
|
std::vector<uint8_t>* scratch_buffer) {
|
||||||
|
if (!src_y || !src_uv || !dst_y || !dst_uv || !scratch_buffer ||
|
||||||
|
src_width <= 0 || src_height <= 0 || dst_width <= 0 || dst_height <= 0 ||
|
||||||
|
(src_width & 1) != 0 || (src_height & 1) != 0 || (dst_width & 1) != 0 ||
|
||||||
|
(dst_height & 1) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int src_chroma_width = src_width / 2;
|
||||||
|
const int src_chroma_height = src_height / 2;
|
||||||
|
const int dst_chroma_width = dst_width / 2;
|
||||||
|
const int dst_chroma_height = dst_height / 2;
|
||||||
|
const size_t src_chroma_size =
|
||||||
|
static_cast<size_t>(src_chroma_width) * src_chroma_height;
|
||||||
|
const size_t dst_chroma_size =
|
||||||
|
static_cast<size_t>(dst_chroma_width) * dst_chroma_height;
|
||||||
|
const size_t max_size = std::numeric_limits<size_t>::max();
|
||||||
|
if (src_chroma_size > max_size / 2 || dst_chroma_size > max_size / 2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t src_planes_size = 2 * src_chroma_size;
|
||||||
|
const size_t dst_planes_size = 2 * dst_chroma_size;
|
||||||
|
if (src_planes_size > max_size - dst_planes_size) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
scratch_buffer->resize(src_planes_size + dst_planes_size);
|
||||||
|
uint8_t* src_u = scratch_buffer->data();
|
||||||
|
uint8_t* src_v = src_u + src_chroma_size;
|
||||||
|
uint8_t* dst_u = src_v + src_chroma_size;
|
||||||
|
uint8_t* dst_v = dst_u + dst_chroma_size;
|
||||||
|
|
||||||
|
libyuv::SplitUVPlane(src_uv, src_stride_uv, src_u, src_chroma_width, src_v,
|
||||||
|
src_chroma_width, src_chroma_width, src_chroma_height);
|
||||||
|
const int result = libyuv::I420Scale(
|
||||||
|
src_y, src_stride_y, src_u, src_chroma_width, src_v, src_chroma_width,
|
||||||
|
src_width, src_height, dst_y, dst_stride_y, dst_u, dst_chroma_width,
|
||||||
|
dst_v, dst_chroma_width, dst_width, dst_height, filtering);
|
||||||
|
if (result != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
libyuv::MergeUVPlane(dst_u, dst_chroma_width, dst_v, dst_chroma_width, dst_uv,
|
||||||
|
dst_stride_uv, dst_chroma_width, dst_chroma_height);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace crossdesk
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef CROSSDESK_COMMON_NV12_SCALER_H_
|
||||||
|
#define CROSSDESK_COMMON_NV12_SCALER_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "libyuv/scale.h"
|
||||||
|
|
||||||
|
namespace crossdesk {
|
||||||
|
|
||||||
|
// Scales NV12 by separating the interleaved chroma plane before filtering.
|
||||||
|
// This avoids the downward chroma rounding bias in libyuv::NV12Scale while
|
||||||
|
// preserving the requested filtering quality.
|
||||||
|
int ScaleNv12ViaI420(const uint8_t* src_y, int src_stride_y,
|
||||||
|
const uint8_t* src_uv, int src_stride_uv, int src_width,
|
||||||
|
int src_height, uint8_t* dst_y, int dst_stride_y,
|
||||||
|
uint8_t* dst_uv, int dst_stride_uv, int dst_width,
|
||||||
|
int dst_height, libyuv::FilterMode filtering,
|
||||||
|
std::vector<uint8_t>* scratch_buffer);
|
||||||
|
|
||||||
|
} // namespace crossdesk
|
||||||
|
|
||||||
|
#endif // CROSSDESK_COMMON_NV12_SCALER_H_
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "crossdesk_ui.h"
|
#include "crossdesk_ui.h"
|
||||||
#include "fa_solid_900.h"
|
#include "fa_solid_900.h"
|
||||||
#include "localization.h"
|
#include "localization.h"
|
||||||
|
#include "nv12_scaler.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@@ -866,6 +867,7 @@ struct GuiApplication::SlintUi {
|
|||||||
std::make_shared<slint::VectorModel<slint::SharedString>>();
|
std::make_shared<slint::VectorModel<slint::SharedString>>();
|
||||||
std::unordered_map<std::string, uint64_t> displayed_frame_sequence;
|
std::unordered_map<std::string, uint64_t> displayed_frame_sequence;
|
||||||
std::vector<uint8_t> scaled_video_frame;
|
std::vector<uint8_t> scaled_video_frame;
|
||||||
|
std::vector<uint8_t> scaled_video_frame_scratch;
|
||||||
#if !defined(__APPLE__)
|
#if !defined(__APPLE__)
|
||||||
std::mutex video_gl_mutex;
|
std::mutex video_gl_mutex;
|
||||||
std::vector<uint8_t> video_gl_conversion_frame;
|
std::vector<uint8_t> video_gl_conversion_frame;
|
||||||
@@ -2651,10 +2653,11 @@ void GuiApplication::SyncStreamVideoFrame() {
|
|||||||
uint8_t* scaled_uv =
|
uint8_t* scaled_uv =
|
||||||
scaled_y +
|
scaled_y +
|
||||||
static_cast<size_t>(render_size.width) * render_size.height;
|
static_cast<size_t>(render_size.width) * render_size.height;
|
||||||
if (libyuv::NV12Scale(y_plane, width, uv_plane, width, width, height,
|
if (ScaleNv12ViaI420(
|
||||||
scaled_y, render_size.width, scaled_uv,
|
y_plane, width, uv_plane, width, width, height, scaled_y,
|
||||||
render_size.width, render_size.width,
|
render_size.width, scaled_uv, render_size.width, render_size.width,
|
||||||
render_size.height, libyuv::kFilterBox) == 0) {
|
render_size.height, libyuv::kFilterBox,
|
||||||
|
&ui_->scaled_video_frame_scratch) == 0) {
|
||||||
y_plane = scaled_y;
|
y_plane = scaled_y;
|
||||||
uv_plane = scaled_uv;
|
uv_plane = scaled_uv;
|
||||||
output_width = render_size.width;
|
output_width = render_size.width;
|
||||||
|
|||||||
+1
-1
Submodule submodules/minirtc updated: 9eafddd2fe...c2cda31219
@@ -33,6 +33,7 @@ function setup_targets()
|
|||||||
target("common")
|
target("common")
|
||||||
set_kind("object")
|
set_kind("object")
|
||||||
add_deps("rd_log")
|
add_deps("rd_log")
|
||||||
|
add_packages("libyuv")
|
||||||
add_files("src/common/*.cpp")
|
add_files("src/common/*.cpp")
|
||||||
remove_files("src/common/rounded_corner_button.cpp")
|
remove_files("src/common/rounded_corner_button.cpp")
|
||||||
if is_os("macosx") then
|
if is_os("macosx") then
|
||||||
|
|||||||
Reference in New Issue
Block a user