Remove dependency on FFmpeg

This commit is contained in:
dijunkun
2024-05-17 17:55:57 +08:00
parent d58ae3a6b1
commit 1393615f01
5 changed files with 539 additions and 506 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -5,36 +5,9 @@
#include <winrt/Windows.Foundation.Metadata.h>
#include <winrt/Windows.Graphics.Capture.h>
extern "C" {
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
};
#include <iostream>
int BGRAToNV12FFmpeg(unsigned char *src_buffer, int width, int height,
unsigned char *dst_buffer) {
AVFrame *Input_pFrame = av_frame_alloc();
AVFrame *Output_pFrame = av_frame_alloc();
struct SwsContext *img_convert_ctx =
sws_getContext(width, height, AV_PIX_FMT_BGRA, 1280, 720, AV_PIX_FMT_NV12,
SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);
av_image_fill_arrays(Input_pFrame->data, Input_pFrame->linesize, src_buffer,
AV_PIX_FMT_BGRA, width, height, 1);
av_image_fill_arrays(Output_pFrame->data, Output_pFrame->linesize, dst_buffer,
AV_PIX_FMT_NV12, 1280, 720, 1);
sws_scale(img_convert_ctx, (uint8_t const **)Input_pFrame->data,
Input_pFrame->linesize, 0, height, Output_pFrame->data,
Output_pFrame->linesize);
if (Input_pFrame) av_free(Input_pFrame);
if (Output_pFrame) av_free(Output_pFrame);
if (img_convert_ctx) sws_freeContext(img_convert_ctx);
return 0;
}
#include "libyuv.h"
BOOL WINAPI EnumMonitorProc(HMONITOR hmonitor, HDC hdc, LPRECT lprc,
LPARAM data) {
@@ -81,7 +54,11 @@ int ScreenCapturerWgc::Init(const RECORD_DESKTOP_RECT &rect, const int fps,
int error = 0;
if (_inited == true) return error;
nv12_frame_ = new unsigned char[rect.right * rect.bottom * 4];
int r = rect.right;
int b = rect.bottom;
nv12_frame_ = new unsigned char[rect.right * rect.bottom * 3 / 2];
nv12_frame_scaled_ = new unsigned char[1280 * 720 * 3 / 2];
_fps = fps;
@@ -120,6 +97,11 @@ int ScreenCapturerWgc::Destroy() {
nv12_frame_ = nullptr;
}
if (nv12_frame_scaled_) {
delete nv12_frame_scaled_;
nv12_frame_scaled_ = nullptr;
}
Stop();
CleanUp();
@@ -163,12 +145,83 @@ int ScreenCapturerWgc::Stop() {
return 0;
}
void ConvertABGRtoBGRA(const uint8_t *abgr_data, uint8_t *bgra_data, int width,
int height, int abgr_stride, int bgra_stride) {
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
// ABGR<47><52>BGRA<52><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
int abgr_index = (i * abgr_stride + j) * 4;
int bgra_index = (i * bgra_stride + j) * 4;
// ֱ<>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>ͺ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD>Alphaͨ<61><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bgra_data[bgra_index + 0] = abgr_data[abgr_index + 2]; // <20><>ɫ
bgra_data[bgra_index + 1] = abgr_data[abgr_index + 1]; // <20><>ɫ
bgra_data[bgra_index + 2] = abgr_data[abgr_index + 0]; // <20><>ɫ
bgra_data[bgra_index + 3] = abgr_data[abgr_index + 3]; // Alpha
}
}
}
void ConvertBGRAtoABGR(const uint8_t *bgra_data, uint8_t *abgr_data, int width,
int height, int bgra_stride, int abgr_stride) {
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
// BGRA<52><41>ABGR<47><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
int bgra_index = (i * bgra_stride + j) * 4;
int abgr_index = (i * abgr_stride + j) * 4;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD>Alphaͨ<61><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>
abgr_data[abgr_index + 0] = bgra_data[bgra_index + 3]; // Alpha
abgr_data[abgr_index + 1] = bgra_data[bgra_index + 0]; // Blue
abgr_data[abgr_index + 2] = bgra_data[bgra_index + 1]; // Green
abgr_data[abgr_index + 3] = bgra_data[bgra_index + 2]; // Red
}
}
}
void ScreenCapturerWgc::OnFrame(const WgcSession::wgc_session_frame &frame) {
if (_on_data)
BGRAToNV12FFmpeg((unsigned char *)frame.data, frame.width, frame.height,
nv12_frame_);
_on_data(nv12_frame_, frame.width * frame.height * 3 / 2, frame.width,
frame.height);
if (_on_data) {
int width = 1280;
int height = 720;
// libyuv::ARGBToI420(frame.data, frame.width * 4, yuv420_frame_,
// frame.width,
// yuv420_frame_ + frame.width * frame.height,
// frame.width / 2,
// yuv420_frame_ + frame.width * frame.height * 5 / 4,
// frame.width / 2, frame.width, frame.height);
// libyuv::I420Scale(
// (const uint8_t *)yuv420_frame_, frame.width,
// (const uint8_t *)(yuv420_frame_ + frame.width * frame.height),
// frame.width / 2,
// (const uint8_t *)(yuv420_frame_ + frame.width * frame.height * 5 /
// 4), frame.width / 2, frame.width, frame.height, (uint8_t
// *)yuv420_frame_, width, (uint8_t *)(yuv420_frame_ + width * height),
// width / 2, (uint8_t *)(yuv420_frame_ + width * height * 5 / 4), width
// / 2, width, height, libyuv::FilterMode::kFilterLinear);
// libyuv::I420ToNV12(
// (const uint8_t *)yuv420_frame_, width,
// (const uint8_t *)(yuv420_frame_ + width * height), width / 2,
// (const uint8_t *)(yuv420_frame_ + width * height * 5 / 4), width / 2,
// nv12_frame_, width, nv12_frame_ + width * height, width, width,
// height);
libyuv::ARGBToNV12(frame.data, frame.width * 4, nv12_frame_, frame.width,
nv12_frame_ + frame.width * frame.height,
frame.width / 2, frame.width, frame.height);
libyuv::NV12Scale(
(const uint8_t *)nv12_frame_, frame.width,
(const uint8_t *)(nv12_frame_ + frame.width * frame.height),
frame.width / 2, frame.width, frame.height,
(uint8_t *)nv12_frame_scaled_, width,
(uint8_t *)(nv12_frame_scaled_ + width * height), width / 2, width,
height, libyuv::FilterMode::kFilterLinear);
_on_data(nv12_frame_scaled_, width * height * 3 / 2, width, height);
}
}
void ScreenCapturerWgc::CleanUp() {

View File

@@ -49,9 +49,10 @@ class ScreenCapturerWgc : public ScreenCapturer,
int _fps;
cb_desktop_data _on_data;
cb_desktop_data _on_data = nullptr;
unsigned char *nv12_frame_ = nullptr;
unsigned char *nv12_frame_scaled_ = nullptr;
};
#endif

View File

@@ -16,28 +16,22 @@ end
add_requires("sdl2 2.28.3", {system = false})
add_requires("spdlog 1.11.0", {system = false})
add_requires("imgui 1.89.9", {configs = {sdl2 = true, sdl2_renderer = true}})
add_requires("libyuv")
if is_os("windows") then
add_links("Shell32", "windowsapp", "dwmapi", "User32", "kernel32",
"SDL2-static", "SDL2main", "gdi32", "winmm", "setupapi", "version",
"Imm32", "iphlpapi")
add_requires("vcpkg::ffmpeg 5.1.2", {configs = {shared = false}})
add_packages("vcpkg::ffmpeg")
elseif is_os("linux") then
add_requires("ffmpeg 5.1.2", {system = false})
add_packages("ffmpeg")
add_syslinks("pthread", "dl")
add_linkdirs("thirdparty/projectx/thirdparty/nvcodec/Lib/x64")
add_links("SDL2", "cuda", "nvidia-encode", "nvcuvid")
add_ldflags("-lavformat", "-lavdevice", "-lavfilter", "-lavcodec",
"-lswscale", "-lavutil", "-lswresample",
"-lasound", "-lxcb-shape", "-lxcb-xfixes", "-lsndio", "-lxcb",
add_ldflags("-lasound", "-lxcb-shape", "-lxcb-xfixes", "-lsndio", "-lxcb",
"-lxcb-shm", "-lXext", "-lX11", "-lXv", "-ldl", "-lpthread",
{force = true})
elseif is_os("macosx") then
add_requires("ffmpeg 5.1.2", {system = false})
add_requires("libxcb", {system = false})
add_packages("ffmpeg", "libxcb")
add_packages("libxcb")
add_links("SDL2", "SDL2main")
add_ldflags("-Wl,-ld_classic")
add_frameworks("OpenGL")
@@ -62,6 +56,7 @@ target("common")
target("screen_capturer")
set_kind("object")
add_deps("log")
add_packages("libyuv")
add_includedirs("src/screen_capturer", {public = true})
if is_os("windows") then
add_files("src/screen_capturer/windows/*.cpp")