From a3f3bb4751cdc7db143e22376119d9346897cf88 Mon Sep 17 00:00:00 2001 From: 21pages Date: Mon, 8 May 2023 19:57:32 +0800 Subject: [PATCH 1/6] aom vcpkg binding Signed-off-by: 21pages --- libs/scrap/build.rs | 26 +++++++++++++------------ libs/scrap/src/bindings/aom_ffi.h | 8 ++++++++ libs/scrap/{ => src/bindings}/vpx_ffi.h | 16 +++++++-------- 3 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 libs/scrap/src/bindings/aom_ffi.h rename libs/scrap/{ => src/bindings}/vpx_ffi.h (96%) diff --git a/libs/scrap/build.rs b/libs/scrap/build.rs index 3e08469b0..72fe0707a 100644 --- a/libs/scrap/build.rs +++ b/libs/scrap/build.rs @@ -144,16 +144,17 @@ fn generate_bindings( include_paths: &[PathBuf], ffi_rs: &Path, exact_file: &Path, + regex: &str, ) { let mut b = bindgen::builder() .header(ffi_header.to_str().unwrap()) - .allowlist_type("^[vV].*") - .allowlist_var("^[vV].*") - .allowlist_function("^[vV].*") - .rustified_enum("^v.*") + .allowlist_type(regex) + .allowlist_var(regex) + .allowlist_function(regex) + .rustified_enum(regex) .trust_clang_mangling(false) .layout_tests(false) // breaks 32/64-bit compat - .generate_comments(false); // vpx comments have prefix /*!\ + .generate_comments(false); // comments have prefix /*!\ for dir in include_paths { b = b.clang_arg(format!("-I{}", dir.display())); @@ -163,22 +164,22 @@ fn generate_bindings( fs::copy(ffi_rs, exact_file).ok(); // ignore failure } -fn gen_vpx() { - let includes = find_package("libvpx"); +fn gen_vcpkg_package(package: &str, ffi_header: &str, generated: &str, regex: &str) { + let includes = find_package(package); let src_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); let src_dir = Path::new(&src_dir); let out_dir = env::var_os("OUT_DIR").unwrap(); let out_dir = Path::new(&out_dir); - let ffi_header = src_dir.join("vpx_ffi.h"); + let ffi_header = src_dir.join("src").join("bindings").join(ffi_header); println!("rerun-if-changed={}", ffi_header.display()); for dir in &includes { println!("rerun-if-changed={}", dir.display()); } - let ffi_rs = out_dir.join("vpx_ffi.rs"); - let exact_file = src_dir.join("generated").join("vpx_ffi.rs"); - generate_bindings(&ffi_header, &includes, &ffi_rs, &exact_file); + let ffi_rs = out_dir.join(generated); + let exact_file = src_dir.join("generated").join(generated); + generate_bindings(&ffi_header, &includes, &ffi_rs, &exact_file, regex); } fn main() { @@ -194,7 +195,8 @@ fn main() { env::set_var("CARGO_CFG_TARGET_FEATURE", "crt-static"); find_package("libyuv"); - gen_vpx(); + gen_vcpkg_package("libvpx", "vpx_ffi.h", "vpx_ffi.rs", "^[vV].*"); + gen_vcpkg_package("aom", "aom_ffi.h", "aom_ffi.rs", "^(aom|AOM|OBU|AV1).*"); // there is problem with cfg(target_os) in build.rs, so use our workaround let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); diff --git a/libs/scrap/src/bindings/aom_ffi.h b/libs/scrap/src/bindings/aom_ffi.h new file mode 100644 index 000000000..3b7babf2b --- /dev/null +++ b/libs/scrap/src/bindings/aom_ffi.h @@ -0,0 +1,8 @@ +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/libs/scrap/vpx_ffi.h b/libs/scrap/src/bindings/vpx_ffi.h similarity index 96% rename from libs/scrap/vpx_ffi.h rename to libs/scrap/src/bindings/vpx_ffi.h index 3db471e8f..cd44f9865 100644 --- a/libs/scrap/vpx_ffi.h +++ b/libs/scrap/src/bindings/vpx_ffi.h @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include \ No newline at end of file From e482dc3e2bdf429813c7ff85a1dff96a77990079 Mon Sep 17 00:00:00 2001 From: 21pages Date: Mon, 8 May 2023 20:35:24 +0800 Subject: [PATCH 2/6] aom encode/decode Signed-off-by: 21pages --- flutter/lib/common/widgets/toolbar.dart | 12 +- .../desktop/pages/desktop_setting_page.dart | 5 + libs/hbb_common/protos/message.proto | 4 + libs/hbb_common/src/config.rs | 4 +- libs/scrap/examples/benchmark.rs | 73 +- libs/scrap/src/bindings/aom_ffi.h | 4 +- libs/scrap/src/common/aom.rs | 625 ++++++++++++++++++ libs/scrap/src/common/codec.rs | 53 +- libs/scrap/src/common/mod.rs | 6 + src/client/io_loop.rs | 2 +- src/flutter_ffi.rs | 4 +- src/server/video_service.rs | 6 + src/ui/header.tis | 7 +- src/ui/remote.rs | 3 +- src/ui_session_interface.rs | 6 +- 15 files changed, 780 insertions(+), 34 deletions(-) create mode 100644 libs/scrap/src/common/aom.rs diff --git a/flutter/lib/common/widgets/toolbar.dart b/flutter/lib/common/widgets/toolbar.dart index 451c7d1a5..32522fb66 100644 --- a/flutter/lib/common/widgets/toolbar.dart +++ b/flutter/lib/common/widgets/toolbar.dart @@ -280,15 +280,18 @@ Future>> toolbarCodec( try { final Map codecsJson = jsonDecode(alternativeCodecs); final vp8 = codecsJson['vp8'] ?? false; + final av1 = codecsJson['av1'] ?? false; final h264 = codecsJson['h264'] ?? false; final h265 = codecsJson['h265'] ?? false; codecs.add(vp8); + codecs.add(av1); codecs.add(h264); codecs.add(h265); } catch (e) { debugPrint("Show Codec Preference err=$e"); } - final visible = codecs.length == 3 && (codecs[0] || codecs[1] || codecs[2]); + final visible = + codecs.length == 4 && (codecs[0] || codecs[1] || codecs[2] || codecs[3]); if (!visible) return []; onChanged(String? value) async { if (value == null) return; @@ -307,10 +310,11 @@ Future>> toolbarCodec( return [ radio('Auto', 'auto', true), - if (isDesktop || codecs[0]) radio('VP8', 'vp8', codecs[0]), + if (codecs[0]) radio('VP8', 'vp8', codecs[0]), radio('VP9', 'vp9', true), - if (isDesktop || codecs[1]) radio('H264', 'h264', codecs[1]), - if (isDesktop || codecs[2]) radio('H265', 'h265', codecs[2]), + if (codecs[1]) radio('AV1', 'av1', codecs[1]), + if (codecs[2]) radio('H264', 'h264', codecs[2]), + if (codecs[3]) radio('H265', 'h265', codecs[3]), ]; } diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 3202d0d35..2cb2f5d54 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -1322,6 +1322,11 @@ class _DisplayState extends State<_Display> { groupValue: groupValue, label: 'VP9', onChanged: onChanged), + _Radio(context, + value: 'av1', + groupValue: groupValue, + label: 'AV1', + onChanged: onChanged), ...hwRadios, ]); } diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 1d8e76af4..29cbb35c2 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -25,6 +25,7 @@ message VideoFrame { EncodedVideoFrames h264s = 10; EncodedVideoFrames h265s = 11; EncodedVideoFrames vp8s = 12; + EncodedVideoFrames av1s = 13; } } @@ -85,6 +86,7 @@ message SupportedEncoding { bool h264 = 1; bool h265 = 2; bool vp8 = 3; + bool av1 = 4; } message PeerInfo { @@ -477,6 +479,7 @@ message SupportedDecoding { H264 = 2; H265 = 3; VP8 = 4; + AV1 = 5; } int32 ability_vp9 = 1; @@ -484,6 +487,7 @@ message SupportedDecoding { int32 ability_h265 = 3; PreferCodec prefer = 4; int32 ability_vp8 = 5; + int32 ability_av1 = 6; } message OptionMessage { diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 693acb8f4..14aa5b16b 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -1399,7 +1399,9 @@ impl UserDefaultConfig { "view_style" => self.get_string(key, "original", vec!["adaptive"]), "scroll_style" => self.get_string(key, "scrollauto", vec!["scrollbar"]), "image_quality" => self.get_string(key, "balanced", vec!["best", "low", "custom"]), - "codec-preference" => self.get_string(key, "auto", vec!["vp8", "vp9", "h264", "h265"]), + "codec-preference" => { + self.get_string(key, "auto", vec!["vp8", "vp9", "av1", "h264", "h265"]) + } "custom_image_quality" => self.get_double_string(key, 50.0, 10.0, 100.0), "custom-fps" => self.get_double_string(key, 30.0, 5.0, 120.0), _ => self diff --git a/libs/scrap/examples/benchmark.rs b/libs/scrap/examples/benchmark.rs index ba8dec9f2..eccf502d9 100644 --- a/libs/scrap/examples/benchmark.rs +++ b/libs/scrap/examples/benchmark.rs @@ -1,6 +1,7 @@ use docopt::Docopt; use hbb_common::env_logger::{init_from_env, Env, DEFAULT_FILTER_ENV}; use scrap::{ + aom::{AomDecoder, AomDecoderConfig, AomEncoder, AomEncoderConfig}, codec::{EncoderApi, EncoderCfg}, Capturer, Display, TraitCapturer, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, VpxVideoCodecId::{self, *}, @@ -51,6 +52,7 @@ fn main() { width, height, bitrate_k, args.flag_hw_pixfmt ); [VP8, VP9].map(|c| test_vpx(c, &yuvs, width, height, bitrate_k, yuv_count)); + test_av1(&yuvs, width, height, bitrate_k, yuv_count); #[cfg(feature = "hwcodec")] { use hwcodec::AVPixelFormat; @@ -105,34 +107,29 @@ fn test_vpx( num_threads: (num_cpus::get() / 2) as _, }); let mut encoder = VpxEncoder::new(config).unwrap(); - let start = Instant::now(); - for yuv in yuvs { - let _ = encoder - .encode(start.elapsed().as_millis() as _, yuv, STRIDE_ALIGN) - .unwrap(); - let _ = encoder.flush().unwrap(); - } - println!( - "{:?} encode: {:?}", - codec_id, - start.elapsed() / yuv_count as _ - ); - - // prepare data separately let mut vpxs = vec![]; let start = Instant::now(); + let mut size = 0; for yuv in yuvs { for ref frame in encoder .encode(start.elapsed().as_millis() as _, yuv, STRIDE_ALIGN) .unwrap() { + size += frame.data.len(); vpxs.push(frame.data.to_vec()); } for ref frame in encoder.flush().unwrap() { + size += frame.data.len(); vpxs.push(frame.data.to_vec()); } } assert_eq!(vpxs.len(), yuv_count); + println!( + "{:?} encode: {:?}, {} byte", + codec_id, + start.elapsed() / yuv_count as _, + size / yuv_count + ); let mut decoder = VpxDecoder::new(VpxDecoderConfig { codec: codec_id, @@ -151,6 +148,43 @@ fn test_vpx( ); } +fn test_av1(yuvs: &Vec>, width: usize, height: usize, bitrate_k: usize, yuv_count: usize) { + let config = EncoderCfg::AOM(AomEncoderConfig { + width: width as _, + height: height as _, + bitrate: bitrate_k as _, + }); + let mut encoder = AomEncoder::new(config).unwrap(); + let start = Instant::now(); + let mut size = 0; + let mut av1s = vec![]; + for yuv in yuvs { + for ref frame in encoder + .encode(start.elapsed().as_millis() as _, yuv, STRIDE_ALIGN) + .unwrap() + { + size += frame.data.len(); + av1s.push(frame.data.to_vec()); + } + } + assert_eq!(av1s.len(), yuv_count); + println!( + "AV1 encode: {:?}, {} byte", + start.elapsed() / yuv_count as _, + size / yuv_count + ); + let mut decoder = AomDecoder::new(AomDecoderConfig { + num_threads: (num_cpus::get() / 2) as _, + }) + .unwrap(); + let start = Instant::now(); + for av1 in av1s { + let _ = decoder.decode(&av1); + let _ = decoder.flush(); + } + println!("AV1 decode: {:?}", start.elapsed() / yuv_count as _); +} + #[cfg(feature = "hwcodec")] mod hw { use super::*; @@ -221,14 +255,19 @@ mod hw { ctx.name = info.name; let mut encoder = Encoder::new(ctx.clone()).unwrap(); let start = Instant::now(); + let mut size = 0; for yuv in yuvs { - let _ = encoder.encode(yuv).unwrap(); + let frames = encoder.encode(yuv).unwrap(); + for frame in frames { + size += frame.data.len(); + } } println!( - "{}{}: {:?}", + "{}{}: {:?}, {} byte", if best { "*" } else { "" }, ctx.name, - start.elapsed() / yuvs.len() as _ + start.elapsed() / yuvs.len() as _, + size / yuvs.len(), ); } diff --git a/libs/scrap/src/bindings/aom_ffi.h b/libs/scrap/src/bindings/aom_ffi.h index 3b7babf2b..bc4077b7b 100644 --- a/libs/scrap/src/bindings/aom_ffi.h +++ b/libs/scrap/src/bindings/aom_ffi.h @@ -5,4 +5,6 @@ #include #include #include -#include +#include +#include +#include diff --git a/libs/scrap/src/common/aom.rs b/libs/scrap/src/common/aom.rs new file mode 100644 index 000000000..2d750c8d2 --- /dev/null +++ b/libs/scrap/src/common/aom.rs @@ -0,0 +1,625 @@ +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(improper_ctypes)] +#![allow(dead_code)] + +include!(concat!(env!("OUT_DIR"), "/aom_ffi.rs")); + +use crate::{codec::EncoderApi, EncodeFrame, ImageFormat, ImageRgb, STRIDE_ALIGN}; +use hbb_common::{ + anyhow::{anyhow, Context}, + bytes::Bytes, + message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame}, + ResultType, +}; +use std::{ptr, slice}; + +impl Default for aom_codec_enc_cfg_t { + fn default() -> Self { + unsafe { std::mem::zeroed() } + } +} + +impl Default for aom_codec_ctx_t { + fn default() -> Self { + unsafe { std::mem::zeroed() } + } +} + +impl Default for aom_image_t { + fn default() -> Self { + unsafe { std::mem::zeroed() } + } +} + +#[derive(Debug)] +pub enum Error { + FailedCall(String), + BadPtr(String), +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> { + write!(f, "{:?}", self) + } +} + +impl std::error::Error for Error {} + +pub type Result = std::result::Result; + +macro_rules! call_aom { + ($x:expr) => {{ + let result = unsafe { $x }; // original expression + let result_int = unsafe { std::mem::transmute::<_, i32>(result) }; + if result_int != 0 { + return Err(Error::FailedCall(format!( + "errcode={} {}:{}:{}:{}", + result_int, + module_path!(), + file!(), + line!(), + column!() + )) + .into()); + } + result + }}; +} + +macro_rules! call_aom_ptr { + ($x:expr) => {{ + let result = unsafe { $x }; // original expression + let result_int = unsafe { std::mem::transmute::<_, isize>(result) }; + if result_int == 0 { + return Err(Error::BadPtr(format!( + "errcode={} {}:{}:{}:{}", + result_int, + module_path!(), + file!(), + line!(), + column!() + )) + .into()); + } + result + }}; +} + +#[derive(Clone, Copy, Debug)] +pub struct AomEncoderConfig { + pub width: u32, + pub height: u32, + pub bitrate: u32, +} + +pub struct AomEncoder { + ctx: aom_codec_ctx_t, + width: usize, + height: usize, +} + +// https://webrtc.googlesource.com/src/+/refs/heads/main/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +mod webrtc { + use super::*; + + const kQpMin: u32 = 10; + const kUsageProfile: u32 = AOM_USAGE_REALTIME; + const kMinQindex: u32 = 145; // Min qindex threshold for QP scaling. + const kMaxQindex: u32 = 205; // Max qindex threshold for QP scaling. + const kBitDepth: u32 = 8; + const kLagInFrames: u32 = 0; // No look ahead. + const kRtpTicksPerSecond: i32 = 90000; + const kMinimumFrameRate: f64 = 1.0; + + const kQpMax: u32 = 25; // to-do: webrtc use dynamic value, no more than 63 + + fn number_of_threads(width: u32, height: u32, number_of_cores: usize) -> u32 { + // Keep the number of encoder threads equal to the possible number of + // column/row tiles, which is (1, 2, 4, 8). See comments below for + // AV1E_SET_TILE_COLUMNS/ROWS. + if width * height >= 640 * 360 && number_of_cores > 4 { + return 4; + } else if width * height >= 320 * 180 && number_of_cores > 2 { + return 2; + } else { + // Use 2 threads for low res on ARM. + #[cfg(any(target_arch = "arm", target_arch = "aarch64", target_os = "android"))] + if (width * height >= 320 * 180 && number_of_cores > 2) { + return 2; + } + // 1 thread less than VGA. + return 1; + } + } + + // Only positive speeds, range for real-time coding currently is: 6 - 8. + // Lower means slower/better quality, higher means fastest/lower quality. + fn get_cpu_speed(width: u32, height: u32) -> u32 { + // aux_config_ = nullptr, kComplexityHigh + if width * height <= 320 * 180 { + 8 + } else if width * height <= 640 * 360 { + 9 + } else { + 10 + } + } + + fn get_super_block_size(width: u32, height: u32, threads: u32) -> aom_superblock_size_t { + use aom_superblock_size::*; + let resolution = width * height; + if threads >= 4 && resolution >= 960 * 540 && resolution < 1920 * 1080 { + AOM_SUPERBLOCK_SIZE_64X64 + } else { + AOM_SUPERBLOCK_SIZE_DYNAMIC + } + } + + pub fn enc_cfg( + i: *const aom_codec_iface, + cfg: AomEncoderConfig, + ) -> ResultType { + let mut c = unsafe { std::mem::MaybeUninit::zeroed().assume_init() }; + call_aom!(aom_codec_enc_config_default(i, &mut c, kUsageProfile)); + + // Overwrite default config with input encoder settings & RTC-relevant values. + c.g_w = cfg.width; + c.g_h = cfg.height; + c.g_threads = number_of_threads(cfg.width, cfg.height, num_cpus::get()); + c.g_timebase.num = 1; + c.g_timebase.den = kRtpTicksPerSecond; + c.rc_target_bitrate = cfg.bitrate; // kilobits/sec. + c.g_input_bit_depth = kBitDepth; + c.kf_mode = aom_kf_mode::AOM_KF_DISABLED; + c.rc_min_quantizer = kQpMin; + c.rc_max_quantizer = kQpMax; + c.rc_undershoot_pct = 50; + c.rc_overshoot_pct = 50; + c.rc_buf_initial_sz = 600; + c.rc_buf_optimal_sz = 600; + c.rc_buf_sz = 1000; + c.g_usage = kUsageProfile; + c.g_error_resilient = 0; + // Low-latency settings. + c.rc_end_usage = aom_rc_mode::AOM_CBR; // Constant Bit Rate (CBR) mode + c.g_pass = aom_enc_pass::AOM_RC_ONE_PASS; // One-pass rate control + c.g_lag_in_frames = kLagInFrames; // No look ahead when lag equals 0. + + Ok(c) + } + + pub fn set_controls(ctx: *mut aom_codec_ctx_t, cfg: &aom_codec_enc_cfg) -> ResultType<()> { + use aom_tune_content::*; + use aome_enc_control_id::*; + macro_rules! call_ctl { + ($ctx:expr, $av1e:expr, $arg:expr) => {{ + call_aom!(aom_codec_control($ctx, $av1e as i32, $arg)); + }}; + } + + call_ctl!(ctx, AOME_SET_CPUUSED, get_cpu_speed(cfg.g_w, cfg.g_h)); + call_ctl!(ctx, AV1E_SET_ENABLE_CDEF, 1); + call_ctl!(ctx, AV1E_SET_ENABLE_TPL_MODEL, 0); + call_ctl!(ctx, AV1E_SET_DELTAQ_MODE, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_ORDER_HINT, 0); + call_ctl!(ctx, AV1E_SET_AQ_MODE, 3); + call_ctl!(ctx, AOME_SET_MAX_INTRA_BITRATE_PCT, 300); + call_ctl!(ctx, AV1E_SET_COEFF_COST_UPD_FREQ, 3); + call_ctl!(ctx, AV1E_SET_MODE_COST_UPD_FREQ, 3); + call_ctl!(ctx, AV1E_SET_MV_COST_UPD_FREQ, 3); + // kScreensharing + call_ctl!(ctx, AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN); + call_ctl!(ctx, AV1E_SET_ENABLE_PALETTE, 1); + let tile_set = if cfg.g_threads == 4 && cfg.g_w == 640 && (cfg.g_h == 360 || cfg.g_h == 480) + { + AV1E_SET_TILE_ROWS + } else { + AV1E_SET_TILE_COLUMNS + }; + call_ctl!(ctx, tile_set, (cfg.g_threads as f64 * 1.0f64).log2().ceil()); + call_ctl!(ctx, AV1E_SET_ROW_MT, 1); + call_ctl!(ctx, AV1E_SET_ENABLE_OBMC, 0); + call_ctl!(ctx, AV1E_SET_NOISE_SENSITIVITY, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_WARPED_MOTION, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_GLOBAL_MOTION, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_REF_FRAME_MVS, 0); + call_ctl!( + ctx, + AV1E_SET_SUPERBLOCK_SIZE, + get_super_block_size(cfg.g_w, cfg.g_h, cfg.g_threads) + ); + call_ctl!(ctx, AV1E_SET_ENABLE_CFL_INTRA, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_SMOOTH_INTRA, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_ANGLE_DELTA, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_FILTER_INTRA, 0); + call_ctl!(ctx, AV1E_SET_INTRA_DEFAULT_TX_ONLY, 1); + call_ctl!(ctx, AV1E_SET_DISABLE_TRELLIS_QUANT, 1); + call_ctl!(ctx, AV1E_SET_ENABLE_DIST_WTD_COMP, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_DIFF_WTD_COMP, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_DUAL_FILTER, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_INTERINTRA_COMP, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_INTERINTRA_WEDGE, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_INTRABC, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_MASKED_COMP, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_PAETH_INTRA, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_QM, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_RECT_PARTITIONS, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_RESTORATION, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_SMOOTH_INTERINTRA, 0); + call_ctl!(ctx, AV1E_SET_ENABLE_TX64, 0); + call_ctl!(ctx, AV1E_SET_MAX_REFERENCE_FRAMES, 3); + + Ok(()) + } +} + +impl EncoderApi for AomEncoder { + fn new(cfg: crate::codec::EncoderCfg) -> ResultType + where + Self: Sized, + { + match cfg { + crate::codec::EncoderCfg::AOM(config) => { + let i = call_aom_ptr!(aom_codec_av1_cx()); + let c = webrtc::enc_cfg(i, config)?; + + let mut ctx = Default::default(); + // Flag options: AOM_CODEC_USE_PSNR and AOM_CODEC_USE_HIGHBITDEPTH + let flags: aom_codec_flags_t = 0; + call_aom!(aom_codec_enc_init_ver( + &mut ctx, + i, + &c, + flags, + AOM_ENCODER_ABI_VERSION as _ + )); + webrtc::set_controls(&mut ctx, &c)?; + Ok(Self { + ctx, + width: config.width as _, + height: config.height as _, + }) + } + _ => Err(anyhow!("encoder type mismatch")), + } + } + + fn encode_to_message(&mut self, frame: &[u8], ms: i64) -> ResultType { + let mut frames = Vec::new(); + for ref frame in self + .encode(ms, frame, STRIDE_ALIGN) + .with_context(|| "Failed to encode")? + { + frames.push(Self::create_frame(frame)); + } + if frames.len() > 0 { + Ok(Self::create_msg(frames)) + } else { + Err(anyhow!("no valid frame")) + } + } + + fn use_yuv(&self) -> bool { + true + } + + fn set_bitrate(&mut self, bitrate: u32) -> ResultType<()> { + let mut new_enc_cfg = unsafe { *self.ctx.config.enc.to_owned() }; + new_enc_cfg.rc_target_bitrate = bitrate; + call_aom!(aom_codec_enc_config_set(&mut self.ctx, &new_enc_cfg)); + return Ok(()); + } +} + +impl AomEncoder { + pub fn encode(&mut self, pts: i64, data: &[u8], stride_align: usize) -> Result { + if 2 * data.len() < 3 * self.width * self.height { + return Err(Error::FailedCall("len not enough".to_string())); + } + + let mut image = Default::default(); + call_aom_ptr!(aom_img_wrap( + &mut image, + aom_img_fmt::AOM_IMG_FMT_I420, + self.width as _, + self.height as _, + stride_align as _, + data.as_ptr() as _, + )); + + call_aom!(aom_codec_encode( + &mut self.ctx, + &image, + pts as _, + 1, // Duration + 0, // Flags + )); + + Ok(EncodeFrames { + ctx: &mut self.ctx, + iter: ptr::null(), + }) + } + + #[inline] + pub fn create_msg(frames: Vec) -> Message { + let mut msg_out = Message::new(); + let mut vf = VideoFrame::new(); + let av1s = EncodedVideoFrames { + frames: frames.into(), + ..Default::default() + }; + vf.set_av1s(av1s); + msg_out.set_video_frame(vf); + msg_out + } + + #[inline] + fn create_frame(frame: &EncodeFrame) -> EncodedVideoFrame { + EncodedVideoFrame { + data: Bytes::from(frame.data.to_vec()), + key: frame.key, + pts: frame.pts, + ..Default::default() + } + } +} + +impl Drop for AomEncoder { + fn drop(&mut self) { + unsafe { + let result = aom_codec_destroy(&mut self.ctx); + if result != aom_codec_err_t::AOM_CODEC_OK { + panic!("failed to destroy aom codec"); + } + } + } +} + +pub struct EncodeFrames<'a> { + ctx: &'a mut aom_codec_ctx_t, + iter: aom_codec_iter_t, +} + +impl<'a> Iterator for EncodeFrames<'a> { + type Item = EncodeFrame<'a>; + fn next(&mut self) -> Option { + loop { + unsafe { + let pkt = aom_codec_get_cx_data(self.ctx, &mut self.iter); + if pkt.is_null() { + return None; + } else if (*pkt).kind == aom_codec_cx_pkt_kind::AOM_CODEC_CX_FRAME_PKT { + let f = &(*pkt).data.frame; + return Some(Self::Item { + data: slice::from_raw_parts(f.buf as _, f.sz as _), + key: (f.flags & AOM_FRAME_IS_KEY) != 0, + pts: f.pts, + }); + } else { + // Ignore the packet. + } + } + } + } +} + +pub struct AomDecoderConfig { + pub num_threads: u32, +} + +pub struct AomDecoder { + ctx: aom_codec_ctx_t, +} + +impl AomDecoder { + pub fn new(cfg: AomDecoderConfig) -> Result { + let i = call_aom_ptr!(aom_codec_av1_dx()); + let mut ctx = Default::default(); + let cfg = aom_codec_dec_cfg_t { + threads: if cfg.num_threads == 0 { + num_cpus::get() as _ + } else { + cfg.num_threads + }, + w: 0, + h: 0, + allow_lowbitdepth: 1, + }; + call_aom!(aom_codec_dec_init_ver( + &mut ctx, + i, + &cfg, + 0, + AOM_DECODER_ABI_VERSION as _, + )); + Ok(Self { ctx }) + } + + pub fn decode(&mut self, data: &[u8]) -> Result { + call_aom!(aom_codec_decode( + &mut self.ctx, + data.as_ptr(), + data.len() as _, + ptr::null_mut(), + )); + + Ok(DecodeFrames { + ctx: &mut self.ctx, + iter: ptr::null(), + }) + } + + /// Notify the decoder to return any pending frame + pub fn flush(&mut self) -> Result { + call_aom!(aom_codec_decode( + &mut self.ctx, + ptr::null(), + 0, + ptr::null_mut(), + )); + Ok(DecodeFrames { + ctx: &mut self.ctx, + iter: ptr::null(), + }) + } +} + +impl Drop for AomDecoder { + fn drop(&mut self) { + unsafe { + let result = aom_codec_destroy(&mut self.ctx); + if result != aom_codec_err_t::AOM_CODEC_OK { + panic!("failed to destroy aom codec"); + } + } + } +} + +pub struct DecodeFrames<'a> { + ctx: &'a mut aom_codec_ctx_t, + iter: aom_codec_iter_t, +} + +impl<'a> Iterator for DecodeFrames<'a> { + type Item = Image; + fn next(&mut self) -> Option { + let img = unsafe { aom_codec_get_frame(self.ctx, &mut self.iter) }; + if img.is_null() { + return None; + } else { + return Some(Image(img)); + } + } +} + +pub struct Image(*mut aom_image_t); +impl Image { + #[inline] + pub fn new() -> Self { + Self(std::ptr::null_mut()) + } + + #[inline] + pub fn is_null(&self) -> bool { + self.0.is_null() + } + + #[inline] + pub fn width(&self) -> usize { + self.inner().d_w as _ + } + + #[inline] + pub fn height(&self) -> usize { + self.inner().d_h as _ + } + + #[inline] + pub fn format(&self) -> aom_img_fmt_t { + self.inner().fmt + } + + #[inline] + pub fn inner(&self) -> &aom_image_t { + unsafe { &*self.0 } + } + + #[inline] + pub fn stride(&self, iplane: usize) -> i32 { + self.inner().stride[iplane] + } + + #[inline] + pub fn get_bytes_per_row(w: usize, fmt: ImageFormat, stride: usize) -> usize { + let bytes_per_pixel = match fmt { + ImageFormat::Raw => 3, + ImageFormat::ARGB | ImageFormat::ABGR => 4, + }; + // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L128 + // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L129 + (w * bytes_per_pixel + stride - 1) & !(stride - 1) + } + + // rgb [in/out] fmt and stride must be set in ImageRgb + pub fn to(&self, rgb: &mut ImageRgb) { + rgb.w = self.width(); + rgb.h = self.height(); + let bytes_per_row = Self::get_bytes_per_row(rgb.w, rgb.fmt, rgb.stride()); + rgb.raw.resize(rgb.h * bytes_per_row, 0); + let img = self.inner(); + unsafe { + match rgb.fmt() { + ImageFormat::Raw => { + super::I420ToRAW( + img.planes[0], + img.stride[0], + img.planes[1], + img.stride[1], + img.planes[2], + img.stride[2], + rgb.raw.as_mut_ptr(), + bytes_per_row as _, + self.width() as _, + self.height() as _, + ); + } + ImageFormat::ARGB => { + super::I420ToARGB( + img.planes[0], + img.stride[0], + img.planes[1], + img.stride[1], + img.planes[2], + img.stride[2], + rgb.raw.as_mut_ptr(), + bytes_per_row as _, + self.width() as _, + self.height() as _, + ); + } + ImageFormat::ABGR => { + super::I420ToABGR( + img.planes[0], + img.stride[0], + img.planes[1], + img.stride[1], + img.planes[2], + img.stride[2], + rgb.raw.as_mut_ptr(), + bytes_per_row as _, + self.width() as _, + self.height() as _, + ); + } + } + } + } + + #[inline] + pub fn data(&self) -> (&[u8], &[u8], &[u8]) { + unsafe { + let img = self.inner(); + let h = (img.d_h as usize + 1) & !1; + let n = img.stride[0] as usize * h; + let y = slice::from_raw_parts(img.planes[0], n); + let n = img.stride[1] as usize * (h >> 1); + let u = slice::from_raw_parts(img.planes[1], n); + let v = slice::from_raw_parts(img.planes[2], n); + (y, u, v) + } + } +} + +impl Drop for Image { + fn drop(&mut self) { + if !self.0.is_null() { + unsafe { aom_img_free(self.0) }; + } + } +} + +unsafe impl Send for aom_codec_ctx_t {} diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index 0f5b5dad3..a54921482 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -10,7 +10,11 @@ use crate::hwcodec::*; use crate::mediacodec::{ MediaCodecDecoder, MediaCodecDecoders, H264_DECODER_SUPPORT, H265_DECODER_SUPPORT, }; -use crate::{vpxcodec::*, CodecName, ImageRgb}; +use crate::{ + aom::{self, AomDecoder, AomDecoderConfig, AomEncoder, AomEncoderConfig}, + vpxcodec::{self, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, VpxVideoCodecId}, + CodecName, ImageRgb, +}; #[cfg(not(any(target_os = "android", target_os = "ios")))] use hbb_common::sysinfo::{System, SystemExt}; @@ -43,6 +47,7 @@ pub struct HwEncoderConfig { #[derive(Debug, Clone)] pub enum EncoderCfg { VPX(VpxEncoderConfig), + AOM(AomEncoderConfig), HW(HwEncoderConfig), } @@ -79,6 +84,7 @@ impl DerefMut for Encoder { pub struct Decoder { vp8: VpxDecoder, vp9: VpxDecoder, + av1: AomDecoder, #[cfg(feature = "hwcodec")] hw: HwDecoders, #[cfg(feature = "hwcodec")] @@ -101,6 +107,9 @@ impl Encoder { EncoderCfg::VPX(_) => Ok(Encoder { codec: Box::new(VpxEncoder::new(config)?), }), + EncoderCfg::AOM(_) => Ok(Encoder { + codec: Box::new(AomEncoder::new(config)?), + }), #[cfg(feature = "hwcodec")] EncoderCfg::HW(_) => match HwEncoder::new(config) { @@ -139,6 +148,7 @@ impl Encoder { } let vp8_useable = decodings.len() > 0 && decodings.iter().all(|(_, s)| s.ability_vp8 > 0); + let av1_useable = decodings.len() > 0 && decodings.iter().all(|(_, s)| s.ability_av1 > 0); #[allow(unused_mut)] let mut h264_name = None; #[allow(unused_mut)] @@ -167,6 +177,7 @@ impl Encoder { .filter(|(_, s)| { s.prefer == PreferCodec::VP9.into() || s.prefer == PreferCodec::VP8.into() && vp8_useable + || s.prefer == PreferCodec::AV1.into() && av1_useable || s.prefer == PreferCodec::H264.into() && h264_name.is_some() || s.prefer == PreferCodec::H265.into() && h265_name.is_some() }) @@ -187,6 +198,7 @@ impl Encoder { match preference { PreferCodec::VP8 => *name = CodecName::VP8, PreferCodec::VP9 => *name = CodecName::VP9, + PreferCodec::AV1 => *name = CodecName::AV1, PreferCodec::H264 => *name = h264_name.map_or(auto_codec, |c| CodecName::H264(c)), PreferCodec::H265 => *name = h265_name.map_or(auto_codec, |c| CodecName::H265(c)), PreferCodec::Auto => *name = auto_codec, @@ -209,6 +221,7 @@ impl Encoder { #[allow(unused_mut)] let mut encoding = SupportedEncoding { vp8: true, + av1: true, ..Default::default() }; #[cfg(feature = "hwcodec")] @@ -227,6 +240,7 @@ impl Decoder { let mut decoding = SupportedDecoding { ability_vp8: 1, ability_vp9: 1, + ability_av1: 1, prefer: id_for_perfer .map_or(PreferCodec::Auto, |id| Self::codec_preference(id)) .into(), @@ -267,9 +281,14 @@ impl Decoder { num_threads: (num_cpus::get() / 2) as _, }) .unwrap(); + let av1 = AomDecoder::new(AomDecoderConfig { + num_threads: (num_cpus::get() / 2) as _, + }) + .unwrap(); Decoder { vp8, vp9, + av1, #[cfg(feature = "hwcodec")] hw: if enable_hwcodec_option() { HwDecoder::new_decoders() @@ -300,6 +319,9 @@ impl Decoder { video_frame::Union::Vp9s(vp9s) => { Decoder::handle_vpxs_video_frame(&mut self.vp9, vp9s, rgb) } + video_frame::Union::Av1s(av1s) => { + Decoder::handle_av1s_video_frame(&mut self.av1, av1s, rgb) + } #[cfg(feature = "hwcodec")] video_frame::Union::H264s(h264s) => { if let Some(decoder) = &mut self.hw.h264 { @@ -342,7 +364,7 @@ impl Decoder { vpxs: &EncodedVideoFrames, rgb: &mut ImageRgb, ) -> ResultType { - let mut last_frame = Image::new(); + let mut last_frame = vpxcodec::Image::new(); for vpx in vpxs.frames.iter() { for frame in decoder.decode(&vpx.data)? { drop(last_frame); @@ -361,6 +383,31 @@ impl Decoder { } } + // rgb [in/out] fmt and stride must be set in ImageRgb + fn handle_av1s_video_frame( + decoder: &mut AomDecoder, + av1s: &EncodedVideoFrames, + rgb: &mut ImageRgb, + ) -> ResultType { + let mut last_frame = aom::Image::new(); + for av1 in av1s.frames.iter() { + for frame in decoder.decode(&av1.data)? { + drop(last_frame); + last_frame = frame; + } + } + for frame in decoder.flush()? { + drop(last_frame); + last_frame = frame; + } + if last_frame.is_null() { + Ok(false) + } else { + last_frame.to(rgb); + Ok(true) + } + } + // rgb [in/out] fmt and stride must be set in ImageRgb #[cfg(feature = "hwcodec")] fn handle_hw_video_frame( @@ -404,6 +451,8 @@ impl Decoder { PreferCodec::VP8 } else if codec == "vp9" { PreferCodec::VP9 + } else if codec == "av1" { + PreferCodec::AV1 } else if codec == "h264" { PreferCodec::H264 } else if codec == "h265" { diff --git a/libs/scrap/src/common/mod.rs b/libs/scrap/src/common/mod.rs index 9e73c9e20..3780c268a 100644 --- a/libs/scrap/src/common/mod.rs +++ b/libs/scrap/src/common/mod.rs @@ -41,6 +41,7 @@ pub use self::convert::*; pub const STRIDE_ALIGN: usize = 64; // commonly used in libvpx vpx_img_alloc caller pub const HW_STRIDE_ALIGN: usize = 0; // recommended by av_frame_get_buffer +pub mod aom; pub mod record; mod vpx; @@ -132,6 +133,7 @@ pub fn is_cursor_embedded() -> bool { pub enum CodecName { VP8, VP9, + AV1, H264(String), H265(String), } @@ -140,6 +142,7 @@ pub enum CodecName { pub enum CodecFormat { VP8, VP9, + AV1, H264, H265, Unknown, @@ -150,6 +153,7 @@ impl From<&VideoFrame> for CodecFormat { match it.union { Some(video_frame::Union::Vp8s(_)) => CodecFormat::VP8, Some(video_frame::Union::Vp9s(_)) => CodecFormat::VP9, + Some(video_frame::Union::Av1s(_)) => CodecFormat::AV1, Some(video_frame::Union::H264s(_)) => CodecFormat::H264, Some(video_frame::Union::H265s(_)) => CodecFormat::H265, _ => CodecFormat::Unknown, @@ -162,6 +166,7 @@ impl From<&CodecName> for CodecFormat { match value { CodecName::VP8 => Self::VP8, CodecName::VP9 => Self::VP9, + CodecName::AV1 => Self::AV1, CodecName::H264(_) => Self::H264, CodecName::H265(_) => Self::H265, } @@ -173,6 +178,7 @@ impl ToString for CodecFormat { match self { CodecFormat::VP8 => "VP8".into(), CodecFormat::VP9 => "VP9".into(), + CodecFormat::AV1 => "AV1".into(), CodecFormat::H264 => "H264".into(), CodecFormat::H265 => "H265".into(), CodecFormat::Unknown => "Unknow".into(), diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index 368ea18e5..f7f022b6e 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -844,7 +844,7 @@ impl Remote { use video_frame::Union::*; match &vf.union { Some(vf) => match vf { - Vp8s(f) | Vp9s(f) | H264s(f) | H265s(f) => f.frames.iter().any(|e| e.key), + Vp8s(f) | Vp9s(f) | Av1s(f) | H264s(f) | H265s(f) => f.frames.iter().any(|e| e.key), _ => false, }, None => false, diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 7d8cb5081..31e7f7008 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1100,8 +1100,8 @@ pub fn session_send_note(id: String, note: String) { pub fn session_alternative_codecs(id: String) -> String { if let Some(session) = SESSIONS.read().unwrap().get(&id) { - let (vp8, h264, h265) = session.alternative_codecs(); - let msg = HashMap::from([("vp8", vp8), ("h264", h264), ("h265", h265)]); + let (vp8, av1, h264, h265) = session.alternative_codecs(); + let msg = HashMap::from([("vp8", vp8), ("av1", av1), ("h264", h264), ("h265", h265)]); serde_json::ser::to_string(&msg).unwrap_or("".to_owned()) } else { String::new() diff --git a/src/server/video_service.rs b/src/server/video_service.rs index b76ee3fc6..6c42311ac 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -35,6 +35,7 @@ use hbb_common::{ #[cfg(not(windows))] use scrap::Capturer; use scrap::{ + aom::AomEncoderConfig, codec::{Encoder, EncoderCfg, HwEncoderConfig}, record::{Recorder, RecorderContext}, vpxcodec::{VpxEncoderConfig, VpxVideoCodecId}, @@ -549,6 +550,11 @@ fn run(sp: GenericService) -> ResultType<()> { num_threads: (num_cpus::get() / 2) as _, }) } + scrap::CodecName::AV1 => EncoderCfg::AOM(AomEncoderConfig { + width: c.width as _, + height: c.height as _, + bitrate: bitrate as _, + }), }; let mut encoder; diff --git a/src/ui/header.tis b/src/ui/header.tis index 0aa3c1055..00679f491 100644 --- a/src/ui/header.tis +++ b/src/ui/header.tis @@ -162,7 +162,7 @@ class Header: Reactor.Component { function renderDisplayPop() { var codecs = handler.alternative_codecs(); - var show_codec = codecs[0] || codecs[1] || codecs[2]; + var show_codec = codecs[0] || codecs[1] || codecs[2] || codecs[3]; var cursor_embedded = false; if ((pi.displays || []).length > 0) { @@ -188,8 +188,9 @@ class Header: Reactor.Component {
  • {svg_checkmark}Auto
  • {codecs[0] ?
  • {svg_checkmark}VP8
  • : ""}
  • {svg_checkmark}VP9
  • - {codecs[1] ?
  • {svg_checkmark}H264
  • : ""} - {codecs[2] ?
  • {svg_checkmark}H265
  • : ""} + {codecs[1] ?
  • {svg_checkmark}AV1
  • : ""} + {codecs[2] ?
  • {svg_checkmark}H264
  • : ""} + {codecs[3] ?
  • {svg_checkmark}H265
  • : ""} : ""}
    {!cursor_embedded &&
  • {svg_checkmark}{translate('Show remote cursor')}
  • } diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 26f7af148..4c2af77bd 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -520,9 +520,10 @@ impl SciterSession { } fn alternative_codecs(&self) -> Value { - let (vp8, h264, h265) = self.0.alternative_codecs(); + let (vp8, av1, h264, h265) = self.0.alternative_codecs(); let mut v = Value::array(0); v.push(vp8); + v.push(av1); v.push(h264); v.push(h265); v diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 8a43642d8..f6b19e8ea 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -225,16 +225,18 @@ impl Session { true } - pub fn alternative_codecs(&self) -> (bool, bool, bool) { + pub fn alternative_codecs(&self) -> (bool, bool, bool, bool) { let decoder = scrap::codec::Decoder::supported_decodings(None); let mut vp8 = decoder.ability_vp8 > 0; + let mut av1 = decoder.ability_av1 > 0; let mut h264 = decoder.ability_h264 > 0; let mut h265 = decoder.ability_h265 > 0; let enc = &self.lc.read().unwrap().supported_encoding; vp8 = vp8 && enc.vp8; + av1 = av1 && enc.av1; h264 = h264 && enc.h264; h265 = h265 && enc.h265; - (vp8, h264, h265) + (vp8, av1, h264, h265) } pub fn change_prefer_codec(&self) { From 99d3c47094be6d0864183b53dc1e872eb4742ea9 Mon Sep 17 00:00:00 2001 From: 21pages Date: Tue, 9 May 2023 11:23:38 +0800 Subject: [PATCH 3/6] remove android unused VP8/VP9 Frame Signed-off-by: 21pages --- libs/scrap/src/common/android.rs | 2 -- src/server/video_service.rs | 35 -------------------------------- 2 files changed, 37 deletions(-) diff --git a/libs/scrap/src/common/android.rs b/libs/scrap/src/common/android.rs index 36d6a8a9b..5daa872c6 100644 --- a/libs/scrap/src/common/android.rs +++ b/libs/scrap/src/common/android.rs @@ -50,8 +50,6 @@ impl crate::TraitCapturer for Capturer { pub enum Frame<'a> { RAW(&'a [u8]), - VP8(&'a [u8]), - VP9(&'a [u8]), Empty, } diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 6c42311ac..f1053c5c9 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -680,16 +680,6 @@ fn run(sp: GenericService) -> ResultType<()> { let time = now - start; let ms = (time.as_secs() * 1000 + time.subsec_millis() as u64) as i64; match frame { - scrap::Frame::VP8(data) => { - let send_conn_ids = - handle_one_frame_encoded(VpxVideoCodecId::VP8, &sp, data, ms)?; - frame_controller.set_send(now, send_conn_ids); - } - scrap::Frame::VP9(data) => { - let send_conn_ids = - handle_one_frame_encoded(VpxVideoCodecId::VP9, &sp, data, ms)?; - frame_controller.set_send(now, send_conn_ids); - } scrap::Frame::RAW(data) => { if data.len() != 0 { let send_conn_ids = @@ -876,31 +866,6 @@ fn handle_one_frame( Ok(send_conn_ids) } -#[inline] -#[cfg(any(target_os = "android", target_os = "ios"))] -pub fn handle_one_frame_encoded( - codec: VpxVideoCodecId, - sp: &GenericService, - frame: &[u8], - ms: i64, -) -> ResultType> { - sp.snapshot(|sps| { - // so that new sub and old sub share the same encoder after switch - if sps.has_subscribes() { - bail!("SWITCH"); - } - Ok(()) - })?; - let vpx_frame = EncodedVideoFrame { - data: frame.to_vec().into(), - key: true, - pts: ms, - ..Default::default() - }; - let send_conn_ids = sp.send_video_frame(scrap::VpxEncoder::create_msg(codec, vec![vpx_frame])); - Ok(send_conn_ids) -} - #[inline] fn get_original_resolution(display_name: &str, w: usize, h: usize) -> MessageField { #[cfg(all(windows, feature = "virtual_display_driver"))] From 836323c9f4e584a19161d7ebf768bbb29fa24d8e Mon Sep 17 00:00:00 2001 From: 21pages Date: Tue, 9 May 2023 11:40:33 +0800 Subject: [PATCH 4/6] aom ci and README Signed-off-by: 21pages --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flutter-build.yml | 6 +++--- .github/workflows/vcpkg-deps-linux.yml | 2 +- README.md | 8 ++++---- docs/README-AR.md | 8 ++++---- docs/README-CS.md | 8 ++++---- docs/README-DA.md | 8 ++++---- docs/README-DE.md | 8 ++++---- docs/README-EO.md | 8 ++++---- docs/README-ES.md | 8 ++++---- docs/README-FA.md | 8 ++++---- docs/README-FI.md | 8 ++++---- docs/README-FR.md | 8 ++++---- docs/README-GR.md | 8 ++++---- docs/README-HU.md | 8 ++++---- docs/README-ID.md | 8 ++++---- docs/README-IT.md | 8 ++++---- docs/README-JP.md | 8 ++++---- docs/README-KR.md | 8 ++++---- docs/README-ML.md | 8 ++++---- docs/README-NL.md | 8 ++++---- docs/README-PL.md | 8 ++++---- docs/README-PTBR.md | 8 ++++---- docs/README-RU.md | 8 ++++---- docs/README-UA.md | 8 ++++---- docs/README-VN.md | 8 ++++---- docs/README-ZH.md | 8 ++++---- 27 files changed, 102 insertions(+), 102 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46b0811c5..11cefa4e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,11 +94,11 @@ jobs: uses: lukka/run-vcpkg@v7 with: setupOnly: true - vcpkgGitCommitId: '1d4128f08e30cec31b94500840c7eca8ebc579cb' + vcpkgGitCommitId: '501db0f17ef6df184fcdbfbe0f87cde2313b6ab1' #2023.04.15 - name: Install vcpkg dependencies run: | - $VCPKG_ROOT/vcpkg install libvpx libyuv opus + $VCPKG_ROOT/vcpkg install libvpx libyuv opus aom shell: bash - name: Install Rust toolchain diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml index 051d28706..61543b8ad 100644 --- a/.github/workflows/flutter-build.yml +++ b/.github/workflows/flutter-build.yml @@ -11,9 +11,9 @@ env: LLVM_VERSION: "15.0.6" FLUTTER_VERSION: "3.7.0" TAG_NAME: "nightly" - # vcpkg version: 2022.05.10 + # vcpkg version: 2023.04.15 # for multiarch gcc compatibility - VCPKG_COMMIT_ID: "14e7bb4ae24616ec54ff6b2f6ef4e8659434ea44" + VCPKG_COMMIT_ID: "501db0f17ef6df184fcdbfbe0f87cde2313b6ab1" VERSION: "1.2.0" NDK_VERSION: "r23" #signing keys env variable checks @@ -319,7 +319,7 @@ jobs: - name: Install vcpkg dependencies run: | - $VCPKG_ROOT/vcpkg install libvpx libyuv opus + $VCPKG_ROOT/vcpkg install libvpx libyuv opus aom - name: Show version information (Rust, cargo, Clang) shell: bash diff --git a/.github/workflows/vcpkg-deps-linux.yml b/.github/workflows/vcpkg-deps-linux.yml index 8eee01011..f07621cbb 100644 --- a/.github/workflows/vcpkg-deps-linux.yml +++ b/.github/workflows/vcpkg-deps-linux.yml @@ -63,7 +63,7 @@ jobs: pushd vcpkg git reset --hard ${{ env.VCPKG_COMMIT_ID }} ./bootstrap-vcpkg.sh - ./vcpkg install libvpx libyuv opus + ./vcpkg install libvpx libyuv opus aom ;; aarch64) pushd /artifacts diff --git a/README.md b/README.md index c43bad4ef..61b848c55 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,8 @@ Please download Sciter dynamic library yourself. - Install [vcpkg](https://github.com/microsoft/vcpkg), and set `VCPKG_ROOT` env variable correctly - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/macOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/macOS: vcpkg install libvpx libyuv opus aom - run `cargo run` @@ -104,11 +104,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Fix libvpx (For Fedora) diff --git a/docs/README-AR.md b/docs/README-AR.md index 4f5769839..65a6da3d4 100644 --- a/docs/README-AR.md +++ b/docs/README-AR.md @@ -55,8 +55,8 @@ - بطريقة صحيحة `VCPKG_ROOT` env variable وأعد [vcpkg](https://github.com/microsoft/vcpkg) ثبت - - Windows: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static` - - Linux/MacOS: `vcpkg install libvpx libyuv opus` + - Windows: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static` + - Linux/MacOS: `vcpkg install libvpx libyuv opus aom` - run `cargo run` @@ -88,11 +88,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Fix libvpx (For Fedora) diff --git a/docs/README-CS.md b/docs/README-CS.md index 74c6fcb19..b3e2cb0d2 100644 --- a/docs/README-CS.md +++ b/docs/README-CS.md @@ -49,8 +49,8 @@ Varianta pro mobilní platformy používá aplikační rámec (framework) Flutte - Nainstalujte [vcpkg](https://github.com/microsoft/vcpkg), a nastavte správně proměnnou prostsředí `VCPKG_ROOT` - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - spusťte `cargo run` @@ -81,11 +81,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Oprava libvpx (pro Fedoru) diff --git a/docs/README-DA.md b/docs/README-DA.md index d7283d8ab..f17b3abfd 100644 --- a/docs/README-DA.md +++ b/docs/README-DA.md @@ -47,8 +47,8 @@ Hent venligst sciter dynamic library selv. - Installer [vcpkg](https://github.com/microsoft/vcpkg), og indstil env-variabelen "VCPKG_ROOT" korrekt - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - kør `cargo run` @@ -79,11 +79,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### libvpx rettelse (For Fedora) diff --git a/docs/README-DE.md b/docs/README-DE.md index 2c159bd07..991fa721e 100644 --- a/docs/README-DE.md +++ b/docs/README-DE.md @@ -65,8 +65,8 @@ Bitte laden Sie die dynamische Bibliothek Sciter selbst herunter. - Installieren Sie [vcpkg](https://github.com/microsoft/vcpkg) und fügen Sie die Systemumgebungsvariable `VCPKG_ROOT` hinzu - - Windows: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static` - - Linux/macOS: `vcpkg install libvpx libyuv opus` + - Windows: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static` + - Linux/macOS: `vcpkg install libvpx libyuv opus aom` - Nutzen Sie `cargo run` @@ -104,11 +104,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### libvpx reparieren (für Fedora) diff --git a/docs/README-EO.md b/docs/README-EO.md index 4bca4a793..56acb4e6c 100644 --- a/docs/README-EO.md +++ b/docs/README-EO.md @@ -45,8 +45,8 @@ La labortabla versio uzas [sciter](https://sciter.com/) por la interfaco, bonvol - Instalu [vcpkg](https://github.com/microsoft/vcpkg), kaj agordu la medivariablon `VCPKG_ROOT` korekte - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - Plenumu `cargo run` @@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Ripari libvpx (Por Fedora) diff --git a/docs/README-ES.md b/docs/README-ES.md index 66fc609fb..6c5ebd83c 100644 --- a/docs/README-ES.md +++ b/docs/README-ES.md @@ -54,8 +54,8 @@ Por favor descarga la librería dinámica de Sciter tu mismo. - Instala [vcpkg](https://github.com/microsoft/vcpkg), y configura la variable de entono `VCPKG_ROOT` correctamente. - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/Osx: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/Osx: vcpkg install libvpx libyuv opus aom - Corre `cargo run` @@ -84,11 +84,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Arregla libvpx (Para Fedora) diff --git a/docs/README-FA.md b/docs/README-FA.md index 177e3c122..a23d91930 100644 --- a/docs/README-FA.md +++ b/docs/README-FA.md @@ -52,8 +52,8 @@ - نرم افزار [vcpkg](https://github.com/microsoft/vcpkg) را نصب کنید و متغیر `VCPKG_ROOT` را به درستی تنظیم کنید. - بسته‌های vcpkg مورد نیاز را نصب کنید: - - ویندوز: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static` - - مک و لینوکس: `vcpkg install libvpx libyuv opus` + - ویندوز: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static` + - مک و لینوکس: `vcpkg install libvpx libyuv opus aom` - این دستور را اجرا کنید: `cargo run` ## [ساخت](https://rustdesk.com/docs/en/dev/build/) @@ -83,11 +83,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### رفع ایراد libvpx (برای فدورا) diff --git a/docs/README-FI.md b/docs/README-FI.md index 8674bc1b3..b99d469bb 100644 --- a/docs/README-FI.md +++ b/docs/README-FI.md @@ -45,8 +45,8 @@ Desktop-versiot käyttävät [sciter](https://sciter.com/) graafisena käyttöli - Asenna [vcpkg](https://github.com/microsoft/vcpkg), ja aseta `VCPKG_ROOT`-ympäristömuuttuja oikein - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - suorita `cargo run` @@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Korjaa libvpx (Fedora) diff --git a/docs/README-FR.md b/docs/README-FR.md index bef9b39b4..ce4c45c57 100644 --- a/docs/README-FR.md +++ b/docs/README-FR.md @@ -45,8 +45,8 @@ Les versions de bureau utilisent [sciter](https://sciter.com/) pour l'interface - Installez [vcpkg](https://github.com/microsoft/vcpkg), et définissez correctement la variable d'environnement `VCPKG_ROOT`. - - Windows : vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/Osx : vcpkg install libvpx libyuv opus + - Windows : vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/Osx : vcpkg install libvpx libyuv opus aom - Exécuter `cargo run` @@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Corriger libvpx (Pour Fedora) diff --git a/docs/README-GR.md b/docs/README-GR.md index 8ec98030d..cf9bb0f9d 100644 --- a/docs/README-GR.md +++ b/docs/README-GR.md @@ -65,8 +65,8 @@ - Εγκαταστήσετε το [vcpkg](https://github.com/microsoft/vcpkg), και ρυθμίστε σωστά την παράμετρο συστήματος `VCPKG_ROOT` - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - Εκτελέστε `cargo run` @@ -104,11 +104,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Διόρθωση libvpx (για Fedora) diff --git a/docs/README-HU.md b/docs/README-HU.md index 9582cf1c6..e70ae7aad 100644 --- a/docs/README-HU.md +++ b/docs/README-HU.md @@ -55,8 +55,8 @@ A telefonos verziók Flutter-t hasznának. Később lehetséges hogy Sciterről - Telepítsd a [vcpkg](https://github.com/microsoft/vcpkg)-t, és állítsd be a `VCPKG_ROOT` környezeti változót helyesen - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - Futtasd a `cargo run` parancsot @@ -87,11 +87,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Fixeld a libvpx-t (Fedora-n csak) diff --git a/docs/README-ID.md b/docs/README-ID.md index 702966566..2704758be 100644 --- a/docs/README-ID.md +++ b/docs/README-ID.md @@ -45,8 +45,8 @@ Versi desktop menggunakan [sciter](https://sciter.com/) untuk GUI, silahkan down - Install [vcpkg](https://github.com/microsoft/vcpkg), dan arahkan `VCPKG_ROOT` env variable dengan benar - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - jalankan `cargo run` @@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Perbaiki libvpx (Untuk Fedora) diff --git a/docs/README-IT.md b/docs/README-IT.md index 2dec27e40..be4e4d54a 100644 --- a/docs/README-IT.md +++ b/docs/README-IT.md @@ -45,8 +45,8 @@ La versione Desktop utilizza [sciter](https://sciter.com/) per la GUI, per favor - Installa [vcpkg](https://github.com/microsoft/vcpkg), e imposta correttamente la variabile d'ambiente `VCPKG_ROOT` - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - Esegui `cargo run` @@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Fix libvpx (Per Fedora) diff --git a/docs/README-JP.md b/docs/README-JP.md index fafc5ef8c..709d41547 100644 --- a/docs/README-JP.md +++ b/docs/README-JP.md @@ -51,8 +51,8 @@ RustDeskは誰からの貢献も歓迎します。 貢献するには [`docs/CON - [vcpkg](https://github.com/microsoft/vcpkg), をインストールし、 `VCPKG_ROOT` 環境変数を正しく設定します。 - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - run `cargo run` @@ -85,11 +85,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Fix libvpx (For Fedora) diff --git a/docs/README-KR.md b/docs/README-KR.md index 6f9ba2221..7c6326cc8 100644 --- a/docs/README-KR.md +++ b/docs/README-KR.md @@ -51,8 +51,8 @@ RustDesk는 모든 기여를 환영합니다. 기여하고자 한다면 [`docs/C - [vcpkg](https://github.com/microsoft/vcpkg) 설치하고 `VCPKG_ROOT` 환경변수를 정확히 설정합니다. - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - run `cargo run` @@ -83,11 +83,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Fix libvpx (For Fedora) diff --git a/docs/README-ML.md b/docs/README-ML.md index 5b4c3782a..9f3ed88a3 100644 --- a/docs/README-ML.md +++ b/docs/README-ML.md @@ -44,8 +44,8 @@ - [vcpkg](https://github.com/microsoft/vcpkg) ഇൻസ്റ്റാൾ ചെയ്ത് `VCPKG_ROOT` env വേരിയബിൾ ശരിയായി സജ്ജമാക്കുക - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - run `cargo run` @@ -74,11 +74,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### libvpx പരിഹരിക്കുക (ഫെഡോറയ്ക്ക്) diff --git a/docs/README-NL.md b/docs/README-NL.md index 8ed279b1d..2214adeac 100644 --- a/docs/README-NL.md +++ b/docs/README-NL.md @@ -63,8 +63,8 @@ Download zelf de dynamic library van Sciter. - Installeer [vcpkg](https://github.com/microsoft/vcpkg) en configureer de `VCPKG_ROOT` omgevingsvariabele op de juiste manier: - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - Voer uit: `cargo run` @@ -101,11 +101,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Fix voor libvpx (voor Fedora) diff --git a/docs/README-PL.md b/docs/README-PL.md index 0a27f94d8..f44542581 100644 --- a/docs/README-PL.md +++ b/docs/README-PL.md @@ -63,8 +63,8 @@ Wersje desktopowe używają [sciter](https://sciter.com/) dla GUI, proszę pobra - Zainstaluj [vcpkg](https://github.com/microsoft/vcpkg), i ustaw prawidłowo zmienną `VCPKG_ROOT` - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - uruchom `cargo run` @@ -99,11 +99,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Popraw libvpx (Dla Fedora) diff --git a/docs/README-PTBR.md b/docs/README-PTBR.md index 491d53154..7e8a2d2e7 100644 --- a/docs/README-PTBR.md +++ b/docs/README-PTBR.md @@ -45,8 +45,8 @@ Versões de desktop utilizam [sciter](https://sciter.com/) para a GUI, por favor - Instale [vcpkg](https://github.com/microsoft/vcpkg), e configure a variável de ambiente `VCPKG_ROOT` corretamente - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - Execute `cargo run` @@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Conserte libvpx (Para o Fedora) diff --git a/docs/README-RU.md b/docs/README-RU.md index 75bc3eb7f..282617ace 100644 --- a/docs/README-RU.md +++ b/docs/README-RU.md @@ -57,8 +57,8 @@ RustDesk приветствует вклад каждого. Ознакомьт - Установите [vcpkg](https://github.com/microsoft/vcpkg), и правильно установите переменную `VCPKG_ROOT` - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - Запустите `cargo run` @@ -87,11 +87,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Исправление libvpx (для Fedora) diff --git a/docs/README-UA.md b/docs/README-UA.md index 222da34d2..c6c8e66f6 100644 --- a/docs/README-UA.md +++ b/docs/README-UA.md @@ -67,8 +67,8 @@ RustDesk вітає внесок кожного. Дивіться [`docs/CONTRIB - Встановіть [vcpkg](https://github.com/microsoft/vcpkg), і правильно встановіть змінну `VCPKG_ROOT`. - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/MacOS: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/MacOS: vcpkg install libvpx libyuv opus aom - Запустіть `cargo run` @@ -104,11 +104,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd ... vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Виправлення libvpx (для Fedora) diff --git a/docs/README-VN.md b/docs/README-VN.md index 2f66d011d..38a5df533 100644 --- a/docs/README-VN.md +++ b/docs/README-VN.md @@ -55,8 +55,8 @@ Phiên bản cho điện thoại sử dụng Flutter. Chúng tôi sẽ chuyển - Tải và cài [vcpkg](https://github.com/microsoft/vcpkg), và đặt biến môi trường `VCPKG_ROOT` sao cho đúng. - - Đối với Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Đối với Linux/MacOS: vcpkg install libvpx libyuv opus + - Đối với Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Đối với Linux/MacOS: vcpkg install libvpx libyuv opus aom - Chạy lệnh `cargo run` @@ -87,11 +87,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### Cách sửa lỗi libvpx (Dành cho hệ điều hành Fedora) diff --git a/docs/README-ZH.md b/docs/README-ZH.md index 27c35ff57..b5ee85e72 100644 --- a/docs/README-ZH.md +++ b/docs/README-ZH.md @@ -48,8 +48,8 @@ Chat with us: [知乎](https://www.zhihu.com/people/rustdesk) | [Discord](https: - 安装[vcpkg](https://github.com/microsoft/vcpkg), 正确设置`VCPKG_ROOT`环境变量 - - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - - Linux/Osx: vcpkg install libvpx libyuv opus + - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static + - Linux/Osx: vcpkg install libvpx libyuv opus aom - 运行 `cargo run` @@ -80,11 +80,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c ```sh git clone https://github.com/microsoft/vcpkg cd vcpkg -git checkout 2021.12.01 +git checkout 2023.04.15 cd .. vcpkg/bootstrap-vcpkg.sh export VCPKG_ROOT=$HOME/vcpkg -vcpkg/vcpkg install libvpx libyuv opus +vcpkg/vcpkg install libvpx libyuv opus aom ``` ### 修复 libvpx (仅仅针对 Fedora) From a11dee30ae09882b0b80771a7143e986a110a5b6 Mon Sep 17 00:00:00 2001 From: 21pages Date: Wed, 10 May 2023 09:43:27 +0800 Subject: [PATCH 5/6] merge vpx/aom code Signed-off-by: 21pages --- libs/scrap/src/common/aom.rs | 159 ++++------------------------- libs/scrap/src/common/codec.rs | 1 + libs/scrap/src/common/mod.rs | 149 +++++++++++++++++++++++++++ libs/scrap/src/common/vpxcodec.rs | 161 ++++-------------------------- 4 files changed, 187 insertions(+), 283 deletions(-) diff --git a/libs/scrap/src/common/aom.rs b/libs/scrap/src/common/aom.rs index 2d750c8d2..40026b240 100644 --- a/libs/scrap/src/common/aom.rs +++ b/libs/scrap/src/common/aom.rs @@ -6,7 +6,8 @@ include!(concat!(env!("OUT_DIR"), "/aom_ffi.rs")); -use crate::{codec::EncoderApi, EncodeFrame, ImageFormat, ImageRgb, STRIDE_ALIGN}; +use crate::{codec::EncoderApi, EncodeFrame, STRIDE_ALIGN}; +use crate::{common::GoogleImage, generate_call_macro, generate_call_ptr_macro, Error, Result}; use hbb_common::{ anyhow::{anyhow, Context}, bytes::Bytes, @@ -15,6 +16,9 @@ use hbb_common::{ }; use std::{ptr, slice}; +generate_call_macro!(call_aom); +generate_call_ptr_macro!(call_aom_ptr); + impl Default for aom_codec_enc_cfg_t { fn default() -> Self { unsafe { std::mem::zeroed() } @@ -33,60 +37,6 @@ impl Default for aom_image_t { } } -#[derive(Debug)] -pub enum Error { - FailedCall(String), - BadPtr(String), -} - -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> { - write!(f, "{:?}", self) - } -} - -impl std::error::Error for Error {} - -pub type Result = std::result::Result; - -macro_rules! call_aom { - ($x:expr) => {{ - let result = unsafe { $x }; // original expression - let result_int = unsafe { std::mem::transmute::<_, i32>(result) }; - if result_int != 0 { - return Err(Error::FailedCall(format!( - "errcode={} {}:{}:{}:{}", - result_int, - module_path!(), - file!(), - line!(), - column!() - )) - .into()); - } - result - }}; -} - -macro_rules! call_aom_ptr { - ($x:expr) => {{ - let result = unsafe { $x }; // original expression - let result_int = unsafe { std::mem::transmute::<_, isize>(result) }; - if result_int == 0 { - return Err(Error::BadPtr(format!( - "errcode={} {}:{}:{}:{}", - result_int, - module_path!(), - file!(), - line!(), - column!() - )) - .into()); - } - result - }}; -} - #[derive(Clone, Copy, Debug)] pub struct AomEncoderConfig { pub width: u32, @@ -508,16 +458,6 @@ impl Image { self.0.is_null() } - #[inline] - pub fn width(&self) -> usize { - self.inner().d_w as _ - } - - #[inline] - pub fn height(&self) -> usize { - self.inner().d_h as _ - } - #[inline] pub fn format(&self) -> aom_img_fmt_t { self.inner().fmt @@ -527,90 +467,27 @@ impl Image { pub fn inner(&self) -> &aom_image_t { unsafe { &*self.0 } } +} +impl GoogleImage for Image { #[inline] - pub fn stride(&self, iplane: usize) -> i32 { - self.inner().stride[iplane] + fn width(&self) -> usize { + self.inner().d_w as _ } #[inline] - pub fn get_bytes_per_row(w: usize, fmt: ImageFormat, stride: usize) -> usize { - let bytes_per_pixel = match fmt { - ImageFormat::Raw => 3, - ImageFormat::ARGB | ImageFormat::ABGR => 4, - }; - // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L128 - // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L129 - (w * bytes_per_pixel + stride - 1) & !(stride - 1) - } - - // rgb [in/out] fmt and stride must be set in ImageRgb - pub fn to(&self, rgb: &mut ImageRgb) { - rgb.w = self.width(); - rgb.h = self.height(); - let bytes_per_row = Self::get_bytes_per_row(rgb.w, rgb.fmt, rgb.stride()); - rgb.raw.resize(rgb.h * bytes_per_row, 0); - let img = self.inner(); - unsafe { - match rgb.fmt() { - ImageFormat::Raw => { - super::I420ToRAW( - img.planes[0], - img.stride[0], - img.planes[1], - img.stride[1], - img.planes[2], - img.stride[2], - rgb.raw.as_mut_ptr(), - bytes_per_row as _, - self.width() as _, - self.height() as _, - ); - } - ImageFormat::ARGB => { - super::I420ToARGB( - img.planes[0], - img.stride[0], - img.planes[1], - img.stride[1], - img.planes[2], - img.stride[2], - rgb.raw.as_mut_ptr(), - bytes_per_row as _, - self.width() as _, - self.height() as _, - ); - } - ImageFormat::ABGR => { - super::I420ToABGR( - img.planes[0], - img.stride[0], - img.planes[1], - img.stride[1], - img.planes[2], - img.stride[2], - rgb.raw.as_mut_ptr(), - bytes_per_row as _, - self.width() as _, - self.height() as _, - ); - } - } - } + fn height(&self) -> usize { + self.inner().d_h as _ } #[inline] - pub fn data(&self) -> (&[u8], &[u8], &[u8]) { - unsafe { - let img = self.inner(); - let h = (img.d_h as usize + 1) & !1; - let n = img.stride[0] as usize * h; - let y = slice::from_raw_parts(img.planes[0], n); - let n = img.stride[1] as usize * (h >> 1); - let u = slice::from_raw_parts(img.planes[1], n); - let v = slice::from_raw_parts(img.planes[2], n); - (y, u, v) - } + fn stride(&self) -> Vec { + self.inner().stride.iter().map(|x| *x as i32).collect() + } + + #[inline] + fn planes(&self) -> Vec<*mut u8> { + self.inner().planes.iter().map(|p| *p as *mut u8).collect() } } diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index a54921482..03e8a19a2 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -12,6 +12,7 @@ use crate::mediacodec::{ }; use crate::{ aom::{self, AomDecoder, AomDecoderConfig, AomEncoder, AomEncoderConfig}, + common::GoogleImage, vpxcodec::{self, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, VpxVideoCodecId}, CodecName, ImageRgb, }; diff --git a/libs/scrap/src/common/mod.rs b/libs/scrap/src/common/mod.rs index 3780c268a..15e0f5147 100644 --- a/libs/scrap/src/common/mod.rs +++ b/libs/scrap/src/common/mod.rs @@ -1,5 +1,6 @@ pub use self::vpxcodec::*; use hbb_common::message_proto::{video_frame, VideoFrame}; +use std::slice; cfg_if! { if #[cfg(quartz)] { @@ -185,3 +186,151 @@ impl ToString for CodecFormat { } } } + +#[derive(Debug)] +pub enum Error { + FailedCall(String), + BadPtr(String), +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> { + write!(f, "{:?}", self) + } +} + +impl std::error::Error for Error {} + +pub type Result = std::result::Result; + +#[macro_export] +macro_rules! generate_call_macro { + ($func_name:ident) => { + macro_rules! $func_name { + ($x:expr) => {{ + let result = unsafe { $x }; + let result_int = unsafe { std::mem::transmute::<_, i32>(result) }; + if result_int != 0 { + return Err(crate::Error::FailedCall(format!( + "errcode={} {}:{}:{}:{}", + result_int, + module_path!(), + file!(), + line!(), + column!() + )) + .into()); + } + result + }}; + } + }; +} + +#[macro_export] +macro_rules! generate_call_ptr_macro { + ($func_name:ident) => { + macro_rules! $func_name { + ($x:expr) => {{ + let result = unsafe { $x }; + let result_int = unsafe { std::mem::transmute::<_, isize>(result) }; + if result_int == 0 { + return Err(crate::Error::BadPtr(format!( + "errcode={} {}:{}:{}:{}", + result_int, + module_path!(), + file!(), + line!(), + column!() + )) + .into()); + } + result + }}; + } + }; +} + +pub trait GoogleImage { + fn width(&self) -> usize; + fn height(&self) -> usize; + fn stride(&self) -> Vec; + fn planes(&self) -> Vec<*mut u8>; + fn get_bytes_per_row(w: usize, fmt: ImageFormat, stride: usize) -> usize { + let bytes_per_pixel = match fmt { + ImageFormat::Raw => 3, + ImageFormat::ARGB | ImageFormat::ABGR => 4, + }; + // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L128 + // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L129 + (w * bytes_per_pixel + stride - 1) & !(stride - 1) + } + // rgb [in/out] fmt and stride must be set in ImageRgb + fn to(&self, rgb: &mut ImageRgb) { + rgb.w = self.width(); + rgb.h = self.height(); + let bytes_per_row = Self::get_bytes_per_row(rgb.w, rgb.fmt, rgb.stride()); + rgb.raw.resize(rgb.h * bytes_per_row, 0); + let stride = self.stride(); + let planes = self.planes(); + unsafe { + match rgb.fmt() { + ImageFormat::Raw => { + super::I420ToRAW( + planes[0], + stride[0], + planes[1], + stride[1], + planes[2], + stride[2], + rgb.raw.as_mut_ptr(), + bytes_per_row as _, + self.width() as _, + self.height() as _, + ); + } + ImageFormat::ARGB => { + super::I420ToARGB( + planes[0], + stride[0], + planes[1], + stride[1], + planes[2], + stride[2], + rgb.raw.as_mut_ptr(), + bytes_per_row as _, + self.width() as _, + self.height() as _, + ); + } + ImageFormat::ABGR => { + super::I420ToABGR( + planes[0], + stride[0], + planes[1], + stride[1], + planes[2], + stride[2], + rgb.raw.as_mut_ptr(), + bytes_per_row as _, + self.width() as _, + self.height() as _, + ); + } + } + } + } + fn data(&self) -> (&[u8], &[u8], &[u8]) { + unsafe { + let stride = self.stride(); + let planes = self.planes(); + let h = (self.height() as usize + 1) & !1; + let n = stride[0] as usize * h; + let y = slice::from_raw_parts(planes[0], n); + let n = stride[1] as usize * (h >> 1); + let u = slice::from_raw_parts(planes[1], n); + let v = slice::from_raw_parts(planes[2], n); + (y, u, v) + } + } +} diff --git a/libs/scrap/src/common/vpxcodec.rs b/libs/scrap/src/common/vpxcodec.rs index 21d88ef0c..817971c60 100644 --- a/libs/scrap/src/common/vpxcodec.rs +++ b/libs/scrap/src/common/vpxcodec.rs @@ -6,14 +6,18 @@ use hbb_common::anyhow::{anyhow, Context}; use hbb_common::message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame}; use hbb_common::ResultType; -use crate::STRIDE_ALIGN; -use crate::{codec::EncoderApi, ImageFormat, ImageRgb}; +use crate::codec::EncoderApi; +use crate::{GoogleImage, STRIDE_ALIGN}; use super::vpx::{vp8e_enc_control_id::*, vpx_codec_err_t::*, *}; +use crate::{generate_call_macro, generate_call_ptr_macro, Error, Result}; use hbb_common::bytes::Bytes; use std::os::raw::{c_int, c_uint}; use std::{ptr, slice}; +generate_call_macro!(call_vpx); +generate_call_ptr_macro!(call_vpx_ptr); + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum VpxVideoCodecId { VP8, @@ -37,60 +41,6 @@ pub struct VpxDecoder { ctx: vpx_codec_ctx_t, } -#[derive(Debug)] -pub enum Error { - FailedCall(String), - BadPtr(String), -} - -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> { - write!(f, "{:?}", self) - } -} - -impl std::error::Error for Error {} - -pub type Result = std::result::Result; - -macro_rules! call_vpx { - ($x:expr) => {{ - let result = unsafe { $x }; // original expression - let result_int = unsafe { std::mem::transmute::<_, i32>(result) }; - if result_int != 0 { - return Err(Error::FailedCall(format!( - "errcode={} {}:{}:{}:{}", - result_int, - module_path!(), - file!(), - line!(), - column!() - )) - .into()); - } - result - }}; -} - -macro_rules! call_vpx_ptr { - ($x:expr) => {{ - let result = unsafe { $x }; // original expression - let result_int = unsafe { std::mem::transmute::<_, isize>(result) }; - if result_int == 0 { - return Err(Error::BadPtr(format!( - "errcode={} {}:{}:{}:{}", - result_int, - module_path!(), - file!(), - line!(), - column!() - )) - .into()); - } - result - }}; -} - impl EncoderApi for VpxEncoder { fn new(cfg: crate::codec::EncoderCfg) -> ResultType where @@ -495,16 +445,6 @@ impl Image { self.0.is_null() } - #[inline] - pub fn width(&self) -> usize { - self.inner().d_w as _ - } - - #[inline] - pub fn height(&self) -> usize { - self.inner().d_h as _ - } - #[inline] pub fn format(&self) -> vpx_img_fmt_t { // VPX_IMG_FMT_I420 @@ -515,90 +455,27 @@ impl Image { pub fn inner(&self) -> &vpx_image_t { unsafe { &*self.0 } } +} +impl GoogleImage for Image { #[inline] - pub fn stride(&self, iplane: usize) -> i32 { - self.inner().stride[iplane] + fn width(&self) -> usize { + self.inner().d_w as _ } #[inline] - pub fn get_bytes_per_row(w: usize, fmt: ImageFormat, stride: usize) -> usize { - let bytes_per_pixel = match fmt { - ImageFormat::Raw => 3, - ImageFormat::ARGB | ImageFormat::ABGR => 4, - }; - // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L128 - // https://github.com/lemenkov/libyuv/blob/6900494d90ae095d44405cd4cc3f346971fa69c9/source/convert_argb.cc#L129 - (w * bytes_per_pixel + stride - 1) & !(stride - 1) - } - - // rgb [in/out] fmt and stride must be set in ImageRgb - pub fn to(&self, rgb: &mut ImageRgb) { - rgb.w = self.width(); - rgb.h = self.height(); - let bytes_per_row = Self::get_bytes_per_row(rgb.w, rgb.fmt, rgb.stride()); - rgb.raw.resize(rgb.h * bytes_per_row, 0); - let img = self.inner(); - unsafe { - match rgb.fmt() { - ImageFormat::Raw => { - super::I420ToRAW( - img.planes[0], - img.stride[0], - img.planes[1], - img.stride[1], - img.planes[2], - img.stride[2], - rgb.raw.as_mut_ptr(), - bytes_per_row as _, - self.width() as _, - self.height() as _, - ); - } - ImageFormat::ARGB => { - super::I420ToARGB( - img.planes[0], - img.stride[0], - img.planes[1], - img.stride[1], - img.planes[2], - img.stride[2], - rgb.raw.as_mut_ptr(), - bytes_per_row as _, - self.width() as _, - self.height() as _, - ); - } - ImageFormat::ABGR => { - super::I420ToABGR( - img.planes[0], - img.stride[0], - img.planes[1], - img.stride[1], - img.planes[2], - img.stride[2], - rgb.raw.as_mut_ptr(), - bytes_per_row as _, - self.width() as _, - self.height() as _, - ); - } - } - } + fn height(&self) -> usize { + self.inner().d_h as _ } #[inline] - pub fn data(&self) -> (&[u8], &[u8], &[u8]) { - unsafe { - let img = self.inner(); - let h = (img.d_h as usize + 1) & !1; - let n = img.stride[0] as usize * h; - let y = slice::from_raw_parts(img.planes[0], n); - let n = img.stride[1] as usize * (h >> 1); - let u = slice::from_raw_parts(img.planes[1], n); - let v = slice::from_raw_parts(img.planes[2], n); - (y, u, v) - } + fn stride(&self) -> Vec { + self.inner().stride.iter().map(|x| *x as i32).collect() + } + + #[inline] + fn planes(&self) -> Vec<*mut u8> { + self.inner().planes.iter().map(|p| *p as *mut u8).collect() } } From 1ae2ebaa8c3ae028bfbd6649a861a68996aff1f5 Mon Sep 17 00:00:00 2001 From: 21pages Date: Sat, 20 May 2023 16:23:00 +0800 Subject: [PATCH 6/6] allow set config err for android Signed-off-by: 21pages --- libs/scrap/build.rs | 6 +++--- libs/scrap/src/common/aom.rs | 7 +++++-- libs/scrap/src/common/mod.rs | 12 ++++++++---- libs/scrap/src/common/vpxcodec.rs | 3 ++- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libs/scrap/build.rs b/libs/scrap/build.rs index 72fe0707a..709e64aa9 100644 --- a/libs/scrap/build.rs +++ b/libs/scrap/build.rs @@ -128,9 +128,9 @@ fn find_package(name: &str) -> Vec { let no_pkg_config_var_name = format!("NO_PKG_CONFIG_{name}"); println!("cargo:rerun-if-env-changed={no_pkg_config_var_name}"); if cfg!(all(target_os = "linux", feature = "linux-pkg-config")) - && std::env::var(no_pkg_config_var_name).as_deref() != Ok("1") { - - link_pkg_config(name) + && std::env::var(no_pkg_config_var_name).as_deref() != Ok("1") + { + link_pkg_config(name) } else if let Ok(vcpkg_root) = std::env::var("VCPKG_ROOT") { vec![link_vcpkg(vcpkg_root.into(), name)] } else { diff --git a/libs/scrap/src/common/aom.rs b/libs/scrap/src/common/aom.rs index 40026b240..b9748efda 100644 --- a/libs/scrap/src/common/aom.rs +++ b/libs/scrap/src/common/aom.rs @@ -11,12 +11,14 @@ use crate::{common::GoogleImage, generate_call_macro, generate_call_ptr_macro, E use hbb_common::{ anyhow::{anyhow, Context}, bytes::Bytes, + log, message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame}, ResultType, }; use std::{ptr, slice}; -generate_call_macro!(call_aom); +generate_call_macro!(call_aom, false); +generate_call_macro!(call_aom_allow_err, true); generate_call_ptr_macro!(call_aom_ptr); impl Default for aom_codec_enc_cfg_t { @@ -145,7 +147,7 @@ mod webrtc { use aome_enc_control_id::*; macro_rules! call_ctl { ($ctx:expr, $av1e:expr, $arg:expr) => {{ - call_aom!(aom_codec_control($ctx, $av1e as i32, $arg)); + call_aom_allow_err!(aom_codec_control($ctx, $av1e as i32, $arg)); }}; } @@ -168,6 +170,7 @@ mod webrtc { } else { AV1E_SET_TILE_COLUMNS }; + // Failed on android call_ctl!(ctx, tile_set, (cfg.g_threads as f64 * 1.0f64).log2().ceil()); call_ctl!(ctx, AV1E_SET_ROW_MT, 1); call_ctl!(ctx, AV1E_SET_ENABLE_OBMC, 0); diff --git a/libs/scrap/src/common/mod.rs b/libs/scrap/src/common/mod.rs index 15e0f5147..75e350b49 100644 --- a/libs/scrap/src/common/mod.rs +++ b/libs/scrap/src/common/mod.rs @@ -205,21 +205,25 @@ pub type Result = std::result::Result; #[macro_export] macro_rules! generate_call_macro { - ($func_name:ident) => { + ($func_name:ident, $allow_err:expr) => { macro_rules! $func_name { ($x:expr) => {{ let result = unsafe { $x }; let result_int = unsafe { std::mem::transmute::<_, i32>(result) }; if result_int != 0 { - return Err(crate::Error::FailedCall(format!( + let message = format!( "errcode={} {}:{}:{}:{}", result_int, module_path!(), file!(), line!(), column!() - )) - .into()); + ); + if $allow_err { + log::warn!("Failed to call {}, {}", stringify!($func_name), message); + } else { + return Err(crate::Error::FailedCall(message).into()); + } } result }}; diff --git a/libs/scrap/src/common/vpxcodec.rs b/libs/scrap/src/common/vpxcodec.rs index 817971c60..801527811 100644 --- a/libs/scrap/src/common/vpxcodec.rs +++ b/libs/scrap/src/common/vpxcodec.rs @@ -3,6 +3,7 @@ // https://github.com/rust-av/vpx-rs/blob/master/src/decoder.rs use hbb_common::anyhow::{anyhow, Context}; +use hbb_common::log; use hbb_common::message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame}; use hbb_common::ResultType; @@ -15,7 +16,7 @@ use hbb_common::bytes::Bytes; use std::os::raw::{c_int, c_uint}; use std::{ptr, slice}; -generate_call_macro!(call_vpx); +generate_call_macro!(call_vpx, false); generate_call_ptr_macro!(call_vpx_ptr); #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]