Merge pull request #4379 from 21pages/av1

av1 support
This commit is contained in:
RustDesk 2023-05-21 18:44:40 +08:00 committed by GitHub
commit f26bdda977
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 968 additions and 337 deletions

View File

@ -94,11 +94,11 @@ jobs:
uses: lukka/run-vcpkg@v7 uses: lukka/run-vcpkg@v7
with: with:
setupOnly: true setupOnly: true
vcpkgGitCommitId: '1d4128f08e30cec31b94500840c7eca8ebc579cb' vcpkgGitCommitId: '501db0f17ef6df184fcdbfbe0f87cde2313b6ab1' #2023.04.15
- name: Install vcpkg dependencies - name: Install vcpkg dependencies
run: | run: |
$VCPKG_ROOT/vcpkg install libvpx libyuv opus $VCPKG_ROOT/vcpkg install libvpx libyuv opus aom
shell: bash shell: bash
- name: Install Rust toolchain - name: Install Rust toolchain

View File

@ -11,9 +11,9 @@ env:
LLVM_VERSION: "15.0.6" LLVM_VERSION: "15.0.6"
FLUTTER_VERSION: "3.7.0" FLUTTER_VERSION: "3.7.0"
TAG_NAME: "nightly" TAG_NAME: "nightly"
# vcpkg version: 2022.05.10 # vcpkg version: 2023.04.15
# for multiarch gcc compatibility # for multiarch gcc compatibility
VCPKG_COMMIT_ID: "14e7bb4ae24616ec54ff6b2f6ef4e8659434ea44" VCPKG_COMMIT_ID: "501db0f17ef6df184fcdbfbe0f87cde2313b6ab1"
VERSION: "1.2.0" VERSION: "1.2.0"
NDK_VERSION: "r23" NDK_VERSION: "r23"
#signing keys env variable checks #signing keys env variable checks
@ -319,7 +319,7 @@ jobs:
- name: Install vcpkg dependencies - name: Install vcpkg dependencies
run: | run: |
$VCPKG_ROOT/vcpkg install libvpx libyuv opus $VCPKG_ROOT/vcpkg install libvpx libyuv opus aom
- name: Show version information (Rust, cargo, Clang) - name: Show version information (Rust, cargo, Clang)
shell: bash shell: bash

View File

@ -63,7 +63,7 @@ jobs:
pushd vcpkg pushd vcpkg
git reset --hard ${{ env.VCPKG_COMMIT_ID }} git reset --hard ${{ env.VCPKG_COMMIT_ID }}
./bootstrap-vcpkg.sh ./bootstrap-vcpkg.sh
./vcpkg install libvpx libyuv opus ./vcpkg install libvpx libyuv opus aom
;; ;;
aarch64) aarch64)
pushd /artifacts pushd /artifacts

View File

@ -65,8 +65,8 @@ Please download Sciter dynamic library yourself.
- Install [vcpkg](https://github.com/microsoft/vcpkg), and set `VCPKG_ROOT` env variable correctly - 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 - 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 - Linux/macOS: vcpkg install libvpx libyuv opus aom
- run `cargo run` - run `cargo run`
@ -104,11 +104,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Fix libvpx (For Fedora) ### Fix libvpx (For Fedora)

View File

@ -55,8 +55,8 @@
- بطريقة صحيحة `VCPKG_ROOT` env variable وأعد [vcpkg](https://github.com/microsoft/vcpkg) ثبت - بطريقة صحيحة `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` - 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` - Linux/MacOS: `vcpkg install libvpx libyuv opus aom`
- run `cargo run` - run `cargo run`
@ -88,11 +88,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Fix libvpx (For Fedora) ### Fix libvpx (For Fedora)

View File

@ -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` - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- spusťte `cargo run` - 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 ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Oprava libvpx (pro Fedoru) ### Oprava libvpx (pro Fedoru)

View File

@ -47,8 +47,8 @@ Hent venligst sciter dynamic library selv.
- Installer [vcpkg](https://github.com/microsoft/vcpkg), og indstil env-variabelen "VCPKG_ROOT" korrekt - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- kør `cargo run` - 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 ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### libvpx rettelse (For Fedora) ### libvpx rettelse (For Fedora)

View File

@ -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 - 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` - 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` - Linux/macOS: `vcpkg install libvpx libyuv opus aom`
- Nutzen Sie `cargo run` - 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 ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### libvpx reparieren (für Fedora) ### libvpx reparieren (für Fedora)

View File

@ -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 - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Plenumu `cargo run` - Plenumu `cargo run`
@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Ripari libvpx (Por Fedora) ### Ripari libvpx (Por Fedora)

View File

@ -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. - 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 - 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 - Linux/Osx: vcpkg install libvpx libyuv opus aom
- Corre `cargo run` - Corre `cargo run`
@ -84,11 +84,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Arregla libvpx (Para Fedora) ### Arregla libvpx (Para Fedora)

View File

@ -52,8 +52,8 @@
- نرم افزار [vcpkg](https://github.com/microsoft/vcpkg) را نصب کنید و متغیر `VCPKG_ROOT` را به درستی تنظیم کنید. - نرم افزار [vcpkg](https://github.com/microsoft/vcpkg) را نصب کنید و متغیر `VCPKG_ROOT` را به درستی تنظیم کنید.
- بسته‌های vcpkg مورد نیاز را نصب کنید: - بسته‌های vcpkg مورد نیاز را نصب کنید:
- ویندوز: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static` - ویندوز: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static`
- مک و لینوکس: `vcpkg install libvpx libyuv opus` - مک و لینوکس: `vcpkg install libvpx libyuv opus aom`
- این دستور را اجرا کنید: `cargo run` - این دستور را اجرا کنید: `cargo run`
## [ساخت](https://rustdesk.com/docs/en/dev/build/) ## [ساخت](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 ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### رفع ایراد libvpx (برای فدورا) ### رفع ایراد libvpx (برای فدورا)

View File

@ -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 - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- suorita `cargo run` - suorita `cargo run`
@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Korjaa libvpx (Fedora) ### Korjaa libvpx (Fedora)

View File

@ -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`. - 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 - 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 - Linux/Osx : vcpkg install libvpx libyuv opus aom
- Exécuter `cargo run` - 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 ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Corriger libvpx (Pour Fedora) ### Corriger libvpx (Pour Fedora)

View File

@ -65,8 +65,8 @@
- Εγκαταστήσετε το [vcpkg](https://github.com/microsoft/vcpkg), και ρυθμίστε σωστά την παράμετρο συστήματος `VCPKG_ROOT` - Εγκαταστήσετε το [vcpkg](https://github.com/microsoft/vcpkg), και ρυθμίστε σωστά την παράμετρο συστήματος `VCPKG_ROOT`
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Εκτελέστε `cargo run` - Εκτελέστε `cargo run`
@ -104,11 +104,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Διόρθωση libvpx (για Fedora) ### Διόρθωση libvpx (για Fedora)

View File

@ -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 - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Futtasd a `cargo run` parancsot - 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 ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg 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) ### Fixeld a libvpx-t (Fedora-n csak)

View File

@ -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 - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- jalankan `cargo run` - jalankan `cargo run`
@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Perbaiki libvpx (Untuk Fedora) ### Perbaiki libvpx (Untuk Fedora)

View File

@ -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` - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Esegui `cargo run` - Esegui `cargo run`
@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Fix libvpx (Per Fedora) ### Fix libvpx (Per Fedora)

View File

@ -51,8 +51,8 @@ RustDeskは誰からの貢献も歓迎します。 貢献するには [`docs/CON
- [vcpkg](https://github.com/microsoft/vcpkg), をインストールし、 `VCPKG_ROOT` 環境変数を正しく設定します。 - [vcpkg](https://github.com/microsoft/vcpkg), をインストールし、 `VCPKG_ROOT` 環境変数を正しく設定します。
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- run `cargo run` - run `cargo run`
@ -85,11 +85,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Fix libvpx (For Fedora) ### Fix libvpx (For Fedora)

View File

@ -51,8 +51,8 @@ RustDesk는 모든 기여를 환영합니다. 기여하고자 한다면 [`docs/C
- [vcpkg](https://github.com/microsoft/vcpkg) 설치하고 `VCPKG_ROOT` 환경변수를 정확히 설정합니다. - [vcpkg](https://github.com/microsoft/vcpkg) 설치하고 `VCPKG_ROOT` 환경변수를 정확히 설정합니다.
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- run `cargo run` - run `cargo run`
@ -83,11 +83,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Fix libvpx (For Fedora) ### Fix libvpx (For Fedora)

View File

@ -44,8 +44,8 @@
- [vcpkg](https://github.com/microsoft/vcpkg) ഇൻസ്റ്റാൾ ചെയ്ത് `VCPKG_ROOT` env വേരിയബിൾ ശരിയായി സജ്ജമാക്കുക - [vcpkg](https://github.com/microsoft/vcpkg) ഇൻസ്റ്റാൾ ചെയ്ത് `VCPKG_ROOT` env വേരിയബിൾ ശരിയായി സജ്ജമാക്കുക
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- run `cargo run` - run `cargo run`
@ -74,11 +74,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### libvpx പരിഹരിക്കുക (ഫെഡോറയ്ക്ക്) ### libvpx പരിഹരിക്കുക (ഫെഡോറയ്ക്ക്)

View File

@ -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: - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Voer uit: `cargo run` - 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 ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Fix voor libvpx (voor Fedora) ### Fix voor libvpx (voor Fedora)

View File

@ -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` - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- uruchom `cargo run` - uruchom `cargo run`
@ -99,11 +99,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Popraw libvpx (Dla Fedora) ### Popraw libvpx (Dla Fedora)

View File

@ -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 - 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 - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Execute `cargo run` - Execute `cargo run`
@ -75,11 +75,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Conserte libvpx (Para o Fedora) ### Conserte libvpx (Para o Fedora)

View File

@ -57,8 +57,8 @@ RustDesk приветствует вклад каждого. Ознакомьт
- Установите [vcpkg](https://github.com/microsoft/vcpkg), и правильно установите переменную `VCPKG_ROOT` - Установите [vcpkg](https://github.com/microsoft/vcpkg), и правильно установите переменную `VCPKG_ROOT`
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Запустите `cargo run` - Запустите `cargo run`
@ -87,11 +87,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Исправление libvpx (для Fedora) ### Исправление libvpx (для Fedora)

View File

@ -67,8 +67,8 @@ RustDesk вітає внесок кожного. Дивіться [`docs/CONTRIB
- Встановіть [vcpkg](https://github.com/microsoft/vcpkg), і правильно встановіть змінну `VCPKG_ROOT`. - Встановіть [vcpkg](https://github.com/microsoft/vcpkg), і правильно встановіть змінну `VCPKG_ROOT`.
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - 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 - Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Запустіть `cargo run` - Запустіть `cargo run`
@ -104,11 +104,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd ... cd ...
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### Виправлення libvpx (для Fedora) ### Виправлення libvpx (для Fedora)

View File

@ -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. - 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 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 - Đối với Linux/MacOS: vcpkg install libvpx libyuv opus aom
- Chạy lệnh `cargo run` - 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 ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg 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) ### Cách sửa lỗi libvpx (Dành cho hệ điều hành Fedora)

View File

@ -48,8 +48,8 @@ Chat with us: [知乎](https://www.zhihu.com/people/rustdesk) | [Discord](https:
- 安装[vcpkg](https://github.com/microsoft/vcpkg), 正确设置`VCPKG_ROOT`环境变量 - 安装[vcpkg](https://github.com/microsoft/vcpkg), 正确设置`VCPKG_ROOT`环境变量
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static - 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 - Linux/Osx: vcpkg install libvpx libyuv opus aom
- 运行 `cargo run` - 运行 `cargo run`
@ -80,11 +80,11 @@ sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-c
```sh ```sh
git clone https://github.com/microsoft/vcpkg git clone https://github.com/microsoft/vcpkg
cd vcpkg cd vcpkg
git checkout 2021.12.01 git checkout 2023.04.15
cd .. cd ..
vcpkg/bootstrap-vcpkg.sh vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$HOME/vcpkg export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus vcpkg/vcpkg install libvpx libyuv opus aom
``` ```
### 修复 libvpx (仅仅针对 Fedora) ### 修复 libvpx (仅仅针对 Fedora)

View File

@ -280,15 +280,18 @@ Future<List<TRadioMenu<String>>> toolbarCodec(
try { try {
final Map codecsJson = jsonDecode(alternativeCodecs); final Map codecsJson = jsonDecode(alternativeCodecs);
final vp8 = codecsJson['vp8'] ?? false; final vp8 = codecsJson['vp8'] ?? false;
final av1 = codecsJson['av1'] ?? false;
final h264 = codecsJson['h264'] ?? false; final h264 = codecsJson['h264'] ?? false;
final h265 = codecsJson['h265'] ?? false; final h265 = codecsJson['h265'] ?? false;
codecs.add(vp8); codecs.add(vp8);
codecs.add(av1);
codecs.add(h264); codecs.add(h264);
codecs.add(h265); codecs.add(h265);
} catch (e) { } catch (e) {
debugPrint("Show Codec Preference err=$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 []; if (!visible) return [];
onChanged(String? value) async { onChanged(String? value) async {
if (value == null) return; if (value == null) return;
@ -307,10 +310,11 @@ Future<List<TRadioMenu<String>>> toolbarCodec(
return [ return [
radio('Auto', 'auto', true), 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), radio('VP9', 'vp9', true),
if (isDesktop || codecs[1]) radio('H264', 'h264', codecs[1]), if (codecs[1]) radio('AV1', 'av1', codecs[1]),
if (isDesktop || codecs[2]) radio('H265', 'h265', codecs[2]), if (codecs[2]) radio('H264', 'h264', codecs[2]),
if (codecs[3]) radio('H265', 'h265', codecs[3]),
]; ];
} }

View File

@ -1322,6 +1322,11 @@ class _DisplayState extends State<_Display> {
groupValue: groupValue, groupValue: groupValue,
label: 'VP9', label: 'VP9',
onChanged: onChanged), onChanged: onChanged),
_Radio(context,
value: 'av1',
groupValue: groupValue,
label: 'AV1',
onChanged: onChanged),
...hwRadios, ...hwRadios,
]); ]);
} }

View File

@ -25,6 +25,7 @@ message VideoFrame {
EncodedVideoFrames h264s = 10; EncodedVideoFrames h264s = 10;
EncodedVideoFrames h265s = 11; EncodedVideoFrames h265s = 11;
EncodedVideoFrames vp8s = 12; EncodedVideoFrames vp8s = 12;
EncodedVideoFrames av1s = 13;
} }
} }
@ -85,6 +86,7 @@ message SupportedEncoding {
bool h264 = 1; bool h264 = 1;
bool h265 = 2; bool h265 = 2;
bool vp8 = 3; bool vp8 = 3;
bool av1 = 4;
} }
message PeerInfo { message PeerInfo {
@ -477,6 +479,7 @@ message SupportedDecoding {
H264 = 2; H264 = 2;
H265 = 3; H265 = 3;
VP8 = 4; VP8 = 4;
AV1 = 5;
} }
int32 ability_vp9 = 1; int32 ability_vp9 = 1;
@ -484,6 +487,7 @@ message SupportedDecoding {
int32 ability_h265 = 3; int32 ability_h265 = 3;
PreferCodec prefer = 4; PreferCodec prefer = 4;
int32 ability_vp8 = 5; int32 ability_vp8 = 5;
int32 ability_av1 = 6;
} }
message OptionMessage { message OptionMessage {

View File

@ -1399,7 +1399,9 @@ impl UserDefaultConfig {
"view_style" => self.get_string(key, "original", vec!["adaptive"]), "view_style" => self.get_string(key, "original", vec!["adaptive"]),
"scroll_style" => self.get_string(key, "scrollauto", vec!["scrollbar"]), "scroll_style" => self.get_string(key, "scrollauto", vec!["scrollbar"]),
"image_quality" => self.get_string(key, "balanced", vec!["best", "low", "custom"]), "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_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), "custom-fps" => self.get_double_string(key, 30.0, 5.0, 120.0),
_ => self _ => self

View File

@ -128,8 +128,8 @@ fn find_package(name: &str) -> Vec<PathBuf> {
let no_pkg_config_var_name = format!("NO_PKG_CONFIG_{name}"); let no_pkg_config_var_name = format!("NO_PKG_CONFIG_{name}");
println!("cargo:rerun-if-env-changed={no_pkg_config_var_name}"); println!("cargo:rerun-if-env-changed={no_pkg_config_var_name}");
if cfg!(all(target_os = "linux", feature = "linux-pkg-config")) if cfg!(all(target_os = "linux", feature = "linux-pkg-config"))
&& std::env::var(no_pkg_config_var_name).as_deref() != Ok("1") { && std::env::var(no_pkg_config_var_name).as_deref() != Ok("1")
{
link_pkg_config(name) link_pkg_config(name)
} else if let Ok(vcpkg_root) = std::env::var("VCPKG_ROOT") { } else if let Ok(vcpkg_root) = std::env::var("VCPKG_ROOT") {
vec![link_vcpkg(vcpkg_root.into(), name)] vec![link_vcpkg(vcpkg_root.into(), name)]
@ -144,16 +144,17 @@ fn generate_bindings(
include_paths: &[PathBuf], include_paths: &[PathBuf],
ffi_rs: &Path, ffi_rs: &Path,
exact_file: &Path, exact_file: &Path,
regex: &str,
) { ) {
let mut b = bindgen::builder() let mut b = bindgen::builder()
.header(ffi_header.to_str().unwrap()) .header(ffi_header.to_str().unwrap())
.allowlist_type("^[vV].*") .allowlist_type(regex)
.allowlist_var("^[vV].*") .allowlist_var(regex)
.allowlist_function("^[vV].*") .allowlist_function(regex)
.rustified_enum("^v.*") .rustified_enum(regex)
.trust_clang_mangling(false) .trust_clang_mangling(false)
.layout_tests(false) // breaks 32/64-bit compat .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 { for dir in include_paths {
b = b.clang_arg(format!("-I{}", dir.display())); b = b.clang_arg(format!("-I{}", dir.display()));
@ -163,22 +164,22 @@ fn generate_bindings(
fs::copy(ffi_rs, exact_file).ok(); // ignore failure fs::copy(ffi_rs, exact_file).ok(); // ignore failure
} }
fn gen_vpx() { fn gen_vcpkg_package(package: &str, ffi_header: &str, generated: &str, regex: &str) {
let includes = find_package("libvpx"); let includes = find_package(package);
let src_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); let src_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
let src_dir = Path::new(&src_dir); let src_dir = Path::new(&src_dir);
let out_dir = env::var_os("OUT_DIR").unwrap(); let out_dir = env::var_os("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir); 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()); println!("rerun-if-changed={}", ffi_header.display());
for dir in &includes { for dir in &includes {
println!("rerun-if-changed={}", dir.display()); println!("rerun-if-changed={}", dir.display());
} }
let ffi_rs = out_dir.join("vpx_ffi.rs"); let ffi_rs = out_dir.join(generated);
let exact_file = src_dir.join("generated").join("vpx_ffi.rs"); let exact_file = src_dir.join("generated").join(generated);
generate_bindings(&ffi_header, &includes, &ffi_rs, &exact_file); generate_bindings(&ffi_header, &includes, &ffi_rs, &exact_file, regex);
} }
fn main() { fn main() {
@ -194,7 +195,8 @@ fn main() {
env::set_var("CARGO_CFG_TARGET_FEATURE", "crt-static"); env::set_var("CARGO_CFG_TARGET_FEATURE", "crt-static");
find_package("libyuv"); 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 // 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(); let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();

View File

@ -1,6 +1,7 @@
use docopt::Docopt; use docopt::Docopt;
use hbb_common::env_logger::{init_from_env, Env, DEFAULT_FILTER_ENV}; use hbb_common::env_logger::{init_from_env, Env, DEFAULT_FILTER_ENV};
use scrap::{ use scrap::{
aom::{AomDecoder, AomDecoderConfig, AomEncoder, AomEncoderConfig},
codec::{EncoderApi, EncoderCfg}, codec::{EncoderApi, EncoderCfg},
Capturer, Display, TraitCapturer, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, Capturer, Display, TraitCapturer, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig,
VpxVideoCodecId::{self, *}, VpxVideoCodecId::{self, *},
@ -51,6 +52,7 @@ fn main() {
width, height, bitrate_k, args.flag_hw_pixfmt width, height, bitrate_k, args.flag_hw_pixfmt
); );
[VP8, VP9].map(|c| test_vpx(c, &yuvs, width, height, bitrate_k, yuv_count)); [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")] #[cfg(feature = "hwcodec")]
{ {
use hwcodec::AVPixelFormat; use hwcodec::AVPixelFormat;
@ -105,34 +107,29 @@ fn test_vpx(
num_threads: (num_cpus::get() / 2) as _, num_threads: (num_cpus::get() / 2) as _,
}); });
let mut encoder = VpxEncoder::new(config).unwrap(); 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 mut vpxs = vec![];
let start = Instant::now(); let start = Instant::now();
let mut size = 0;
for yuv in yuvs { for yuv in yuvs {
for ref frame in encoder for ref frame in encoder
.encode(start.elapsed().as_millis() as _, yuv, STRIDE_ALIGN) .encode(start.elapsed().as_millis() as _, yuv, STRIDE_ALIGN)
.unwrap() .unwrap()
{ {
size += frame.data.len();
vpxs.push(frame.data.to_vec()); vpxs.push(frame.data.to_vec());
} }
for ref frame in encoder.flush().unwrap() { for ref frame in encoder.flush().unwrap() {
size += frame.data.len();
vpxs.push(frame.data.to_vec()); vpxs.push(frame.data.to_vec());
} }
} }
assert_eq!(vpxs.len(), yuv_count); 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 { let mut decoder = VpxDecoder::new(VpxDecoderConfig {
codec: codec_id, codec: codec_id,
@ -151,6 +148,43 @@ fn test_vpx(
); );
} }
fn test_av1(yuvs: &Vec<Vec<u8>>, 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")] #[cfg(feature = "hwcodec")]
mod hw { mod hw {
use super::*; use super::*;
@ -221,14 +255,19 @@ mod hw {
ctx.name = info.name; ctx.name = info.name;
let mut encoder = Encoder::new(ctx.clone()).unwrap(); let mut encoder = Encoder::new(ctx.clone()).unwrap();
let start = Instant::now(); let start = Instant::now();
let mut size = 0;
for yuv in yuvs { for yuv in yuvs {
let _ = encoder.encode(yuv).unwrap(); let frames = encoder.encode(yuv).unwrap();
for frame in frames {
size += frame.data.len();
}
} }
println!( println!(
"{}{}: {:?}", "{}{}: {:?}, {} byte",
if best { "*" } else { "" }, if best { "*" } else { "" },
ctx.name, ctx.name,
start.elapsed() / yuvs.len() as _ start.elapsed() / yuvs.len() as _,
size / yuvs.len(),
); );
} }

View File

@ -0,0 +1,10 @@
#include <aom/aom.h>
#include <aom/aom_image.h>
#include <aom/aom_integer.h>
#include <aom/aom_codec.h>
#include <aom/aom_external_partition.h>
#include <aom/aom_frame_buffer.h>
#include <aom/aom_encoder.h>
#include <aom/aom_decoder.h>
#include <aom/aomcx.h>
#include <aom/aomdx.h>

View File

@ -50,8 +50,6 @@ impl crate::TraitCapturer for Capturer {
pub enum Frame<'a> { pub enum Frame<'a> {
RAW(&'a [u8]), RAW(&'a [u8]),
VP8(&'a [u8]),
VP9(&'a [u8]),
Empty, Empty,
} }

View File

@ -0,0 +1,505 @@
#![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, STRIDE_ALIGN};
use crate::{common::GoogleImage, generate_call_macro, generate_call_ptr_macro, Error, Result};
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, false);
generate_call_macro!(call_aom_allow_err, true);
generate_call_ptr_macro!(call_aom_ptr);
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(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<aom_codec_enc_cfg> {
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_allow_err!(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
};
// 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);
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<Self>
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<Message> {
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<EncodeFrames> {
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<EncodedVideoFrame>) -> 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<Self::Item> {
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<Self> {
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<DecodeFrames> {
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<DecodeFrames> {
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<Self::Item> {
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 format(&self) -> aom_img_fmt_t {
self.inner().fmt
}
#[inline]
pub fn inner(&self) -> &aom_image_t {
unsafe { &*self.0 }
}
}
impl GoogleImage for Image {
#[inline]
fn width(&self) -> usize {
self.inner().d_w as _
}
#[inline]
fn height(&self) -> usize {
self.inner().d_h as _
}
#[inline]
fn stride(&self) -> Vec<i32> {
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()
}
}
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 {}

View File

@ -10,7 +10,12 @@ use crate::hwcodec::*;
use crate::mediacodec::{ use crate::mediacodec::{
MediaCodecDecoder, MediaCodecDecoders, H264_DECODER_SUPPORT, H265_DECODER_SUPPORT, MediaCodecDecoder, MediaCodecDecoders, H264_DECODER_SUPPORT, H265_DECODER_SUPPORT,
}; };
use crate::{vpxcodec::*, CodecName, ImageRgb}; use crate::{
aom::{self, AomDecoder, AomDecoderConfig, AomEncoder, AomEncoderConfig},
common::GoogleImage,
vpxcodec::{self, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, VpxVideoCodecId},
CodecName, ImageRgb,
};
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
use hbb_common::sysinfo::{System, SystemExt}; use hbb_common::sysinfo::{System, SystemExt};
@ -43,6 +48,7 @@ pub struct HwEncoderConfig {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum EncoderCfg { pub enum EncoderCfg {
VPX(VpxEncoderConfig), VPX(VpxEncoderConfig),
AOM(AomEncoderConfig),
HW(HwEncoderConfig), HW(HwEncoderConfig),
} }
@ -79,6 +85,7 @@ impl DerefMut for Encoder {
pub struct Decoder { pub struct Decoder {
vp8: VpxDecoder, vp8: VpxDecoder,
vp9: VpxDecoder, vp9: VpxDecoder,
av1: AomDecoder,
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
hw: HwDecoders, hw: HwDecoders,
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
@ -101,6 +108,9 @@ impl Encoder {
EncoderCfg::VPX(_) => Ok(Encoder { EncoderCfg::VPX(_) => Ok(Encoder {
codec: Box::new(VpxEncoder::new(config)?), codec: Box::new(VpxEncoder::new(config)?),
}), }),
EncoderCfg::AOM(_) => Ok(Encoder {
codec: Box::new(AomEncoder::new(config)?),
}),
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
EncoderCfg::HW(_) => match HwEncoder::new(config) { EncoderCfg::HW(_) => match HwEncoder::new(config) {
@ -139,6 +149,7 @@ impl Encoder {
} }
let vp8_useable = decodings.len() > 0 && decodings.iter().all(|(_, s)| s.ability_vp8 > 0); 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)] #[allow(unused_mut)]
let mut h264_name = None; let mut h264_name = None;
#[allow(unused_mut)] #[allow(unused_mut)]
@ -167,6 +178,7 @@ impl Encoder {
.filter(|(_, s)| { .filter(|(_, s)| {
s.prefer == PreferCodec::VP9.into() s.prefer == PreferCodec::VP9.into()
|| s.prefer == PreferCodec::VP8.into() && vp8_useable || 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::H264.into() && h264_name.is_some()
|| s.prefer == PreferCodec::H265.into() && h265_name.is_some() || s.prefer == PreferCodec::H265.into() && h265_name.is_some()
}) })
@ -187,6 +199,7 @@ impl Encoder {
match preference { match preference {
PreferCodec::VP8 => *name = CodecName::VP8, PreferCodec::VP8 => *name = CodecName::VP8,
PreferCodec::VP9 => *name = CodecName::VP9, PreferCodec::VP9 => *name = CodecName::VP9,
PreferCodec::AV1 => *name = CodecName::AV1,
PreferCodec::H264 => *name = h264_name.map_or(auto_codec, |c| CodecName::H264(c)), 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::H265 => *name = h265_name.map_or(auto_codec, |c| CodecName::H265(c)),
PreferCodec::Auto => *name = auto_codec, PreferCodec::Auto => *name = auto_codec,
@ -209,6 +222,7 @@ impl Encoder {
#[allow(unused_mut)] #[allow(unused_mut)]
let mut encoding = SupportedEncoding { let mut encoding = SupportedEncoding {
vp8: true, vp8: true,
av1: true,
..Default::default() ..Default::default()
}; };
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
@ -227,6 +241,7 @@ impl Decoder {
let mut decoding = SupportedDecoding { let mut decoding = SupportedDecoding {
ability_vp8: 1, ability_vp8: 1,
ability_vp9: 1, ability_vp9: 1,
ability_av1: 1,
prefer: id_for_perfer prefer: id_for_perfer
.map_or(PreferCodec::Auto, |id| Self::codec_preference(id)) .map_or(PreferCodec::Auto, |id| Self::codec_preference(id))
.into(), .into(),
@ -267,9 +282,14 @@ impl Decoder {
num_threads: (num_cpus::get() / 2) as _, num_threads: (num_cpus::get() / 2) as _,
}) })
.unwrap(); .unwrap();
let av1 = AomDecoder::new(AomDecoderConfig {
num_threads: (num_cpus::get() / 2) as _,
})
.unwrap();
Decoder { Decoder {
vp8, vp8,
vp9, vp9,
av1,
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
hw: if enable_hwcodec_option() { hw: if enable_hwcodec_option() {
HwDecoder::new_decoders() HwDecoder::new_decoders()
@ -300,6 +320,9 @@ impl Decoder {
video_frame::Union::Vp9s(vp9s) => { video_frame::Union::Vp9s(vp9s) => {
Decoder::handle_vpxs_video_frame(&mut self.vp9, vp9s, rgb) 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")] #[cfg(feature = "hwcodec")]
video_frame::Union::H264s(h264s) => { video_frame::Union::H264s(h264s) => {
if let Some(decoder) = &mut self.hw.h264 { if let Some(decoder) = &mut self.hw.h264 {
@ -342,7 +365,7 @@ impl Decoder {
vpxs: &EncodedVideoFrames, vpxs: &EncodedVideoFrames,
rgb: &mut ImageRgb, rgb: &mut ImageRgb,
) -> ResultType<bool> { ) -> ResultType<bool> {
let mut last_frame = Image::new(); let mut last_frame = vpxcodec::Image::new();
for vpx in vpxs.frames.iter() { for vpx in vpxs.frames.iter() {
for frame in decoder.decode(&vpx.data)? { for frame in decoder.decode(&vpx.data)? {
drop(last_frame); drop(last_frame);
@ -361,6 +384,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<bool> {
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 // rgb [in/out] fmt and stride must be set in ImageRgb
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
fn handle_hw_video_frame( fn handle_hw_video_frame(
@ -404,6 +452,8 @@ impl Decoder {
PreferCodec::VP8 PreferCodec::VP8
} else if codec == "vp9" { } else if codec == "vp9" {
PreferCodec::VP9 PreferCodec::VP9
} else if codec == "av1" {
PreferCodec::AV1
} else if codec == "h264" { } else if codec == "h264" {
PreferCodec::H264 PreferCodec::H264
} else if codec == "h265" { } else if codec == "h265" {

View File

@ -1,5 +1,6 @@
pub use self::vpxcodec::*; pub use self::vpxcodec::*;
use hbb_common::message_proto::{video_frame, VideoFrame}; use hbb_common::message_proto::{video_frame, VideoFrame};
use std::slice;
cfg_if! { cfg_if! {
if #[cfg(quartz)] { if #[cfg(quartz)] {
@ -41,6 +42,7 @@ pub use self::convert::*;
pub const STRIDE_ALIGN: usize = 64; // commonly used in libvpx vpx_img_alloc caller 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 const HW_STRIDE_ALIGN: usize = 0; // recommended by av_frame_get_buffer
pub mod aom;
pub mod record; pub mod record;
mod vpx; mod vpx;
@ -132,6 +134,7 @@ pub fn is_cursor_embedded() -> bool {
pub enum CodecName { pub enum CodecName {
VP8, VP8,
VP9, VP9,
AV1,
H264(String), H264(String),
H265(String), H265(String),
} }
@ -140,6 +143,7 @@ pub enum CodecName {
pub enum CodecFormat { pub enum CodecFormat {
VP8, VP8,
VP9, VP9,
AV1,
H264, H264,
H265, H265,
Unknown, Unknown,
@ -150,6 +154,7 @@ impl From<&VideoFrame> for CodecFormat {
match it.union { match it.union {
Some(video_frame::Union::Vp8s(_)) => CodecFormat::VP8, Some(video_frame::Union::Vp8s(_)) => CodecFormat::VP8,
Some(video_frame::Union::Vp9s(_)) => CodecFormat::VP9, 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::H264s(_)) => CodecFormat::H264,
Some(video_frame::Union::H265s(_)) => CodecFormat::H265, Some(video_frame::Union::H265s(_)) => CodecFormat::H265,
_ => CodecFormat::Unknown, _ => CodecFormat::Unknown,
@ -162,6 +167,7 @@ impl From<&CodecName> for CodecFormat {
match value { match value {
CodecName::VP8 => Self::VP8, CodecName::VP8 => Self::VP8,
CodecName::VP9 => Self::VP9, CodecName::VP9 => Self::VP9,
CodecName::AV1 => Self::AV1,
CodecName::H264(_) => Self::H264, CodecName::H264(_) => Self::H264,
CodecName::H265(_) => Self::H265, CodecName::H265(_) => Self::H265,
} }
@ -173,9 +179,162 @@ impl ToString for CodecFormat {
match self { match self {
CodecFormat::VP8 => "VP8".into(), CodecFormat::VP8 => "VP8".into(),
CodecFormat::VP9 => "VP9".into(), CodecFormat::VP9 => "VP9".into(),
CodecFormat::AV1 => "AV1".into(),
CodecFormat::H264 => "H264".into(), CodecFormat::H264 => "H264".into(),
CodecFormat::H265 => "H265".into(), CodecFormat::H265 => "H265".into(),
CodecFormat::Unknown => "Unknow".into(), CodecFormat::Unknown => "Unknow".into(),
} }
} }
} }
#[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<T> = std::result::Result<T, Error>;
#[macro_export]
macro_rules! generate_call_macro {
($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 {
let message = format!(
"errcode={} {}:{}:{}:{}",
result_int,
module_path!(),
file!(),
line!(),
column!()
);
if $allow_err {
log::warn!("Failed to call {}, {}", stringify!($func_name), message);
} else {
return Err(crate::Error::FailedCall(message).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<i32>;
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)
}
}
}

View File

@ -3,17 +3,22 @@
// https://github.com/rust-av/vpx-rs/blob/master/src/decoder.rs // https://github.com/rust-av/vpx-rs/blob/master/src/decoder.rs
use hbb_common::anyhow::{anyhow, Context}; use hbb_common::anyhow::{anyhow, Context};
use hbb_common::log;
use hbb_common::message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame}; use hbb_common::message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame};
use hbb_common::ResultType; use hbb_common::ResultType;
use crate::STRIDE_ALIGN; use crate::codec::EncoderApi;
use crate::{codec::EncoderApi, ImageFormat, ImageRgb}; use crate::{GoogleImage, STRIDE_ALIGN};
use super::vpx::{vp8e_enc_control_id::*, vpx_codec_err_t::*, *}; 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 hbb_common::bytes::Bytes;
use std::os::raw::{c_int, c_uint}; use std::os::raw::{c_int, c_uint};
use std::{ptr, slice}; use std::{ptr, slice};
generate_call_macro!(call_vpx, false);
generate_call_ptr_macro!(call_vpx_ptr);
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum VpxVideoCodecId { pub enum VpxVideoCodecId {
VP8, VP8,
@ -37,60 +42,6 @@ pub struct VpxDecoder {
ctx: vpx_codec_ctx_t, 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<T> = std::result::Result<T, Error>;
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 { impl EncoderApi for VpxEncoder {
fn new(cfg: crate::codec::EncoderCfg) -> ResultType<Self> fn new(cfg: crate::codec::EncoderCfg) -> ResultType<Self>
where where
@ -495,16 +446,6 @@ impl Image {
self.0.is_null() 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] #[inline]
pub fn format(&self) -> vpx_img_fmt_t { pub fn format(&self) -> vpx_img_fmt_t {
// VPX_IMG_FMT_I420 // VPX_IMG_FMT_I420
@ -515,90 +456,27 @@ impl Image {
pub fn inner(&self) -> &vpx_image_t { pub fn inner(&self) -> &vpx_image_t {
unsafe { &*self.0 } unsafe { &*self.0 }
} }
}
impl GoogleImage for Image {
#[inline] #[inline]
pub fn stride(&self, iplane: usize) -> i32 { fn width(&self) -> usize {
self.inner().stride[iplane] self.inner().d_w as _
} }
#[inline] #[inline]
pub fn get_bytes_per_row(w: usize, fmt: ImageFormat, stride: usize) -> usize { fn height(&self) -> usize {
let bytes_per_pixel = match fmt { self.inner().d_h as _
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] #[inline]
pub fn data(&self) -> (&[u8], &[u8], &[u8]) { fn stride(&self) -> Vec<i32> {
unsafe { self.inner().stride.iter().map(|x| *x as i32).collect()
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)
} }
#[inline]
fn planes(&self) -> Vec<*mut u8> {
self.inner().planes.iter().map(|p| *p as *mut u8).collect()
} }
} }

View File

@ -844,7 +844,7 @@ impl<T: InvokeUiSession> Remote<T> {
use video_frame::Union::*; use video_frame::Union::*;
match &vf.union { match &vf.union {
Some(vf) => match vf { 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, _ => false,
}, },
None => false, None => false,

View File

@ -1100,8 +1100,8 @@ pub fn session_send_note(id: String, note: String) {
pub fn session_alternative_codecs(id: String) -> String { pub fn session_alternative_codecs(id: String) -> String {
if let Some(session) = SESSIONS.read().unwrap().get(&id) { if let Some(session) = SESSIONS.read().unwrap().get(&id) {
let (vp8, h264, h265) = session.alternative_codecs(); let (vp8, av1, h264, h265) = session.alternative_codecs();
let msg = HashMap::from([("vp8", vp8), ("h264", h264), ("h265", h265)]); let msg = HashMap::from([("vp8", vp8), ("av1", av1), ("h264", h264), ("h265", h265)]);
serde_json::ser::to_string(&msg).unwrap_or("".to_owned()) serde_json::ser::to_string(&msg).unwrap_or("".to_owned())
} else { } else {
String::new() String::new()

View File

@ -35,6 +35,7 @@ use hbb_common::{
#[cfg(not(windows))] #[cfg(not(windows))]
use scrap::Capturer; use scrap::Capturer;
use scrap::{ use scrap::{
aom::AomEncoderConfig,
codec::{Encoder, EncoderCfg, HwEncoderConfig}, codec::{Encoder, EncoderCfg, HwEncoderConfig},
record::{Recorder, RecorderContext}, record::{Recorder, RecorderContext},
vpxcodec::{VpxEncoderConfig, VpxVideoCodecId}, vpxcodec::{VpxEncoderConfig, VpxVideoCodecId},
@ -549,6 +550,11 @@ fn run(sp: GenericService) -> ResultType<()> {
num_threads: (num_cpus::get() / 2) as _, 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; let mut encoder;
@ -674,16 +680,6 @@ fn run(sp: GenericService) -> ResultType<()> {
let time = now - start; let time = now - start;
let ms = (time.as_secs() * 1000 + time.subsec_millis() as u64) as i64; let ms = (time.as_secs() * 1000 + time.subsec_millis() as u64) as i64;
match frame { 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) => { scrap::Frame::RAW(data) => {
if data.len() != 0 { if data.len() != 0 {
let send_conn_ids = let send_conn_ids =
@ -870,31 +866,6 @@ fn handle_one_frame(
Ok(send_conn_ids) 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<HashSet<i32>> {
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] #[inline]
fn get_original_resolution(display_name: &str, w: usize, h: usize) -> MessageField<Resolution> { fn get_original_resolution(display_name: &str, w: usize, h: usize) -> MessageField<Resolution> {
#[cfg(all(windows, feature = "virtual_display_driver"))] #[cfg(all(windows, feature = "virtual_display_driver"))]

View File

@ -162,7 +162,7 @@ class Header: Reactor.Component {
function renderDisplayPop() { function renderDisplayPop() {
var codecs = handler.alternative_codecs(); 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; var cursor_embedded = false;
if ((pi.displays || []).length > 0) { if ((pi.displays || []).length > 0) {
@ -188,8 +188,9 @@ class Header: Reactor.Component {
<li #auto type="codec-preference"><span>{svg_checkmark}</span>Auto</li> <li #auto type="codec-preference"><span>{svg_checkmark}</span>Auto</li>
{codecs[0] ? <li #vp8 type="codec-preference"><span>{svg_checkmark}</span>VP8</li> : ""} {codecs[0] ? <li #vp8 type="codec-preference"><span>{svg_checkmark}</span>VP8</li> : ""}
<li #vp9 type="codec-preference"><span>{svg_checkmark}</span>VP9</li> <li #vp9 type="codec-preference"><span>{svg_checkmark}</span>VP9</li>
{codecs[1] ? <li #h264 type="codec-preference"><span>{svg_checkmark}</span>H264</li> : ""} {codecs[1] ? <li #av1 type="codec-preference"><span>{svg_checkmark}</span>AV1</li> : ""}
{codecs[2] ? <li #h265 type="codec-preference"><span>{svg_checkmark}</span>H265</li> : ""} {codecs[2] ? <li #h264 type="codec-preference"><span>{svg_checkmark}</span>H264</li> : ""}
{codecs[3] ? <li #h265 type="codec-preference"><span>{svg_checkmark}</span>H265</li> : ""}
</div> : ""} </div> : ""}
<div .separator /> <div .separator />
{!cursor_embedded && <li #show-remote-cursor .toggle-option><span>{svg_checkmark}</span>{translate('Show remote cursor')}</li>} {!cursor_embedded && <li #show-remote-cursor .toggle-option><span>{svg_checkmark}</span>{translate('Show remote cursor')}</li>}

View File

@ -520,9 +520,10 @@ impl SciterSession {
} }
fn alternative_codecs(&self) -> Value { 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); let mut v = Value::array(0);
v.push(vp8); v.push(vp8);
v.push(av1);
v.push(h264); v.push(h264);
v.push(h265); v.push(h265);
v v

View File

@ -225,16 +225,18 @@ impl<T: InvokeUiSession> Session<T> {
true 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 decoder = scrap::codec::Decoder::supported_decodings(None);
let mut vp8 = decoder.ability_vp8 > 0; let mut vp8 = decoder.ability_vp8 > 0;
let mut av1 = decoder.ability_av1 > 0;
let mut h264 = decoder.ability_h264 > 0; let mut h264 = decoder.ability_h264 > 0;
let mut h265 = decoder.ability_h265 > 0; let mut h265 = decoder.ability_h265 > 0;
let enc = &self.lc.read().unwrap().supported_encoding; let enc = &self.lc.read().unwrap().supported_encoding;
vp8 = vp8 && enc.vp8; vp8 = vp8 && enc.vp8;
av1 = av1 && enc.av1;
h264 = h264 && enc.h264; h264 = h264 && enc.h264;
h265 = h265 && enc.h265; h265 = h265 && enc.h265;
(vp8, h264, h265) (vp8, av1, h264, h265)
} }
pub fn change_prefer_codec(&self) { pub fn change_prefer_codec(&self) {