diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml
index abaeb602..31f1decf 100644
--- a/.github/actions/build/action.yml
+++ b/.github/actions/build/action.yml
@@ -42,7 +42,7 @@ runs:
with:
java-version: ${{ inputs.java-version }}
distribution: 'temurin'
- server-id: ossrh
+ server-id: central
server-username: MAVEN_USERNAME
server-password: MAVEN_TOKEN
diff --git a/.github/actions/prepare-linux/action.yml b/.github/actions/prepare-linux/action.yml
new file mode 100644
index 00000000..f4faa49a
--- /dev/null
+++ b/.github/actions/prepare-linux/action.yml
@@ -0,0 +1,46 @@
+name: 'Prepare Linux Build'
+
+description: 'Frees up disk space and installs required packages for Linux builds.'
+
+runs:
+ using: "composite"
+ steps:
+ - name: Disk cleanup
+ run: |
+ set -x
+ df -h
+ #sudo du -h -d1 /usr/local
+ #sudo du -h -d1 /usr/local/share
+ #sudo du -h -d1 /usr/local/lib
+ #sudo du -h -d1 /usr/share
+ RMI=`docker images -q -a`
+ if [ -n "$RMI" ]; then
+ docker rmi $RMI
+ fi
+ # 4.6G
+ sudo rm -rf /usr/local/.ghcup
+ # 1.7G
+ sudo rm -rf /usr/share/swift
+ # 1.4G
+ sudo rm -rf /usr/share/dotnet
+ # 13G
+ sudo rm -rf /usr/local/lib/android
+ df -h
+ shell: bash
+
+ - name: Install required packages
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y pulseaudio libpulse-dev libasound2-dev libdbus-1-dev libudev-dev libv4l-dev libx11-dev libxcomposite-dev libxrandr-dev libxfixes-dev binutils cmake git locales lsb-release ninja-build pkg-config python3 python3-setuptools rsync unzip wget xz-utils
+
+ # More recent LLVM and Clang.
+ wget https://apt.llvm.org/llvm.sh
+ chmod +x llvm.sh
+ sudo ./llvm.sh ${{ matrix.llvm }} all
+
+ # Required for testing
+ #pulseaudio --start
+ sudo apt-get install -y pipewire pipewire-pulse gstreamer1.0-pipewire libspa-0.2-bluetooth libspa-0.2-jack pipewire-audio-client-libraries
+ systemctl --user daemon-reload
+ systemctl --user --now enable pipewire{,-pulse}.{socket,service}
+ shell: bash
diff --git a/.github/actions/prepare-macos/action.yml b/.github/actions/prepare-macos/action.yml
new file mode 100644
index 00000000..11db8c49
--- /dev/null
+++ b/.github/actions/prepare-macos/action.yml
@@ -0,0 +1,19 @@
+name: 'Prepare macOS Build'
+
+description: 'Installs required packages for macOS builds.'
+
+runs:
+ using: "composite"
+ steps:
+ - name: Install required packages
+ run: |
+ brew install ninja
+ # Required for macos-13
+ pip install setuptools
+ # Required for macos-14
+ brew install python-setuptools
+ shell: bash
+
+ - name: Select Xcode version
+ run: sudo xcode-select -s /Applications/Xcode_15.0.1.app/Contents/Developer
+ shell: bash
diff --git a/.github/actions/prepare-windows/action.yml b/.github/actions/prepare-windows/action.yml
new file mode 100644
index 00000000..ff9b023a
--- /dev/null
+++ b/.github/actions/prepare-windows/action.yml
@@ -0,0 +1,40 @@
+name: 'Prepare Windows Build'
+
+description: 'Frees up disk space and installs required packages for Windows builds.'
+
+runs:
+ using: "composite"
+ steps:
+ - name: Set up Python 3.11
+ if: false
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+
+ - name: Disk cleanup
+ if: false
+ run: |
+ Get-PSDrive
+ # Docker Images
+ docker rmi $(docker images -q -a)
+ # Android SDK
+ if ($Env:ANDROID_HOME) {
+ Remove-Item -Recurse -Force $Env:ANDROID_HOME -ErrorAction Ignore
+ }
+ if ($Env:ANDROID_NDK_HOME) {
+ Remove-Item -Recurse -Force $Env:ANDROID_NDK_HOME -ErrorAction Ignore
+ }
+ # JVM
+ if ($Env:JAVA_HOME_11_X64) {
+ Remove-Item -Recurse -Force $Env:JAVA_HOME_11_X64 -ErrorAction Ignore
+ }
+ if ($Env:JAVA_HOME_8_X64) {
+ Remove-Item -Recurse -Force $Env:JAVA_HOME_8_X64 -ErrorAction Ignore
+ }
+ Get-PSDrive
+ shell: powershell
+
+ - name: Install required packages
+ run: |
+ choco install ninja
+ shell: powershell
diff --git a/.github/actions/release/action.yml b/.github/actions/release/action.yml
index 399ecb5f..aa5a83fc 100644
--- a/.github/actions/release/action.yml
+++ b/.github/actions/release/action.yml
@@ -50,7 +50,7 @@ runs:
with:
java-version: ${{ inputs.java-version }}
distribution: 'temurin'
- server-id: ossrh
+ server-id: central
server-username: MAVEN_USERNAME
server-password: MAVEN_TOKEN
gpg-private-key: ${{ inputs.maven-gpg-private-key }}
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e16b1978..c812d903 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -16,7 +16,7 @@ on:
workflow_dispatch:
env:
- WEBRTC_CACHE_BRANCH: 4844
+ WEBRTC_CACHE_BRANCH: 6998
WEBRTC_CHECKOUT_FOLDER: webrtc
WEBRTC_INSTALL_FOLDER: webrtc/build
@@ -27,44 +27,16 @@ jobs:
matrix:
platform:
- name: windows_x86_64
- runs-on: windows-2019
+ runs-on: windows-2022
java: [17]
runs-on: ${{ matrix.platform.runs-on }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- - name: Set up Python 3.11
- if: false
- uses: actions/setup-python@v5
- with:
- python-version: "3.11"
-
- - name: Disk cleanup
- if: false
- run: |
- Get-PSDrive
- # Docker Images
- docker rmi $(docker images -q -a)
- # Android SDK
- if ($Env:ANDROID_HOME) {
- Remove-Item -Recurse -Force $Env:ANDROID_HOME -ErrorAction Ignore
- }
- if ($Env:ANDROID_NDK_HOME) {
- Remove-Item -Recurse -Force $Env:ANDROID_NDK_HOME -ErrorAction Ignore
- }
- # JVM
- if ($Env:JAVA_HOME_11_X64) {
- Remove-Item -Recurse -Force $Env:JAVA_HOME_11_X64 -ErrorAction Ignore
- }
- if ($Env:JAVA_HOME_8_X64) {
- Remove-Item -Recurse -Force $Env:JAVA_HOME_8_X64 -ErrorAction Ignore
- }
- Get-PSDrive
-
- - name: Install required packages
- run: |
- choco install ninja
+ - id: prepare
+ name: Prepare build
+ uses: ./.github/actions/prepare-windows
- id: maven-build
name: Maven build
@@ -81,44 +53,17 @@ jobs:
matrix:
platform:
- name: linux_x86-64
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
java: [17]
+ llvm: [21]
runs-on: ${{ matrix.platform.runs-on }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- - name: Disk cleanup
- run: |
- set -x
- df -h
- #sudo du -h -d1 /usr/local
- #sudo du -h -d1 /usr/local/share
- #sudo du -h -d1 /usr/local/lib
- #sudo du -h -d1 /usr/share
- RMI=`docker images -q -a`
- if [ -n "$RMI" ]; then
- docker rmi $RMI
- fi
- # 4.6G
- sudo rm -rf /usr/local/.ghcup
- # 1.7G
- sudo rm -rf /usr/share/swift
- # 1.4G
- sudo rm -rf /usr/share/dotnet
- # 13G
- sudo rm -rf /usr/local/lib/android
- df -h
-
- - name: Install required packages
- run: |
- sudo apt-get update
- sudo apt-get install -y pulseaudio libpulse-dev libasound2-dev libdbus-1-dev libudev-dev libv4l-dev libx11-dev libxcomposite-dev libxrandr-dev libxfixes-dev binutils cmake git locales lsb-release ninja-build pkg-config python3 python3-setuptools rsync unzip wget xz-utils
- # Required for testing
- #pulseaudio --start
- sudo apt-get install -y pipewire pipewire-pulse gstreamer1.0-pipewire libspa-0.2-bluetooth libspa-0.2-jack pipewire-audio-client-libraries
- systemctl --user daemon-reload
- systemctl --user --now enable pipewire{,-pulse}.{socket,service}
+ - id: prepare
+ name: Prepare build
+ uses: ./.github/actions/prepare-linux
- id: maven-build
name: Maven build
@@ -144,16 +89,9 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- - name: Install required packages
- run: |
- brew install ninja
- # Required for macos-13
- pip install setuptools
- # Required for macos-14
- brew install python-setuptools
-
- - name: Select Xcode version
- run: sudo xcode-select -s /Applications/Xcode_15.0.1.app/Contents/Developer
+ - id: prepare-build
+ name: Prepare build
+ uses: ./.github/actions/prepare-macos
- id: maven-build
name: Maven build
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ceee83a6..834393f4 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,48 +12,27 @@ on:
default: "X.Y.Z-SNAPSHOT"
env:
- WEBRTC_CACHE_BRANCH: 4844
+ WEBRTC_CACHE_BRANCH: 6998
WEBRTC_CHECKOUT_FOLDER: webrtc
WEBRTC_INSTALL_FOLDER: webrtc/build
jobs:
prepare-release:
- runs-on: ubuntu-20.04
+ strategy:
+ matrix:
+ llvm: [ 21 ]
+ runs-on: ubuntu-22.04
steps:
- - name: Disk cleanup
- run: |
- set -x
- df -h
- #sudo du -h -d1 /usr/local
- #sudo du -h -d1 /usr/local/share
- #sudo du -h -d1 /usr/local/lib
- #sudo du -h -d1 /usr/share
- # 4.6G
- sudo rm -rf /usr/local/.ghcup
- # 1.7G
- sudo rm -rf /usr/share/swift
- # 1.4G
- sudo rm -rf /usr/share/dotnet
- # 13G
- sudo rm -rf /usr/local/lib/android
- df -h
-
- - name: Install required packages
- run: |
- sudo apt-get update
- sudo apt-get install -y pulseaudio libpulse-dev libasound2-dev libdbus-1-dev libudev-dev libv4l-dev libx11-dev libxcomposite-dev libxrandr-dev libxfixes-dev binutils cmake git locales lsb-release ninja-build pkg-config python3 python3-setuptools rsync unzip wget xz-utils
- # Required for testing
- pulseaudio --start
- #sudo apt-get install -y pipewire pipewire-pulse gstreamer1.0-pipewire libspa-0.2-bluetooth libspa-0.2-jack pipewire-audio-client-libraries
- #systemctl --user daemon-reload
- #systemctl --user --now enable pipewire{,-pulse}.{socket,service}
+ - id: prepare
+ name: Prepare release build
+ uses: ./.github/actions/prepare-linux
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- server-id: ossrh
+ server-id: central
server-username: MAVEN_USERNAME
server-password: MAVEN_TOKEN
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
@@ -79,7 +58,7 @@ jobs:
matrix:
platform:
- name: windows_x86_64
- runs-on: windows-2019
+ runs-on: windows-2022
java: [17]
runs-on: ${{ matrix.platform.runs-on }}
steps:
@@ -97,37 +76,9 @@ jobs:
echo "tag=$tag" >> "$GITHUB_OUTPUT"
git checkout $tag
- - name: Set up Python 3.11
- if: false
- uses: actions/setup-python@v5
- with:
- python-version: "3.11"
-
- - name: Disk cleanup
- if: false
- run: |
- Get-PSDrive
- # Docker Images
- docker rmi $(docker images -q -a)
- # Android SDK
- if ($Env:ANDROID_HOME) {
- Remove-Item -Recurse -Force $Env:ANDROID_HOME -ErrorAction Ignore
- }
- if ($Env:ANDROID_NDK_HOME) {
- Remove-Item -Recurse -Force $Env:ANDROID_NDK_HOME -ErrorAction Ignore
- }
- # JVM
- if ($Env:JAVA_HOME_11_X64) {
- Remove-Item -Recurse -Force $Env:JAVA_HOME_11_X64 -ErrorAction Ignore
- }
- if ($Env:JAVA_HOME_8_X64) {
- Remove-Item -Recurse -Force $Env:JAVA_HOME_8_X64 -ErrorAction Ignore
- }
- Get-PSDrive
-
- - name: Install required packages
- run: |
- choco install ninja
+ - id: prepare
+ name: Prepare release build
+ uses: ./.github/actions/prepare-windows
- id: maven-build
name: Maven build
@@ -147,8 +98,9 @@ jobs:
matrix:
platform:
- name: linux_x86-64
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
java: [17]
+ llvm: [21]
runs-on: ${{ matrix.platform.runs-on }}
steps:
- name: Checkout code
@@ -164,37 +116,9 @@ jobs:
echo "tag=$tag" >> "$GITHUB_OUTPUT"
git checkout $tag
- - name: Disk cleanup
- run: |
- set -x
- df -h
- #sudo du -h -d1 /usr/local
- #sudo du -h -d1 /usr/local/share
- #sudo du -h -d1 /usr/local/lib
- #sudo du -h -d1 /usr/share
- RMI=`docker images -q -a`
- if [ -n "$RMI" ]; then
- docker rmi $RMI
- fi
- # 4.6G
- sudo rm -rf /usr/local/.ghcup
- # 1.7G
- sudo rm -rf /usr/share/swift
- # 1.4G
- sudo rm -rf /usr/share/dotnet
- # 13G
- sudo rm -rf /usr/local/lib/android
- df -h
-
- - name: Install required packages
- run: |
- sudo apt-get update
- sudo apt-get install -y pulseaudio libpulse-dev libasound2-dev libdbus-1-dev libudev-dev libv4l-dev libx11-dev libxcomposite-dev libxrandr-dev libxfixes-dev binutils cmake git locales lsb-release ninja-build pkg-config python3 python3-setuptools rsync unzip wget xz-utils
- # Required for testing
- pulseaudio --start
- #sudo apt-get install -y pipewire pipewire-pulse gstreamer1.0-pipewire libspa-0.2-bluetooth libspa-0.2-jack pipewire-audio-client-libraries
- #systemctl --user daemon-reload
- #systemctl --user --now enable pipewire{,-pulse}.{socket,service}
+ - id: prepare-build
+ name: Prepare release build
+ uses: ./.github/actions/prepare-linux
- name: Create Release # Create the release only once on Linux
uses: actions/create-release@v1
@@ -243,16 +167,9 @@ jobs:
echo "tag=$tag" >> "$GITHUB_OUTPUT"
git checkout $tag
- - name: Install required packages
- run: |
- brew install ninja
- # Required for macos-13
- pip install setuptools
- # Required for macos-14
- brew install python-setuptools
-
- - name: Select Xcode version
- run: sudo xcode-select -s /Applications/Xcode_15.0.1.app/Contents/Developer
+ - id: prepare-build
+ name: Prepare release build
+ uses: ./.github/actions/prepare-macos
- id: maven-build
name: Maven build
diff --git a/.gitignore b/.gitignore
index a2306aad..624afc12 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-# Eclipse Core
+# Eclipse Core
**/.classpath
**/.project
**/.settings/
diff --git a/README.md b/README.md
index c63f85dd..7e934629 100644
--- a/README.md
+++ b/README.md
@@ -32,24 +32,36 @@ Maven Central artifacts contain native libraries that can be loaded on the follo
- | Linux |
- x86_64, arm64, arm32 |
+ |
+ x64 |
+ arm |
+ arm64 |
-
- | macOS |
- x86_64, arm64 |
+
+ | Linux |
+ ✔ |
+ - |
+ - |
-
- | Windows |
- x86_64 |
+
+ | macOS |
+ ✔ |
+ - |
+ ✔ |
+
+
+ | Windows |
+ ✔ |
+ - |
+ - |
-The native libraries were build with WebRTC branch M99/4844.
+The native libraries were built with WebRTC branch M134/6998.
### Build Notes
-In order to build the native code, be sure to install the prerequisite software (follow the links):
+To build the native code, be sure to install the prerequisite software (follow the links):
**Note**: You don't have to install the Depot Tools, the build script will do that for you.
@@ -74,12 +86,12 @@ Assuming you have all the prerequisites installed for your OS, run:
mvn install
```
-On the first run, the WebRTC source tree will be loaded into the `//webrtc` directory. This will take a while and require about 18 GB of disk space.
+On the first run, the WebRTC source tree will be loaded into the `//webrtc` directory. This will take a while and require about 20 GB of disk space.
#### Build Parameters
| Parameter | Description | Default Value |
| ------------------ | ------------------------------------------------------ |-----------------------------|
-| webrtc.branch | The WebRTC branch to checkout. | branch-heads/4844 |
+| webrtc.branch | The WebRTC branch to checkout. | branch-heads/6997 |
| webrtc.src.dir | The absolute checkout path for the WebRTC source tree. | /\/webrtc |
| webrtc.install.dir | The install path for the compiled WebRTC library. Is also used to link against a pre-compiled WebRTC library to reduce build time. | /\/webrtc/build |
diff --git a/pom.xml b/pom.xml
index 03ef0e9f..1a70d805 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,17 +43,6 @@
HEAD
-
-
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
-
-
- ossrh
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
-
-
-
${maven.build.timestamp}
UTF-8
@@ -111,10 +100,22 @@
true
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.7.0
+ true
+
+ central
+
+ webrtc-java-jni
+
+
+
org.apache.maven.plugins
maven-deploy-plugin
- 3.0.0-M1
+ 3.1.4
org.apache.maven.plugins
@@ -238,6 +239,10 @@
org.apache.maven.plugins
maven-compiler-plugin
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+
diff --git a/webrtc-jni/pom.xml b/webrtc-jni/pom.xml
index cc86b5a3..9918ff96 100644
--- a/webrtc-jni/pom.xml
+++ b/webrtc-jni/pom.xml
@@ -1,187 +1,190 @@
-
-
- 4.0.0
-
-
- dev.onvoid.webrtc
- webrtc-java-parent
- 0.11.0-SNAPSHOT
-
-
- webrtc-java-jni
- pom
-
-
- branch-heads/4844
- ${user.home}/webrtc
- ${user.home}/webrtc/build
- Release
-
-
-
-
- webrtc-java-${project.version}
-
-
-
- org.apache.maven.plugins
- maven-deploy-plugin
-
- true
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
-
-
- prepare-package
-
- jar
-
-
- ${platform.classifier}
- ${project.build.directory}/lib
-
- false
-
- ${platform.module}
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-install-plugin
-
- true
-
-
-
- install-classifier
- package
-
- install-file
-
-
- ${project.build.directory}/webrtc-java-${project.version}-${platform.classifier}.jar
- ${platform.classifier}
- ${project.groupId}
- webrtc-java
- ${project.version}
- jar
- false
-
-
-
-
-
- com.googlecode.cmake-maven-project
- cmake-maven-plugin
- 3.22.1-b1
-
-
- cmake-generate
- generate-resources
-
- generate
-
-
- src/main/cpp
- ${project.build.directory}/${platform.classifier}
-
-
-
-
-
-
-
-
-
-
-
-
- cmake-compile
- generate-resources
-
- compile
-
-
- ${cmake.config}
- install
- ${project.build.directory}/${platform.classifier}
-
-
-
-
-
-
-
-
-
- windows-x86_64
-
-
- windows
- amd64
-
-
-
- -Ax64
- ${cmake.build.type}
-
-
-
- linux-x86_64
-
-
- linux
- amd64
-
-
-
- toolchain/x86_64-linux-gnu.cmake
-
-
-
- linux-aarch32
-
-
- linux
- aarch32
-
-
-
- toolchain/aarch32-linux-gnu.cmake
-
-
-
- linux-aarch64
-
-
- linux
- aarch64
-
-
-
- toolchain/aarch64-linux-gnu.cmake
-
-
-
-
+
+
+ 4.0.0
+
+
+ dev.onvoid.webrtc
+ webrtc-java-parent
+ 0.11.0-SNAPSHOT
+
+
+ webrtc-java-jni
+ pom
+
+
+ branch-heads/6998
+ ${user.home}/webrtc
+ ${user.home}/webrtc/build
+ Release
+
+
+
+
+
+ webrtc-java-${project.version}
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ prepare-package
+
+ jar
+
+
+ ${platform.classifier}
+ ${project.build.directory}/lib
+
+ false
+
+ ${platform.module}
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+
+ true
+
+
+
+ install-classifier
+ package
+
+ install-file
+
+
+ ${project.build.directory}/webrtc-java-${project.version}-${platform.classifier}.jar
+ ${platform.classifier}
+ ${project.groupId}
+ webrtc-java
+ ${project.version}
+ jar
+ false
+
+
+
+
+
+ com.googlecode.cmake-maven-project
+ cmake-maven-plugin
+ 3.22.1-b1
+
+
+ cmake-generate
+ generate-resources
+
+ generate
+
+
+ src/main/cpp
+ ${project.build.directory}/${platform.classifier}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ cmake-compile
+ generate-resources
+
+ compile
+
+
+ ${cmake.config}
+ install
+ ${project.build.directory}/${platform.classifier}
+
+
+
+
+
+
+
+
+
+ windows-x86_64
+
+
+ windows
+ amd64
+
+
+
+ -Ax64
+ ${cmake.build.type}
+
+
+
+ windows-clang
+
+ -T ClangCL
+
+
+
+ linux-x86_64
+
+
+ linux
+ amd64
+
+
+
+ toolchain/x86_64-linux-gnu.cmake
+
+
+
+ linux-aarch32
+
+
+ linux
+ aarch32
+
+
+
+ toolchain/aarch32-linux-gnu.cmake
+
+
+
+ linux-aarch64
+
+
+ linux
+ aarch64
+
+
+
+ toolchain/aarch64-linux-gnu.cmake
+
+
+
+
diff --git a/webrtc-jni/src/main/cpp/CMakeLists.txt b/webrtc-jni/src/main/cpp/CMakeLists.txt
index 6529fa13..7b2d0a7b 100644
--- a/webrtc-jni/src/main/cpp/CMakeLists.txt
+++ b/webrtc-jni/src/main/cpp/CMakeLists.txt
@@ -25,6 +25,10 @@ elseif(WIN32)
set(SOURCE_TARGET windows)
endif()
+if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /showFilenames")
+endif()
+
add_subdirectory(dependencies/webrtc)
add_subdirectory(dependencies/jni-voithos)
@@ -65,7 +69,7 @@ target_include_directories(${PROJECT_NAME}
)
set_target_properties(${PROJECT_NAME} PROPERTIES
- CXX_STANDARD 17
+ CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
)
@@ -75,11 +79,11 @@ target_link_libraries(${PROJECT_NAME} webrtc)
if(APPLE)
set_source_files_properties(${SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c++")
- target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreMedia" "-framework CoreAudio")
+ target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreMedia" "-framework CoreAudio" "-framework IOKit")
elseif(LINUX)
target_link_libraries(${PROJECT_NAME} -static-libgcc -static-libstdc++ pulse udev)
elseif(WIN32)
- target_link_libraries(${PROJECT_NAME} mf.lib mfreadwrite.lib mfplat.lib mfuuid.lib)
+ target_link_libraries(${PROJECT_NAME} dwmapi.lib mf.lib mfreadwrite.lib mfplat.lib mfuuid.lib shcore.lib)
endif()
install(TARGETS ${PROJECT_NAME}
diff --git a/webrtc-jni/src/main/cpp/dependencies/jni-voithos/include/JavaDimension.h b/webrtc-jni/src/main/cpp/dependencies/jni-voithos/include/JavaDimension.h
index 43f5d440..d8b73e55 100644
--- a/webrtc-jni/src/main/cpp/dependencies/jni-voithos/include/JavaDimension.h
+++ b/webrtc-jni/src/main/cpp/dependencies/jni-voithos/include/JavaDimension.h
@@ -25,8 +25,6 @@ namespace jni
private:
jclass cls;
jmethodID ctor;
- jfieldID width;
- jfieldID height;
};
}
diff --git a/webrtc-jni/src/main/cpp/dependencies/jni-voithos/include/JavaRectangle.h b/webrtc-jni/src/main/cpp/dependencies/jni-voithos/include/JavaRectangle.h
index 95216e9f..fd059c7d 100644
--- a/webrtc-jni/src/main/cpp/dependencies/jni-voithos/include/JavaRectangle.h
+++ b/webrtc-jni/src/main/cpp/dependencies/jni-voithos/include/JavaRectangle.h
@@ -25,10 +25,6 @@ namespace jni
private:
jclass cls;
jmethodID ctor;
- jfieldID x;
- jfieldID y;
- jfieldID width;
- jfieldID height;
};
}
diff --git a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt
index d7353f09..06d95c01 100644
--- a/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt
+++ b/webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt
@@ -122,6 +122,8 @@ set(WEBRTC_BUILD out/${TARGET_CPU})
set(WEBRTC_LIB_PATH ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/${WEBRTC_LIB})
set(WEBRTC_LIB_PATH_INSTALLED ${WEBRTC_INSTALL_DIR}/lib/${WEBRTC_LIB})
+set(WEBRTC_CLANG "true")
+
file(TO_CMAKE_PATH "${WEBRTC_DIR}" WEBRTC_DIR)
file(TO_CMAKE_PATH "${WEBRTC_INSTALL_DIR}" WEBRTC_INSTALL_DIR)
file(TO_CMAKE_PATH "${WEBRTC_LIB_PATH}" WEBRTC_LIB_PATH)
@@ -151,8 +153,11 @@ target_link_libraries(${PROJECT_NAME} ${TARGET_LINK_LIB})
if(APPLE)
target_compile_definitions(${PROJECT_NAME} PUBLIC WEBRTC_MAC WEBRTC_POSIX)
- target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreGraphics" "-framework CoreAudio" "-framework AudioToolbox" "-framework IOSurface" "-framework ApplicationServices" "-framework AppKit")
+ target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreGraphics" "-framework CoreAudio" "-framework CoreVideo" "-framework ScreenCaptureKit" "-framework AudioToolbox" "-framework IOSurface" "-framework ApplicationServices" "-framework AppKit")
elseif(LINUX)
+ # Due to branch 6998 (m134) build with gcc. Linking webrtc built with clang causes errors.
+ set(WEBRTC_CLANG "false")
+
# Find DBus
find_package(PkgConfig QUIET REQUIRED) # Include functions provided by PkgConfig module.
pkg_check_modules(DBUS REQUIRED dbus-1)
@@ -161,7 +166,7 @@ elseif(LINUX)
target_compile_definitions(${PROJECT_NAME} PUBLIC WEBRTC_LINUX WEBRTC_POSIX)
target_link_libraries(${PROJECT_NAME} X11 Xfixes Xrandr Xcomposite dbus-1)
elseif(WIN32)
- target_compile_definitions(${PROJECT_NAME} PUBLIC WEBRTC_WIN NOMINMAX WIN32_LEAN_AND_MEAN)
+ target_compile_definitions(${PROJECT_NAME} PUBLIC WEBRTC_WIN NOMINMAX WIN32_LEAN_AND_MEAN NDEBUG)
target_link_libraries(${PROJECT_NAME} D3D11 DXGI user32 gdi32 iphlpapi dmoguids msdmo secur32 strmiids winmm wmcodecdspuuid ws2_32)
endif()
@@ -237,7 +242,7 @@ if (PATCHES)
endif()
message(STATUS "WebRTC: generate")
-set(COMPILE_ARGS "is_debug=false target_cpu=\"${TARGET_CPU}\" treat_warnings_as_errors=false rtc_build_examples=false rtc_include_tests=false use_rtti=true use_custom_libcxx=false symbol_level=0 rtc_use_h264=true")
+set(COMPILE_ARGS "target_cpu=\"${TARGET_CPU}\" is_clang=${WEBRTC_CLANG} is_debug=false is_component_build=false treat_warnings_as_errors=false rtc_build_tools=false rtc_use_perfetto=false rtc_use_pipewire=false rtc_enable_protobuf=false rtc_build_examples=false rtc_include_tests=false use_rtti=true rtc_use_h264=true use_custom_libcxx=false symbol_level=0")
execute_command(
COMMAND gn gen ${WEBRTC_BUILD} --args=${COMPILE_ARGS}
WORKING_DIRECTORY "${WEBRTC_SRC}"
@@ -259,6 +264,7 @@ install(
DESTINATION "${WEBRTC_INSTALL_DIR}/include"
FILES_MATCHING
PATTERN "*.h"
+ PATTERN "*.inc"
REGEX /src/base/ EXCLUDE
REGEX /src/build/ EXCLUDE
REGEX /src/build_overrides/ EXCLUDE
diff --git a/webrtc-jni/src/main/cpp/include/JNI_AudioResampler.h b/webrtc-jni/src/main/cpp/include/JNI_AudioResampler.h
index 6f61f414..d667248e 100644
--- a/webrtc-jni/src/main/cpp/include/JNI_AudioResampler.h
+++ b/webrtc-jni/src/main/cpp/include/JNI_AudioResampler.h
@@ -25,19 +25,11 @@ extern "C" {
/*
* Class: dev_onvoid_webrtc_media_audio_AudioResampler
- * Method: resetInternal
- * Signature: (III)V
- */
- JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_resetInternal
- (JNIEnv*, jobject, jint, jint, jint);
-
- /*
- * Class: dev_onvoid_webrtc_media_audio_AudioResampler
- * Method: resampleInternal
- * Signature: ([BI[BI)I
+ * Method: resample
+ * Signature: ([BI[BII)I
*/
JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_resampleInternal
- (JNIEnv*, jobject, jbyteArray, jint, jbyteArray, jint);
+ (JNIEnv*, jobject, jbyteArray, jint, jbyteArray, jint, jint);
#ifdef __cplusplus
}
diff --git a/webrtc-jni/src/main/cpp/include/JNI_DesktopCapturer.h b/webrtc-jni/src/main/cpp/include/JNI_DesktopCapturer.h
index eae2112a..a9e46aeb 100644
--- a/webrtc-jni/src/main/cpp/include/JNI_DesktopCapturer.h
+++ b/webrtc-jni/src/main/cpp/include/JNI_DesktopCapturer.h
@@ -39,6 +39,14 @@ extern "C" {
JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_desktop_DesktopCapturer_setFocusSelectedSource
(JNIEnv*, jobject, jboolean);
+ /*
+ * Class: dev_onvoid_webrtc_media_video_desktop_DesktopCapturer
+ * Method: setMaxFrameRate
+ * Signature: (I)V
+ */
+ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_desktop_DesktopCapturer_setMaxFrameRate
+ (JNIEnv*, jobject, jint);
+
/*
* Class: dev_onvoid_webrtc_media_video_desktop_DesktopCapturer
* Method: start
diff --git a/webrtc-jni/src/main/cpp/include/JNI_VoiceActivityDetector.h b/webrtc-jni/src/main/cpp/include/JNI_VoiceActivityDetector.h
new file mode 100644
index 00000000..ccda4ddd
--- /dev/null
+++ b/webrtc-jni/src/main/cpp/include/JNI_VoiceActivityDetector.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class dev_onvoid_webrtc_media_audio_VoiceActivityDetector */
+
+#ifndef _Included_dev_onvoid_webrtc_media_audio_VoiceActivityDetector
+#define _Included_dev_onvoid_webrtc_media_audio_VoiceActivityDetector
+#ifdef __cplusplus
+extern "C" {
+#endif
+ /*
+ * Class: dev_onvoid_webrtc_media_audio_VoiceActivityDetector
+ * Method: process
+ * Signature: ([BII)V
+ */
+ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_VoiceActivityDetector_process
+ (JNIEnv *, jobject, jbyteArray, jint, jint);
+
+ /*
+ * Class: dev_onvoid_webrtc_media_audio_VoiceActivityDetector
+ * Method: getLastVoiceProbability
+ * Signature: ()F
+ */
+ JNIEXPORT jfloat JNICALL Java_dev_onvoid_webrtc_media_audio_VoiceActivityDetector_getLastVoiceProbability
+ (JNIEnv *, jobject);
+
+ /*
+ * Class: dev_onvoid_webrtc_media_audio_VoiceActivityDetector
+ * Method: dispose
+ * Signature: ()V
+ */
+ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_VoiceActivityDetector_dispose
+ (JNIEnv *, jobject);
+
+ /*
+ * Class: dev_onvoid_webrtc_media_audio_VoiceActivityDetector
+ * Method: initialize
+ * Signature: ()V
+ */
+ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_VoiceActivityDetector_initialize
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/include/api/RTCRtpContributingSource.h b/webrtc-jni/src/main/cpp/include/api/RTCRtpContributingSource.h
index 5014fc3c..07cccd88 100644
--- a/webrtc-jni/src/main/cpp/include/api/RTCRtpContributingSource.h
+++ b/webrtc-jni/src/main/cpp/include/api/RTCRtpContributingSource.h
@@ -1,49 +1,50 @@
-/*
- * Copyright 2019 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef JNI_WEBRTC_API_RTC_RTP_CONTRIBUTING_SOURCE_H_
-#define JNI_WEBRTC_API_RTC_RTP_CONTRIBUTING_SOURCE_H_
-
-#include "JavaClass.h"
-#include "JavaRef.h"
-
-#include "api/transport/rtp/rtp_source.h"
-
-#include
-
-namespace jni
-{
- namespace RTCRtpContributingSource
- {
- class JavaRTCRtpContributingSourceClass : public JavaClass
- {
- public:
- explicit JavaRTCRtpContributingSourceClass(JNIEnv * env);
-
- jclass cls;
- jmethodID ctor;
- jfieldID timestamp;
- jfieldID source;
- jfieldID audioLevel;
- jfieldID rtpTimestamp;
- };
-
- JavaLocalRef toJava(JNIEnv * env, const webrtc::RtpSource & source);
- webrtc::RtpSource toNative(JNIEnv * env, const JavaRef & source);
- }
-}
-
+/*
+ * Copyright 2019 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JNI_WEBRTC_API_RTC_RTP_CONTRIBUTING_SOURCE_H_
+#define JNI_WEBRTC_API_RTC_RTP_CONTRIBUTING_SOURCE_H_
+
+#include "JavaClass.h"
+#include "JavaRef.h"
+
+#include "api/transport/rtp/rtp_source.h"
+
+#include
+
+namespace jni
+{
+ namespace RTCRtpContributingSource
+ {
+ class JavaRTCRtpContributingSourceClass : public JavaClass
+ {
+ public:
+ explicit JavaRTCRtpContributingSourceClass(JNIEnv * env);
+
+ jclass cls;
+ jmethodID ctor;
+ jfieldID timestamp;
+ jfieldID sourceId;
+ jfieldID sourceType;
+ jfieldID audioLevel;
+ jfieldID rtpTimestamp;
+ };
+
+ JavaLocalRef toJava(JNIEnv * env, const webrtc::RtpSource & source);
+ webrtc::RtpSource toNative(JNIEnv * env, const JavaRef & source);
+ }
+}
+
#endif
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/include/api/RTCStats.h b/webrtc-jni/src/main/cpp/include/api/RTCStats.h
index ad45ccf2..deae15bf 100644
--- a/webrtc-jni/src/main/cpp/include/api/RTCStats.h
+++ b/webrtc-jni/src/main/cpp/include/api/RTCStats.h
@@ -1,67 +1,67 @@
-/*
- * Copyright 2019 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef JNI_WEBRTC_API_RTC_STATS_H_
-#define JNI_WEBRTC_API_RTC_STATS_H_
-
-#include "JavaClass.h"
-#include "JavaRef.h"
-
-#include "api/stats/rtc_stats_report.h"
-
-#include
-
-namespace jni
-{
- namespace RTCStats
- {
- enum class RTCStatsType {
- kCodec,
- kInboundRtp,
- kOutboundRtp,
- kRemoteInboundRtp,
- kRemoteOutboundRtp,
- kMediaSource,
- kCsrc,
- kPeerConnection,
- kDataChannel,
- kStream,
- kTrack,
- kSender,
- kReceiver,
- kTransport,
- kCandidatePair,
- kLocalCandidate,
- kRemoteCandidate,
- kCertificate,
- kIceServer
- };
-
- class JavaRTCStatsClass : public JavaClass
- {
- public:
- explicit JavaRTCStatsClass(JNIEnv * env);
-
- jclass cls;
- jmethodID ctor;
- };
-
- JavaLocalRef toJava(JNIEnv * env, const webrtc::RTCStats & stats);
- JavaLocalRef toJava(JNIEnv * env, const webrtc::RTCStatsMemberInterface & member);
- }
-}
-
+/*
+ * Copyright 2019 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JNI_WEBRTC_API_RTC_STATS_H_
+#define JNI_WEBRTC_API_RTC_STATS_H_
+
+#include "JavaClass.h"
+#include "JavaRef.h"
+
+#include "api/stats/rtc_stats_report.h"
+
+#include
+
+namespace jni
+{
+ namespace RTCStats
+ {
+ enum class RTCStatsType {
+ kCodec,
+ kInboundRtp,
+ kOutboundRtp,
+ kRemoteInboundRtp,
+ kRemoteOutboundRtp,
+ kMediaSource,
+ kCsrc,
+ kPeerConnection,
+ kDataChannel,
+ kStream,
+ kTrack,
+ kSender,
+ kReceiver,
+ kTransport,
+ kCandidatePair,
+ kLocalCandidate,
+ kRemoteCandidate,
+ kCertificate,
+ kIceServer
+ };
+
+ class JavaRTCStatsClass : public JavaClass
+ {
+ public:
+ explicit JavaRTCStatsClass(JNIEnv * env);
+
+ jclass cls;
+ jmethodID ctor;
+ };
+
+ JavaLocalRef toJava(JNIEnv * env, const webrtc::RTCStats & stats);
+ JavaLocalRef toJava(JNIEnv * env, const webrtc::Attribute & attribute);
+ }
+}
+
#endif
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/include/media/MediaStreamTrackObserver.h b/webrtc-jni/src/main/cpp/include/media/MediaStreamTrackObserver.h
index 5e80f9e6..041fde28 100644
--- a/webrtc-jni/src/main/cpp/include/media/MediaStreamTrackObserver.h
+++ b/webrtc-jni/src/main/cpp/include/media/MediaStreamTrackObserver.h
@@ -54,14 +54,10 @@ namespace jni
JavaLocalRef createJavaTrack(JNIEnv * env);
private:
+ const JavaGlobalRef javaTrack;
const webrtc::MediaStreamTrackInterface * track;
-
const MediaStreamTrackEvent eventType;
-
- const JavaGlobalRef javaTrack;
-
const std::shared_ptr javaClass;
-
webrtc::MediaStreamTrackInterface::TrackState trackState;
bool trackEnabled;
};
diff --git a/webrtc-jni/src/main/cpp/include/media/audio/AudioConverter.h b/webrtc-jni/src/main/cpp/include/media/audio/AudioConverter.h
index 76f97f5c..fa496ecf 100644
--- a/webrtc-jni/src/main/cpp/include/media/audio/AudioConverter.h
+++ b/webrtc-jni/src/main/cpp/include/media/audio/AudioConverter.h
@@ -1,59 +1,57 @@
-/*
- * Copyright 2021 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef JNI_WEBRTC_MEDIA_AUDIO_CONVERTER_H_
-#define JNI_WEBRTC_MEDIA_AUDIO_CONVERTER_H_
-
-#include "JavaClass.h"
-#include "JavaRef.h"
-
-#include
-
-#include "rtc_base/constructor_magic.h"
-
-namespace jni
-{
- class AudioConverter
- {
- public:
- static std::unique_ptr create(size_t srcFrames, size_t srcChannels, size_t dstFrames, size_t dstChannels);
-
- virtual ~AudioConverter() = default;
-
- virtual void convert(const int16_t * src, size_t srcSize, int16_t * dst, size_t dstSize) = 0;
-
- size_t getSrcChannels() const { return srcChannels; }
- size_t getSrcFrames() const { return srcFrames; }
- size_t getDstChannels() const { return dstChannels; }
- size_t getDstFrames() const { return dstFrames; }
-
- protected:
- AudioConverter();
- AudioConverter(size_t srcFrames, size_t srcChannels, size_t dstFrames, size_t dstChannels);
-
- void checkSizes(size_t srcSize, size_t dstCapacity) const;
-
- const size_t srcFrames;
- const size_t srcChannels;
- const size_t dstFrames;
- const size_t dstChannels;
-
- private:
- RTC_DISALLOW_COPY_AND_ASSIGN(AudioConverter);
- };
-}
-
+/*
+ * Copyright 2021 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JNI_WEBRTC_MEDIA_AUDIO_CONVERTER_H_
+#define JNI_WEBRTC_MEDIA_AUDIO_CONVERTER_H_
+
+#include "JavaClass.h"
+#include "JavaRef.h"
+
+#include
+
+namespace jni
+{
+ class AudioConverter
+ {
+ public:
+ AudioConverter(const AudioConverter&) = delete;
+ AudioConverter& operator=(const AudioConverter&) = delete;
+
+ static std::unique_ptr create(size_t srcFrames, size_t srcChannels, size_t dstFrames, size_t dstChannels);
+
+ virtual ~AudioConverter() = default;
+
+ virtual void convert(const int16_t * src, size_t srcSize, int16_t * dst, size_t dstSize) = 0;
+
+ size_t getSrcChannels() const { return srcChannels; }
+ size_t getSrcFrames() const { return srcFrames; }
+ size_t getDstChannels() const { return dstChannels; }
+ size_t getDstFrames() const { return dstFrames; }
+
+ protected:
+ AudioConverter();
+ AudioConverter(size_t srcFrames, size_t srcChannels, size_t dstFrames, size_t dstChannels);
+
+ void checkSizes(size_t srcSize, size_t dstCapacity) const;
+
+ const size_t srcFrames;
+ const size_t srcChannels;
+ const size_t dstFrames;
+ const size_t dstChannels;
+ };
+}
+
#endif
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingConfig.h b/webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingConfig.h
index ce95ca30..5c96f4c3 100644
--- a/webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingConfig.h
+++ b/webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingConfig.h
@@ -1,142 +1,112 @@
-/*
- * Copyright 2021 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef JNI_WEBRTC_MEDIA_AUDIO_PROCESSING_CONFIG_H_
-#define JNI_WEBRTC_MEDIA_AUDIO_PROCESSING_CONFIG_H_
-
-#include "JavaClass.h"
-#include "JavaRef.h"
-
-#include "modules/audio_processing/include/audio_processing.h"
-
-#include
-
-namespace jni
-{
- namespace AudioProcessingConfig
- {
- class JavaAudioProcessingConfigClass : public JavaClass
- {
- public:
- explicit JavaAudioProcessingConfigClass(JNIEnv * env);
-
- jclass cls;
- jfieldID echoCanceller;
- jfieldID gainControl;
- jfieldID highPassFilter;
- jfieldID noiseSuppression;
- jfieldID residualEchoDetector;
- jfieldID transientSuppression;
- jfieldID voiceDetection;
- };
-
- webrtc::AudioProcessing::Config toNative(JNIEnv * env, const JavaRef & javaType);
- webrtc::AudioProcessing::Config::GainController2 toGainController2(JNIEnv * env, const JavaLocalRef & javaType);
-
-
- class JavaEchoCancellerClass : public JavaClass
- {
- public:
- explicit JavaEchoCancellerClass(JNIEnv * env);
-
- jclass cls;
- jfieldID enabled;
- jfieldID enforceHighPassFiltering;
- };
-
- class JavaGainControlClass : public JavaClass
- {
- public:
- explicit JavaGainControlClass(JNIEnv * env);
-
- jclass cls;
- jfieldID enabled;
- jfieldID fixedDigital;
- jfieldID adaptiveDigital;
- };
-
- class JavaGainControlFixedDigitalClass : public JavaClass
- {
- public:
- explicit JavaGainControlFixedDigitalClass(JNIEnv * env);
-
- jclass cls;
- jfieldID gainDb;
- };
-
- class JavaGainControlAdaptiveDigitalClass : public JavaClass
- {
- public:
- explicit JavaGainControlAdaptiveDigitalClass(JNIEnv * env);
-
- jclass cls;
- jfieldID enabled;
- jfieldID dryRun;
- jfieldID vadResetPeriodMs;
- jfieldID adjacentSpeechFramesThreshold;
- jfieldID maxGainChangeDbPerSecond;
- jfieldID maxOutputNoiseLevelDbfs;
- };
-
- class JavaHighPassFilterClass : public JavaClass
- {
- public:
- explicit JavaHighPassFilterClass(JNIEnv * env);
-
- jclass cls;
- jfieldID enabled;
- };
-
- class JavaNoiseSuppressionClass : public JavaClass
- {
- public:
- explicit JavaNoiseSuppressionClass(JNIEnv * env);
-
- jclass cls;
- jfieldID enabled;
- jfieldID level;
- };
-
- class JavaResidualEchoDetectorClass : public JavaClass
- {
- public:
- explicit JavaResidualEchoDetectorClass(JNIEnv * env);
-
- jclass cls;
- jfieldID enabled;
- };
-
- class JavaTransientSuppressionClass : public JavaClass
- {
- public:
- explicit JavaTransientSuppressionClass(JNIEnv * env);
-
- jclass cls;
- jfieldID enabled;
- };
-
- class JavaVoiceDetectionClass : public JavaClass
- {
- public:
- explicit JavaVoiceDetectionClass(JNIEnv * env);
-
- jclass cls;
- jfieldID enabled;
- };
- }
-}
-
+/*
+ * Copyright 2021 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JNI_WEBRTC_MEDIA_AUDIO_PROCESSING_CONFIG_H_
+#define JNI_WEBRTC_MEDIA_AUDIO_PROCESSING_CONFIG_H_
+
+#include "JavaClass.h"
+#include "JavaRef.h"
+
+#include "modules/audio_processing/include/audio_processing.h"
+
+#include
+
+namespace jni
+{
+ namespace AudioProcessingConfig
+ {
+ class JavaAudioProcessingConfigClass : public JavaClass
+ {
+ public:
+ explicit JavaAudioProcessingConfigClass(JNIEnv * env);
+
+ jclass cls;
+ jfieldID echoCanceller;
+ jfieldID gainControl;
+ jfieldID highPassFilter;
+ jfieldID noiseSuppression;
+ };
+
+ webrtc::AudioProcessing::Config toNative(JNIEnv * env, const JavaRef & javaType);
+ webrtc::AudioProcessing::Config::GainController2 toGainController2(JNIEnv * env, const JavaLocalRef & javaType);
+
+
+ class JavaEchoCancellerClass : public JavaClass
+ {
+ public:
+ explicit JavaEchoCancellerClass(JNIEnv * env);
+
+ jclass cls;
+ jfieldID enabled;
+ jfieldID enforceHighPassFiltering;
+ };
+
+ class JavaGainControlClass : public JavaClass
+ {
+ public:
+ explicit JavaGainControlClass(JNIEnv * env);
+
+ jclass cls;
+ jfieldID enabled;
+ jfieldID fixedDigital;
+ jfieldID adaptiveDigital;
+ };
+
+ class JavaGainControlFixedDigitalClass : public JavaClass
+ {
+ public:
+ explicit JavaGainControlFixedDigitalClass(JNIEnv * env);
+
+ jclass cls;
+ jfieldID gainDb;
+ };
+
+ class JavaGainControlAdaptiveDigitalClass : public JavaClass
+ {
+ public:
+ explicit JavaGainControlAdaptiveDigitalClass(JNIEnv * env);
+
+ jclass cls;
+ jfieldID enabled;
+ jfieldID headroomDb;
+ jfieldID maxGainDb;
+ jfieldID initialGainDb;
+ jfieldID maxGainChangeDbPerSecond;
+ jfieldID maxOutputNoiseLevelDbfs;
+ };
+
+ class JavaHighPassFilterClass : public JavaClass
+ {
+ public:
+ explicit JavaHighPassFilterClass(JNIEnv * env);
+
+ jclass cls;
+ jfieldID enabled;
+ };
+
+ class JavaNoiseSuppressionClass : public JavaClass
+ {
+ public:
+ explicit JavaNoiseSuppressionClass(JNIEnv * env);
+
+ jclass cls;
+ jfieldID enabled;
+ jfieldID level;
+ };
+ }
+}
+
#endif
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingStats.h b/webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingStats.h
index a25313b3..6b277aa3 100644
--- a/webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingStats.h
+++ b/webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingStats.h
@@ -34,7 +34,6 @@ namespace jni
explicit JavaAudioProcessingStatsClass(JNIEnv * env);
jclass cls;
- jfieldID voiceDetected;
jfieldID echoReturnLoss;
jfieldID echoReturnLossEnhancement;
jfieldID divergentFilterFraction;
diff --git a/webrtc-jni/src/main/cpp/include/media/video/VideoCaptureCapability.h b/webrtc-jni/src/main/cpp/include/media/video/VideoCaptureCapability.h
index e9aefa47..2c17332c 100644
--- a/webrtc-jni/src/main/cpp/include/media/video/VideoCaptureCapability.h
+++ b/webrtc-jni/src/main/cpp/include/media/video/VideoCaptureCapability.h
@@ -31,7 +31,7 @@ namespace jni
class VideoCaptureCapability : public webrtc::VideoCaptureCapability
{
public:
- virtual bool operator<(const VideoCaptureCapability & other) const;
+ bool operator<(const VideoCaptureCapability & other) const;
};
}
diff --git a/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDesktopSource.h b/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDesktopSource.h
index e52fd819..312758cd 100644
--- a/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDesktopSource.h
+++ b/webrtc-jni/src/main/cpp/include/media/video/VideoTrackDesktopSource.h
@@ -1,75 +1,75 @@
-/*
- * Copyright 2019 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef JNI_WEBRTC_MEDIA_VIDEO_TRACK_DESKTOP_SOURCE_H_
-#define JNI_WEBRTC_MEDIA_VIDEO_TRACK_DESKTOP_SOURCE_H_
-
-#include "api/video/i420_buffer.h"
-#include "media/base/adapted_video_track_source.h"
-#include "modules/desktop_capture/desktop_capturer.h"
-#include "rtc_base/thread.h"
-
-namespace jni
-{
- class VideoTrackDesktopSource : public rtc::AdaptedVideoTrackSource, public webrtc::DesktopCapturer::Callback
- {
- public:
- VideoTrackDesktopSource();
- ~VideoTrackDesktopSource();
-
- void setSourceId(webrtc::DesktopCapturer::SourceId source, bool isWindow);
- void setFrameRate(const uint16_t frameRate);
- void setMaxFrameSize(webrtc::DesktopSize size);
- void setFocusSelectedSource(bool focus);
-
- void start();
- void stop();
- void terminate();
-
- // AdaptedVideoTrackSource implementation.
- virtual bool is_screencast() const override;
- virtual absl::optional needs_denoising() const override;
- SourceState state() const override;
- bool remote() const override;
-
- // DesktopCapturer::Callback implementation.
- void OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr frame) override;
-
- private:
- void capture();
- void process(std::unique_ptr & frame);
-
- private:
- uint16_t frameRate;
- bool isCapturing;
- bool focusSelectedSource;
-
- webrtc::DesktopSize maxFrameSize;
-
- webrtc::MediaSourceInterface::SourceState sourceState;
-
- webrtc::DesktopCapturer::SourceId sourceId;
- bool sourceIsWindow;
-
- std::unique_ptr lastFrame;
-
- std::unique_ptr captureThread;
-
- rtc::scoped_refptr buffer;
- };
-}
-
+/*
+ * Copyright 2019 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JNI_WEBRTC_MEDIA_VIDEO_TRACK_DESKTOP_SOURCE_H_
+#define JNI_WEBRTC_MEDIA_VIDEO_TRACK_DESKTOP_SOURCE_H_
+
+#include "api/video/i420_buffer.h"
+#include "media/base/adapted_video_track_source.h"
+#include "modules/desktop_capture/desktop_capturer.h"
+#include "rtc_base/thread.h"
+
+namespace jni
+{
+ class VideoTrackDesktopSource : public rtc::AdaptedVideoTrackSource, public webrtc::DesktopCapturer::Callback
+ {
+ public:
+ VideoTrackDesktopSource();
+ ~VideoTrackDesktopSource();
+
+ void setSourceId(webrtc::DesktopCapturer::SourceId source, bool isWindow);
+ void setFrameRate(const uint16_t frameRate);
+ void setMaxFrameSize(webrtc::DesktopSize size);
+ void setFocusSelectedSource(bool focus);
+
+ void start();
+ void stop();
+ void terminate();
+
+ // AdaptedVideoTrackSource implementation.
+ virtual bool is_screencast() const override;
+ virtual std::optional needs_denoising() const override;
+ SourceState state() const override;
+ bool remote() const override;
+
+ // DesktopCapturer::Callback implementation.
+ void OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr frame) override;
+
+ private:
+ void capture();
+ void process(std::unique_ptr & frame);
+
+ private:
+ uint16_t frameRate;
+ bool isCapturing;
+ bool focusSelectedSource;
+
+ webrtc::DesktopSize maxFrameSize;
+
+ webrtc::MediaSourceInterface::SourceState sourceState;
+
+ webrtc::DesktopCapturer::SourceId sourceId;
+ bool sourceIsWindow;
+
+ std::unique_ptr lastFrame;
+
+ std::unique_ptr captureThread;
+
+ rtc::scoped_refptr buffer;
+ };
+}
+
#endif
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/include/media/video/desktop/DesktopCaptureCallback.h b/webrtc-jni/src/main/cpp/include/media/video/desktop/DesktopCaptureCallback.h
index 911f2fad..b6863349 100644
--- a/webrtc-jni/src/main/cpp/include/media/video/desktop/DesktopCaptureCallback.h
+++ b/webrtc-jni/src/main/cpp/include/media/video/desktop/DesktopCaptureCallback.h
@@ -32,7 +32,7 @@ namespace jni
{
public:
DesktopCaptureCallback(JNIEnv * env, const JavaGlobalRef & callback);
- ~DesktopCaptureCallback() = default;
+ ~DesktopCaptureCallback() override = default;
// DesktopCapturer::Callback implementation.
void OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr frame) override;
diff --git a/webrtc-jni/src/main/cpp/include/media/video/desktop/DesktopCapturer.h b/webrtc-jni/src/main/cpp/include/media/video/desktop/DesktopCapturer.h
index 927afdc8..5f5dc000 100644
--- a/webrtc-jni/src/main/cpp/include/media/video/desktop/DesktopCapturer.h
+++ b/webrtc-jni/src/main/cpp/include/media/video/desktop/DesktopCapturer.h
@@ -14,36 +14,41 @@
* limitations under the License.
*/
-#ifndef JNI_WEBRTC_MEDIA_DESKTOP_CAPTURER_H_
-#define JNI_WEBRTC_MEDIA_DESKTOP_CAPTURER_H_
+#ifndef JNI_WEBRTC_MEDIA_VIDEO_DESKTOP_CAPTURER_H_
+#define JNI_WEBRTC_MEDIA_VIDEO_DESKTOP_CAPTURER_H_
#if defined(WEBRTC_WIN)
#include "platform/windows/ComInitializer.h"
#endif
#include "modules/desktop_capture/desktop_capturer.h"
+#include "modules/desktop_capture/desktop_and_cursor_composer.h"
#include
#include
namespace jni
{
- class DesktopCapturer : public webrtc::DesktopCapturer
+ class DesktopCapturer
{
public:
- explicit DesktopCapturer(bool screenCapturer);
- ~DesktopCapturer() override;
+ DesktopCapturer(webrtc::DesktopCapturer * capturer);
+ ~DesktopCapturer();
+
+ DesktopCapturer(const DesktopCapturer &) = delete;
+ DesktopCapturer & operator=(const DesktopCapturer &) = delete;
// webrtc::DesktopCapturer implementations.
- void Start(Callback * callback) override;
- void SetSharedMemoryFactory(std::unique_ptr factory) override;
- void CaptureFrame() override;
- void SetExcludedWindow(webrtc::WindowId window) override;
- bool GetSourceList(SourceList * sources) override;
- bool SelectSource(SourceId id) override;
- bool FocusOnSelectedSource() override;
+ void Start(webrtc::DesktopCapturer::Callback * callback);
+ void SetSharedMemoryFactory(std::unique_ptr factory);
+ void SetMaxFrameRate(uint32_t max_frame_rate);
+ void CaptureFrame();
+ void SetExcludedWindow(webrtc::WindowId window);
+ bool GetSourceList(webrtc::DesktopCapturer::SourceList * sources);
+ bool SelectSource(webrtc::DesktopCapturer::SourceId id);
+ bool FocusOnSelectedSource();
void setFocusSelectedSource(bool focus);
- bool IsOccluded(const webrtc::DesktopVector & pos) override;
+ bool IsOccluded(const webrtc::DesktopVector & pos);
protected:
std::unique_ptr capturer;
diff --git a/webrtc-jni/src/main/cpp/include/media/video/desktop/macos/MacOSPowerManagement.h b/webrtc-jni/src/main/cpp/include/media/video/desktop/macos/MacOSPowerManagement.h
new file mode 100644
index 00000000..87b69ea2
--- /dev/null
+++ b/webrtc-jni/src/main/cpp/include/media/video/desktop/macos/MacOSPowerManagement.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JNI_WEBRTC_MEDIA_DESKTOP_MACOS_POWER_MANAGEMENT_H_
+#define JNI_WEBRTC_MEDIA_DESKTOP_MACOS_POWER_MANAGEMENT_H_
+
+#include "media/video/desktop/PowerManagement.h"
+
+#include
+
+namespace jni
+{
+ namespace avdev
+ {
+ class MacOSPowerManagement : public PowerManagement
+ {
+ public:
+ MacOSPowerManagement();
+ ~MacOSPowerManagement() = default;
+
+ void enableUserActivity();
+ void disableUserActivity();
+
+ private:
+ IOPMAssertionID powerAssertion;
+ };
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/include/media/video/windows/WindowsVideoDeviceManager.h b/webrtc-jni/src/main/cpp/include/media/video/windows/WindowsVideoDeviceManager.h
index be7590d8..f195fd76 100644
--- a/webrtc-jni/src/main/cpp/include/media/video/windows/WindowsVideoDeviceManager.h
+++ b/webrtc-jni/src/main/cpp/include/media/video/windows/WindowsVideoDeviceManager.h
@@ -34,8 +34,8 @@ namespace jni
std::set getVideoCaptureCapabilities(const VideoDevice & device) override;
protected:
- void onDeviceConnected(std::wstring symLink);
- void onDeviceDisconnected(std::wstring symLink);
+ void onDeviceConnected(std::wstring symLink) override;
+ void onDeviceDisconnected(std::wstring symLink) override;
private:
void enumerateDevices(std::wstring * symLink);
diff --git a/webrtc-jni/src/main/cpp/src/JNI_AudioConverter.cpp b/webrtc-jni/src/main/cpp/src/JNI_AudioConverter.cpp
index 0caf4633..47e1a336 100644
--- a/webrtc-jni/src/main/cpp/src/JNI_AudioConverter.cpp
+++ b/webrtc-jni/src/main/cpp/src/JNI_AudioConverter.cpp
@@ -1,65 +1,66 @@
-/*
- * Copyright 2021 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "JNI_AudioConverter.h"
-#include "media/audio/AudioConverter.h"
-#include "JavaUtils.h"
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioConverter_convertInternal
-(JNIEnv * env, jobject caller, jbyteArray src, jint nSrcSamples, jbyteArray dst, jint nDstSamples)
-{
- jni::AudioConverter * converter = GetHandle(env, caller);
- CHECK_HANDLE(converter);
-
- jboolean isDstCopy = JNI_FALSE;
-
- jbyte * srcPtr = env->GetByteArrayElements(src, nullptr);
- jbyte * dstPtr = env->GetByteArrayElements(dst, &isDstCopy);
-
- converter->convert(reinterpret_cast(srcPtr), nSrcSamples, reinterpret_cast(dstPtr), nDstSamples);
-
- if (isDstCopy == JNI_TRUE) {
- jsize dstLength = env->GetArrayLength(dst);
-
- env->SetByteArrayRegion(dst, 0, dstLength, dstPtr);
- }
-
- env->ReleaseByteArrayElements(src, srcPtr, JNI_ABORT);
- env->ReleaseByteArrayElements(dst, dstPtr, JNI_ABORT);
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioConverter_dispose
-(JNIEnv * env, jobject caller)
-{
- jni::AudioConverter * converter = GetHandle(env, caller);
- CHECK_HANDLE(converter);
-
- SetHandle(env, caller, nullptr);
-
- delete converter;
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioConverter_initialize
-(JNIEnv * env, jobject caller, jint srcSampleRate, jint srcChannels, jint dstSampleRate, jint dstChannels)
-{
- // 10 ms frames
- size_t srcFrames = srcSampleRate / 100;
- size_t dstFrames = dstSampleRate / 100;
-
- jni::AudioConverter * converter = jni::AudioConverter::create(srcFrames, srcChannels, dstFrames, dstChannels).release();
-
- SetHandle(env, caller, converter);
+/*
+ * Copyright 2021 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "JNI_AudioConverter.h"
+#include "api/audio/audio_processing.h"
+#include "media/audio/AudioConverter.h"
+#include "JavaUtils.h"
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioConverter_convertInternal
+(JNIEnv * env, jobject caller, jbyteArray src, jint nSrcSamples, jbyteArray dst, jint nDstSamples)
+{
+ jni::AudioConverter * converter = GetHandle(env, caller);
+ CHECK_HANDLE(converter);
+
+ jboolean isDstCopy = JNI_FALSE;
+
+ jbyte * srcPtr = env->GetByteArrayElements(src, nullptr);
+ jbyte * dstPtr = env->GetByteArrayElements(dst, &isDstCopy);
+
+ converter->convert(reinterpret_cast(srcPtr), nSrcSamples, reinterpret_cast(dstPtr), nDstSamples);
+
+ if (isDstCopy == JNI_TRUE) {
+ jsize dstLength = env->GetArrayLength(dst);
+
+ env->SetByteArrayRegion(dst, 0, dstLength, dstPtr);
+ }
+
+ env->ReleaseByteArrayElements(src, srcPtr, JNI_ABORT);
+ env->ReleaseByteArrayElements(dst, dstPtr, JNI_ABORT);
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioConverter_dispose
+(JNIEnv * env, jobject caller)
+{
+ jni::AudioConverter * converter = GetHandle(env, caller);
+ CHECK_HANDLE(converter);
+
+ SetHandle(env, caller, nullptr);
+
+ delete converter;
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioConverter_initialize
+(JNIEnv * env, jobject caller, jint srcSampleRate, jint srcChannels, jint dstSampleRate, jint dstChannels)
+{
+ // 10 ms frames
+ size_t srcFrames = webrtc::AudioProcessing::GetFrameSize(srcSampleRate);
+ size_t dstFrames = webrtc::AudioProcessing::GetFrameSize(dstSampleRate);
+
+ jni::AudioConverter * converter = jni::AudioConverter::create(srcFrames, srcChannels, dstFrames, dstChannels).release();
+
+ SetHandle(env, caller, converter);
}
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/src/JNI_AudioDeviceModule.cpp b/webrtc-jni/src/main/cpp/src/JNI_AudioDeviceModule.cpp
index aebc6656..a9a425f5 100644
--- a/webrtc-jni/src/main/cpp/src/JNI_AudioDeviceModule.cpp
+++ b/webrtc-jni/src/main/cpp/src/JNI_AudioDeviceModule.cpp
@@ -1,498 +1,498 @@
-/*
- * Copyright 2019 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "JNI_AudioDeviceModule.h"
-#include "Exception.h"
-#include "JavaArrayList.h"
-#include "JavaEnums.h"
-#include "JavaError.h"
-#include "JavaObject.h"
-#include "JavaRef.h"
-#include "JavaString.h"
-#include "JavaUtils.h"
-#include "media/audio/AudioDevice.h"
-#include "media/audio/AudioTransportSink.h"
-#include "media/audio/AudioTransportSource.h"
-
-#include "api/scoped_refptr.h"
-#include "api/task_queue/default_task_queue_factory.h"
-#include "modules/audio_device/include/audio_device.h"
-#include "rtc_base/logging.h"
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_initPlayout
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->InitPlayout() != 0) {
- env->Throw(jni::JavaError(env, "Init playout failed"));
- return;
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_stopPlayout
-(JNIEnv* env, jobject caller)
-{
- webrtc::AudioDeviceModule* audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->StopPlayout() != 0) {
- env->Throw(jni::JavaError(env, "Stop playout failed"));
- return;
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_startPlayout
-(JNIEnv* env, jobject caller)
-{
- webrtc::AudioDeviceModule* audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->StartPlayout() != 0) {
- env->Throw(jni::JavaError(env, "Start playout failed"));
- return;
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_initRecording
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->InitRecording() != 0) {
- env->Throw(jni::JavaError(env, "Init recording failed"));
- return;
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_stopRecording
-(JNIEnv* env, jobject caller)
-{
- webrtc::AudioDeviceModule* audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->StopRecording() != 0) {
- env->Throw(jni::JavaError(env, "Stop recording failed"));
- return;
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_startRecording
-(JNIEnv* env, jobject caller)
-{
- webrtc::AudioDeviceModule* audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->StartRecording() != 0) {
- env->Throw(jni::JavaError(env, "Start recording failed"));
- return;
- }
-}
-
-JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getPlayoutDevices
-(JNIEnv* env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, nullptr);
-
- char name[webrtc::kAdmMaxDeviceNameSize];
- char guid[webrtc::kAdmMaxGuidSize];
-
- int16_t deviceCount = audioModule->PlayoutDevices();
-
- jni::JavaArrayList deviceList(env, deviceCount);
-
- for (int i = 0; i < deviceCount; ++i) {
- if (audioModule->PlayoutDeviceName(i, name, guid) == 0) {
- auto device = std::make_shared(name, guid);
-
- deviceList.add(jni::AudioDevice::toJavaAudioDevice(env, device));
- }
- }
-
- return deviceList.listObject().release();
-}
-
-JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getRecordingDevices
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, nullptr);
-
- char name[webrtc::kAdmMaxDeviceNameSize];
- char guid[webrtc::kAdmMaxGuidSize];
-
- int16_t deviceCount = audioModule->RecordingDevices();
-
- jni::JavaArrayList deviceList(env, deviceCount);
-
- for (int i = 0; i < deviceCount; ++i) {
- if (audioModule->RecordingDeviceName(i, name, guid) == 0) {
- auto device = std::make_shared(name, guid);
-
- deviceList.add(jni::AudioDevice::toJavaAudioDevice(env, device));
- }
- }
-
- return deviceList.listObject().release();
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setPlayoutDevice
-(JNIEnv * env, jobject caller, jobject device)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (!device) {
- env->Throw(jni::JavaNullPointerException(env, "AudioDevice is null"));
- return;
- }
-
- jni::JavaObject obj(env, jni::JavaLocalRef(env, device));
-
- const auto javaClass = jni::JavaClasses::get(env);
- const std::string devGuid = jni::JavaString::toNative(env, obj.getString(javaClass->descriptor));
-
- uint16_t index = 0;
- int16_t deviceCount = audioModule->PlayoutDevices();
-
- char name[webrtc::kAdmMaxDeviceNameSize];
- char guid[webrtc::kAdmMaxGuidSize];
-
- for (int i = 0; i < deviceCount; ++i) {
- if ((audioModule->PlayoutDeviceName(i, name, guid) == 0) && devGuid == std::string(guid)) {
- index = i;
- break;
- }
- }
-
- if (audioModule->SetPlayoutDevice(index) != 0) {
- env->Throw(jni::JavaError(env, "Set playout device failed"));
- return;
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setRecordingDevice
-(JNIEnv * env, jobject caller, jobject device)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (!device) {
- env->Throw(jni::JavaNullPointerException(env, "AudioDevice is null"));
- return;
- }
-
- jni::JavaObject obj(env, jni::JavaLocalRef(env, device));
-
- const auto javaClass = jni::JavaClasses::get(env);
- const std::string devGuid = jni::JavaString::toNative(env, obj.getString(javaClass->descriptor));
-
- uint16_t index = 0;
- int16_t deviceCount = audioModule->RecordingDevices();
-
- char name[webrtc::kAdmMaxDeviceNameSize];
- char guid[webrtc::kAdmMaxGuidSize];
-
- for (int i = 0; i < deviceCount; ++i) {
- if ((audioModule->RecordingDeviceName(i, name, guid) == 0) && devGuid == std::string(guid)) {
- index = i;
- break;
- }
- }
-
- if (audioModule->SetRecordingDevice(index) != 0) {
- env->Throw(jni::JavaError(env, "Set recording device failed"));
- return;
- }
-}
-
-JNIEXPORT jboolean JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_isSpeakerMuted
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, true);
-
- bool mute = true;
-
- audioModule->SpeakerMute(&mute);
-
- return mute;
-}
-
-JNIEXPORT jboolean JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_isMicrophoneMuted
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, true);
-
- bool mute = true;
-
- audioModule->MicrophoneMute(&mute);
-
- return mute;
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getSpeakerVolume
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, 0);
-
- uint32_t volume = 0;
-
- if (audioModule->SpeakerVolume(&volume) != 0) {
- env->Throw(jni::JavaError(env, "Get speaker volume failed"));
- }
-
- return volume;
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMaxSpeakerVolume
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, 0);
-
- uint32_t volume = 0;
-
- if (audioModule->MaxSpeakerVolume(&volume) != 0) {
- env->Throw(jni::JavaError(env, "Get max speaker volume failed"));
- }
-
- return volume;
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMinSpeakerVolume
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, 0);
-
- uint32_t volume = 0;
-
- if (audioModule->MinSpeakerVolume(&volume) != 0) {
- env->Throw(jni::JavaError(env, "Get min speaker volume failed"));
- }
-
- return volume;
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMicrophoneVolume
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, 0);
-
- uint32_t volume = 0;
-
- if (audioModule->MicrophoneVolume(&volume) != 0) {
- env->Throw(jni::JavaError(env, "Get microphone volume failed"));
- }
-
- return volume;
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMaxMicrophoneVolume
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, 0);
-
- uint32_t volume = 0;
-
- if (audioModule->MaxMicrophoneVolume(&volume) != 0) {
- env->Throw(jni::JavaError(env, "Get max microphone volume failed"));
- }
-
- return volume;
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMinMicrophoneVolume
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, 0);
-
- uint32_t volume = 0;
-
- if (audioModule->MinMicrophoneVolume(&volume) != 0) {
- env->Throw(jni::JavaError(env, "Get min microphone volume failed"));
- }
-
- return volume;
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setSpeakerVolume
-(JNIEnv * env, jobject caller, jint volume)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->SetSpeakerVolume(static_cast(volume)) != 0) {
- env->Throw(jni::JavaError(env, "Set speaker volume failed"));
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setSpeakerMute
-(JNIEnv * env, jobject caller, jboolean mute)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->SetSpeakerMute(mute) != 0) {
- env->Throw(jni::JavaError(env, "Set speaker mute failed"));
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setMicrophoneVolume
-(JNIEnv * env, jobject caller, jint volume)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->SetMicrophoneVolume(static_cast(volume)) != 0) {
- env->Throw(jni::JavaError(env, "Set microphone volume failed"));
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setMicrophoneMute
-(JNIEnv * env, jobject caller, jboolean mute)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->SetMicrophoneMute(mute) != 0) {
- env->Throw(jni::JavaError(env, "Set microphone mute failed"));
- }
-}
-
-JNIEXPORT jlong JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_addSinkInternal
-(JNIEnv * env, jobject caller, jobject jSink)
-{
- if (jSink == nullptr) {
- env->Throw(jni::JavaNullPointerException(env, "AudioSink must not be null"));
- return 0;
- }
-
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, 0);
-
- auto sink = new jni::AudioTransportSink(env, jni::JavaGlobalRef(env, jSink));
-
- audioModule->RegisterAudioCallback(sink);
-
- return reinterpret_cast(sink);
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_removeSinkInternal
-(JNIEnv * env, jobject caller, jlong sinkHandle)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- auto sink = reinterpret_cast(sinkHandle);
-
- if (sink != nullptr) {
- audioModule->RegisterAudioCallback(nullptr);
-
- delete sink;
- }
-}
-
-JNIEXPORT jlong JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_addSourceInternal
-(JNIEnv * env, jobject caller, jobject jSource)
-{
- if (jSource == nullptr) {
- env->Throw(jni::JavaNullPointerException(env, "AudioSource must not be null"));
- return 0;
- }
-
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLEV(audioModule, 0);
-
- auto source = new jni::AudioTransportSource(env, jni::JavaGlobalRef(env, jSource));
-
- audioModule->RegisterAudioCallback(source);
-
- return reinterpret_cast(source);
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_removeSourceInternal
-(JNIEnv * env, jobject caller, jlong sourceHandle)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- auto source = reinterpret_cast(sourceHandle);
-
- if (source != nullptr) {
- audioModule->RegisterAudioCallback(nullptr);
-
- delete source;
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_disposeInternal
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
- CHECK_HANDLE(audioModule);
-
- if (audioModule->Initialized()) {
- audioModule->Terminate();
- }
-
- rtc::RefCountReleaseStatus status = audioModule->Release();
-
- if (status != rtc::RefCountReleaseStatus::kDroppedLastRef) {
- RTC_LOG(LS_WARNING) << "Native object was not deleted. A reference is still around somewhere.";
- }
-
- SetHandle(env, caller, nullptr);
-
- audioModule = nullptr;
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_initialize
-(JNIEnv * env, jobject caller, jobject jAudioLayer)
-{
- std::unique_ptr taskQueueFactory = webrtc::CreateDefaultTaskQueueFactory();
-
- if (!taskQueueFactory) {
- env->Throw(jni::JavaError(env, "Create TaskQueueFactory failed"));
- return;
- }
-
- auto audioLayer = jni::JavaEnums::toNative(env, jAudioLayer);
-
- rtc::scoped_refptr audioModule = webrtc::AudioDeviceModule::Create(
- audioLayer, taskQueueFactory.release());
-
- if (!audioModule) {
- env->Throw(jni::JavaError(env, "Create AudioDeviceModule failed"));
- return;
- }
-
- if (audioModule->Init() != 0) {
- env->Throw(jni::JavaError(env, "Initialize AudioDeviceModule failed"));
- return;
- }
-
- SetHandle(env, caller, audioModule.release());
-}
+/*
+ * Copyright 2019 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "JNI_AudioDeviceModule.h"
+#include "Exception.h"
+#include "JavaArrayList.h"
+#include "JavaEnums.h"
+#include "JavaError.h"
+#include "JavaObject.h"
+#include "JavaRef.h"
+#include "JavaString.h"
+#include "JavaUtils.h"
+#include "media/audio/AudioDevice.h"
+#include "media/audio/AudioTransportSink.h"
+#include "media/audio/AudioTransportSource.h"
+
+#include "api/scoped_refptr.h"
+#include "api/task_queue/default_task_queue_factory.h"
+#include "modules/audio_device/include/audio_device.h"
+#include "rtc_base/logging.h"
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_initPlayout
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->InitPlayout() != 0) {
+ env->Throw(jni::JavaError(env, "Init playout failed"));
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_stopPlayout
+(JNIEnv* env, jobject caller)
+{
+ webrtc::AudioDeviceModule* audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->StopPlayout() != 0) {
+ env->Throw(jni::JavaError(env, "Stop playout failed"));
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_startPlayout
+(JNIEnv* env, jobject caller)
+{
+ webrtc::AudioDeviceModule* audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->StartPlayout() != 0) {
+ env->Throw(jni::JavaError(env, "Start playout failed"));
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_initRecording
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->InitRecording() != 0) {
+ env->Throw(jni::JavaError(env, "Init recording failed"));
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_stopRecording
+(JNIEnv* env, jobject caller)
+{
+ webrtc::AudioDeviceModule* audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->StopRecording() != 0) {
+ env->Throw(jni::JavaError(env, "Stop recording failed"));
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_startRecording
+(JNIEnv* env, jobject caller)
+{
+ webrtc::AudioDeviceModule* audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->StartRecording() != 0) {
+ env->Throw(jni::JavaError(env, "Start recording failed"));
+ return;
+ }
+}
+
+JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getPlayoutDevices
+(JNIEnv* env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, nullptr);
+
+ char name[webrtc::kAdmMaxDeviceNameSize];
+ char guid[webrtc::kAdmMaxGuidSize];
+
+ int16_t deviceCount = audioModule->PlayoutDevices();
+
+ jni::JavaArrayList deviceList(env, deviceCount);
+
+ for (int i = 0; i < deviceCount; ++i) {
+ if (audioModule->PlayoutDeviceName(i, name, guid) == 0) {
+ auto device = std::make_shared(name, guid);
+
+ deviceList.add(jni::AudioDevice::toJavaAudioDevice(env, device));
+ }
+ }
+
+ return deviceList.listObject().release();
+}
+
+JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getRecordingDevices
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, nullptr);
+
+ char name[webrtc::kAdmMaxDeviceNameSize];
+ char guid[webrtc::kAdmMaxGuidSize];
+
+ int16_t deviceCount = audioModule->RecordingDevices();
+
+ jni::JavaArrayList deviceList(env, deviceCount);
+
+ for (int i = 0; i < deviceCount; ++i) {
+ if (audioModule->RecordingDeviceName(i, name, guid) == 0) {
+ auto device = std::make_shared(name, guid);
+
+ deviceList.add(jni::AudioDevice::toJavaAudioDevice(env, device));
+ }
+ }
+
+ return deviceList.listObject().release();
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setPlayoutDevice
+(JNIEnv * env, jobject caller, jobject device)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (!device) {
+ env->Throw(jni::JavaNullPointerException(env, "AudioDevice is null"));
+ return;
+ }
+
+ jni::JavaObject obj(env, jni::JavaLocalRef(env, device));
+
+ const auto javaClass = jni::JavaClasses::get(env);
+ const std::string devGuid = jni::JavaString::toNative(env, obj.getString(javaClass->descriptor));
+
+ uint16_t index = 0;
+ int16_t deviceCount = audioModule->PlayoutDevices();
+
+ char name[webrtc::kAdmMaxDeviceNameSize];
+ char guid[webrtc::kAdmMaxGuidSize];
+
+ for (int i = 0; i < deviceCount; ++i) {
+ if ((audioModule->PlayoutDeviceName(i, name, guid) == 0) && devGuid == std::string(guid)) {
+ index = i;
+ break;
+ }
+ }
+
+ if (audioModule->SetPlayoutDevice(index) != 0) {
+ env->Throw(jni::JavaError(env, "Set playout device failed"));
+ return;
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setRecordingDevice
+(JNIEnv * env, jobject caller, jobject device)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (!device) {
+ env->Throw(jni::JavaNullPointerException(env, "AudioDevice is null"));
+ return;
+ }
+
+ jni::JavaObject obj(env, jni::JavaLocalRef(env, device));
+
+ const auto javaClass = jni::JavaClasses::get(env);
+ const std::string devGuid = jni::JavaString::toNative(env, obj.getString(javaClass->descriptor));
+
+ uint16_t index = 0;
+ int16_t deviceCount = audioModule->RecordingDevices();
+
+ char name[webrtc::kAdmMaxDeviceNameSize];
+ char guid[webrtc::kAdmMaxGuidSize];
+
+ for (int i = 0; i < deviceCount; ++i) {
+ if ((audioModule->RecordingDeviceName(i, name, guid) == 0) && devGuid == std::string(guid)) {
+ index = i;
+ break;
+ }
+ }
+
+ if (audioModule->SetRecordingDevice(index) != 0) {
+ env->Throw(jni::JavaError(env, "Set recording device failed"));
+ return;
+ }
+}
+
+JNIEXPORT jboolean JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_isSpeakerMuted
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, true);
+
+ bool mute = true;
+
+ audioModule->SpeakerMute(&mute);
+
+ return mute;
+}
+
+JNIEXPORT jboolean JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_isMicrophoneMuted
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, true);
+
+ bool mute = true;
+
+ audioModule->MicrophoneMute(&mute);
+
+ return mute;
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getSpeakerVolume
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, 0);
+
+ uint32_t volume = 0;
+
+ if (audioModule->SpeakerVolume(&volume) != 0) {
+ env->Throw(jni::JavaError(env, "Get speaker volume failed"));
+ }
+
+ return volume;
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMaxSpeakerVolume
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, 0);
+
+ uint32_t volume = 0;
+
+ if (audioModule->MaxSpeakerVolume(&volume) != 0) {
+ env->Throw(jni::JavaError(env, "Get max speaker volume failed"));
+ }
+
+ return volume;
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMinSpeakerVolume
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, 0);
+
+ uint32_t volume = 0;
+
+ if (audioModule->MinSpeakerVolume(&volume) != 0) {
+ env->Throw(jni::JavaError(env, "Get min speaker volume failed"));
+ }
+
+ return volume;
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMicrophoneVolume
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, 0);
+
+ uint32_t volume = 0;
+
+ if (audioModule->MicrophoneVolume(&volume) != 0) {
+ env->Throw(jni::JavaError(env, "Get microphone volume failed"));
+ }
+
+ return volume;
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMaxMicrophoneVolume
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, 0);
+
+ uint32_t volume = 0;
+
+ if (audioModule->MaxMicrophoneVolume(&volume) != 0) {
+ env->Throw(jni::JavaError(env, "Get max microphone volume failed"));
+ }
+
+ return volume;
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_getMinMicrophoneVolume
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, 0);
+
+ uint32_t volume = 0;
+
+ if (audioModule->MinMicrophoneVolume(&volume) != 0) {
+ env->Throw(jni::JavaError(env, "Get min microphone volume failed"));
+ }
+
+ return volume;
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setSpeakerVolume
+(JNIEnv * env, jobject caller, jint volume)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->SetSpeakerVolume(static_cast(volume)) != 0) {
+ env->Throw(jni::JavaError(env, "Set speaker volume failed"));
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setSpeakerMute
+(JNIEnv * env, jobject caller, jboolean mute)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->SetSpeakerMute(mute) != 0) {
+ env->Throw(jni::JavaError(env, "Set speaker mute failed"));
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setMicrophoneVolume
+(JNIEnv * env, jobject caller, jint volume)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->SetMicrophoneVolume(static_cast(volume)) != 0) {
+ env->Throw(jni::JavaError(env, "Set microphone volume failed"));
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_setMicrophoneMute
+(JNIEnv * env, jobject caller, jboolean mute)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->SetMicrophoneMute(mute) != 0) {
+ env->Throw(jni::JavaError(env, "Set microphone mute failed"));
+ }
+}
+
+JNIEXPORT jlong JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_addSinkInternal
+(JNIEnv * env, jobject caller, jobject jSink)
+{
+ if (jSink == nullptr) {
+ env->Throw(jni::JavaNullPointerException(env, "AudioSink must not be null"));
+ return 0;
+ }
+
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, 0);
+
+ auto sink = new jni::AudioTransportSink(env, jni::JavaGlobalRef(env, jSink));
+
+ audioModule->RegisterAudioCallback(sink);
+
+ return reinterpret_cast(sink);
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_removeSinkInternal
+(JNIEnv * env, jobject caller, jlong sinkHandle)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ auto sink = reinterpret_cast(sinkHandle);
+
+ if (sink != nullptr) {
+ audioModule->RegisterAudioCallback(nullptr);
+
+ delete sink;
+ }
+}
+
+JNIEXPORT jlong JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_addSourceInternal
+(JNIEnv * env, jobject caller, jobject jSource)
+{
+ if (jSource == nullptr) {
+ env->Throw(jni::JavaNullPointerException(env, "AudioSource must not be null"));
+ return 0;
+ }
+
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLEV(audioModule, 0);
+
+ auto source = new jni::AudioTransportSource(env, jni::JavaGlobalRef(env, jSource));
+
+ audioModule->RegisterAudioCallback(source);
+
+ return reinterpret_cast(source);
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_removeSourceInternal
+(JNIEnv * env, jobject caller, jlong sourceHandle)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ auto source = reinterpret_cast(sourceHandle);
+
+ if (source != nullptr) {
+ audioModule->RegisterAudioCallback(nullptr);
+
+ delete source;
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_disposeInternal
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioDeviceModule * audioModule = GetHandle(env, caller);
+ CHECK_HANDLE(audioModule);
+
+ if (audioModule->Initialized()) {
+ audioModule->Terminate();
+ }
+
+ webrtc::RefCountReleaseStatus status = audioModule->Release();
+
+ if (status != webrtc::RefCountReleaseStatus::kDroppedLastRef) {
+ RTC_LOG(LS_WARNING) << "Native object was not deleted. A reference is still around somewhere.";
+ }
+
+ SetHandle(env, caller, nullptr);
+
+ audioModule = nullptr;
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioDeviceModule_initialize
+(JNIEnv * env, jobject caller, jobject jAudioLayer)
+{
+ std::unique_ptr taskQueueFactory = webrtc::CreateDefaultTaskQueueFactory();
+
+ if (!taskQueueFactory) {
+ env->Throw(jni::JavaError(env, "Create TaskQueueFactory failed"));
+ return;
+ }
+
+ auto audioLayer = jni::JavaEnums::toNative(env, jAudioLayer);
+
+ rtc::scoped_refptr audioModule = webrtc::AudioDeviceModule::Create(
+ audioLayer, taskQueueFactory.release());
+
+ if (!audioModule) {
+ env->Throw(jni::JavaError(env, "Create AudioDeviceModule failed"));
+ return;
+ }
+
+ if (audioModule->Init() != 0) {
+ env->Throw(jni::JavaError(env, "Initialize AudioDeviceModule failed"));
+ return;
+ }
+
+ SetHandle(env, caller, audioModule.release());
+}
diff --git a/webrtc-jni/src/main/cpp/src/JNI_AudioProcessing.cpp b/webrtc-jni/src/main/cpp/src/JNI_AudioProcessing.cpp
index aa1985c6..da7feecd 100644
--- a/webrtc-jni/src/main/cpp/src/JNI_AudioProcessing.cpp
+++ b/webrtc-jni/src/main/cpp/src/JNI_AudioProcessing.cpp
@@ -1,215 +1,218 @@
-/*
- * Copyright 2021 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "JNI_AudioProcessing.h"
-#include "Exception.h"
-#include "JavaArrayList.h"
-#include "JavaEnums.h"
-#include "JavaError.h"
-#include "JavaObject.h"
-#include "JavaRef.h"
-#include "JavaString.h"
-#include "JavaUtils.h"
-
-#include "media/audio/AudioProcessing.h"
-#include "media/audio/AudioProcessingConfig.h"
-#include "media/audio/AudioProcessingStreamConfig.h"
-#include "api/audio/audio_frame.h"
-#include "api/scoped_refptr.h"
-#include "modules/audio_processing/include/audio_processing.h"
-#include "rtc_base/logging.h"
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_applyConfig
-(JNIEnv * env, jobject caller, jobject config)
-{
- webrtc::AudioProcessing * apm = GetHandle(env, caller);
- CHECK_HANDLE(apm);
-
- apm->ApplyConfig(jni::AudioProcessingConfig::toNative(env, jni::JavaLocalRef(env, config)));
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_setStreamDelayMs
-(JNIEnv * env, jobject caller, jint delayMs)
-{
- webrtc::AudioProcessing * apm = GetHandle(env, caller);
- CHECK_HANDLE(apm);
-
- apm->set_stream_delay_ms(delayMs);
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_getStreamDelayMs
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioProcessing * apm = GetHandle(env, caller);
- CHECK_HANDLEV(apm, 0);
-
- return apm->stream_delay_ms();
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_processStream
-(JNIEnv * env, jobject caller, jbyteArray src, jobject inputConfig, jobject outputConfig, jbyteArray dest)
-{
- webrtc::AudioProcessing * apm = GetHandle(env, caller);
- CHECK_HANDLEV(apm, 0);
-
- webrtc::StreamConfig srcConfig = jni::AudioProcessingStreamConfig::toNative(env, jni::JavaLocalRef(env, inputConfig));
- webrtc::StreamConfig dstConfig = jni::AudioProcessingStreamConfig::toNative(env, jni::JavaLocalRef(env, outputConfig));
-
- jboolean isDstCopy = JNI_FALSE;
-
- jbyte * srcPtr = env->GetByteArrayElements(src, NULL);
- jbyte * dstPtr = env->GetByteArrayElements(dest, &isDstCopy);
-
- const int16_t * srcFrame = reinterpret_cast(srcPtr);
- int16_t * dstFrame = reinterpret_cast(dstPtr);
-
- int result;
-
- if (srcConfig.num_channels() == 1 && dstConfig.num_channels() == 2) {
- // Up-mixing, only mono to stereo.
- // For complex channel layouts a channel mixer is required.
-
- const size_t srcNumSamples = srcConfig.num_samples();
- const size_t dstNumChannels = dstConfig.num_channels();
- const size_t frameSize = srcNumSamples * dstNumChannels;
-
- if (frameSize > webrtc::AudioFrame::kMaxDataSizeSamples) {
- return -9;
- }
-
- for (int i = static_cast(srcNumSamples) - 1; i >= 0; i--) {
- for (size_t j = 0; j < dstNumChannels; ++j) {
- dstFrame[dstNumChannels * i + j] = srcFrame[i];
- }
- }
-
- srcConfig.set_num_channels(dstNumChannels);
-
- result = apm->ProcessStream(dstFrame, srcConfig, dstConfig, dstFrame);
- }
- else {
- // Will also down-mix if required, e.g. from stereo to mono.
- result = apm->ProcessStream(srcFrame, srcConfig, dstConfig, dstFrame);
- }
-
- if (isDstCopy == JNI_TRUE) {
- jsize dstLength = env->GetArrayLength(dest);
-
- env->SetByteArrayRegion(dest, 0, dstLength, dstPtr);
- }
-
- env->ReleaseByteArrayElements(src, srcPtr, JNI_ABORT);
- env->ReleaseByteArrayElements(dest, dstPtr, JNI_ABORT);
-
- return result;
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_processReverseStream
-(JNIEnv * env, jobject caller, jbyteArray src, jobject inputConfig, jobject outputConfig, jbyteArray dest)
-{
- webrtc::AudioProcessing * apm = GetHandle(env, caller);
- CHECK_HANDLEV(apm, 0);
-
- webrtc::StreamConfig srcConfig = jni::AudioProcessingStreamConfig::toNative(env, jni::JavaLocalRef(env, inputConfig));
- webrtc::StreamConfig dstConfig = jni::AudioProcessingStreamConfig::toNative(env, jni::JavaLocalRef(env, outputConfig));
-
- jboolean isDstCopy = JNI_FALSE;
-
- jbyte * srcPtr = env->GetByteArrayElements(src, nullptr);
- jbyte * dstPtr = env->GetByteArrayElements(dest, &isDstCopy);
-
- const int16_t * srcFrame = reinterpret_cast(srcPtr);
- int16_t * dstFrame = reinterpret_cast(dstPtr);
-
- int result;
-
- if (srcConfig.num_channels() == 1 && dstConfig.num_channels() == 2) {
- // Up-mixing, only mono to stereo.
- // For complex channel layouts a channel mixer is required.
-
- const size_t srcNumSamples = srcConfig.num_samples();
- const size_t dstNumChannels = dstConfig.num_channels();
- const size_t frameSize = srcNumSamples * dstNumChannels;
-
- if (frameSize > webrtc::AudioFrame::kMaxDataSizeSamples) {
- return -9;
- }
-
- for (int i = static_cast(srcNumSamples) - 1; i >= 0; i--) {
- for (size_t j = 0; j < dstNumChannels; ++j) {
- dstFrame[dstNumChannels * i + j] = srcFrame[i];
- }
- }
-
- srcConfig.set_num_channels(dstNumChannels);
-
- result = apm->ProcessReverseStream(dstFrame, srcConfig, dstConfig, dstFrame);
- }
- else {
- // Will also down-mix if required, e.g. from stereo to mono.
- result = apm->ProcessReverseStream(srcFrame, srcConfig, dstConfig, dstFrame);
- }
-
- if (isDstCopy == JNI_TRUE) {
- jsize dstLength = env->GetArrayLength(dest);
-
- env->SetByteArrayRegion(dest, 0, dstLength, dstPtr);
- }
-
- env->ReleaseByteArrayElements(src, srcPtr, JNI_ABORT);
- env->ReleaseByteArrayElements(dest, dstPtr, JNI_ABORT);
-
- return result;
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_dispose
-(JNIEnv * env, jobject caller)
-{
- webrtc::AudioProcessing * apm = GetHandle(env, caller);
- CHECK_HANDLE(apm);
-
- rtc::RefCountReleaseStatus status = apm->Release();
-
- if (status != rtc::RefCountReleaseStatus::kDroppedLastRef) {
- RTC_LOG(LS_WARNING) << "Native object was not deleted. A reference is still around somewhere.";
- }
-
- SetHandle(env, caller, nullptr);
-
- apm = nullptr;
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_initialize
-(JNIEnv * env, jobject caller)
-{
- rtc::scoped_refptr apm = webrtc::AudioProcessingBuilder().Create();
-
- if (!apm) {
- env->Throw(jni::JavaError(env, "Create AudioProcessing failed"));
- return;
- }
-
- SetHandle(env, caller, apm.release());
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_updateStats
-(JNIEnv* env, jobject caller)
-{
- webrtc::AudioProcessing * apm = GetHandle(env, caller);
- CHECK_HANDLE(apm);
-
- jni::AudioProcessing::updateStats(apm->GetStatistics(), env, jni::JavaLocalRef(env, caller));
+/*
+ * Copyright 2021 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "JNI_AudioProcessing.h"
+#include "Exception.h"
+#include "JavaArrayList.h"
+#include "JavaEnums.h"
+#include "JavaError.h"
+#include "JavaObject.h"
+#include "JavaRef.h"
+#include "JavaString.h"
+#include "JavaUtils.h"
+
+#include "media/audio/AudioProcessing.h"
+#include "media/audio/AudioProcessingConfig.h"
+#include "media/audio/AudioProcessingStreamConfig.h"
+#include "api/audio/audio_frame.h"
+#include "api/audio/audio_processing.h"
+#include "api/audio/builtin_audio_processing_builder.h"
+#include "api/environment/environment_factory.h"
+#include "api/scoped_refptr.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/logging.h"
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_applyConfig
+(JNIEnv * env, jobject caller, jobject config)
+{
+ webrtc::AudioProcessing * apm = GetHandle(env, caller);
+ CHECK_HANDLE(apm);
+
+ apm->ApplyConfig(jni::AudioProcessingConfig::toNative(env, jni::JavaLocalRef(env, config)));
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_setStreamDelayMs
+(JNIEnv * env, jobject caller, jint delayMs)
+{
+ webrtc::AudioProcessing * apm = GetHandle(env, caller);
+ CHECK_HANDLE(apm);
+
+ apm->set_stream_delay_ms(delayMs);
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_getStreamDelayMs
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioProcessing * apm = GetHandle(env, caller);
+ CHECK_HANDLEV(apm, 0);
+
+ return apm->stream_delay_ms();
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_processStream
+(JNIEnv * env, jobject caller, jbyteArray src, jobject inputConfig, jobject outputConfig, jbyteArray dest)
+{
+ webrtc::AudioProcessing * apm = GetHandle(env, caller);
+ CHECK_HANDLEV(apm, 0);
+
+ webrtc::StreamConfig srcConfig = jni::AudioProcessingStreamConfig::toNative(env, jni::JavaLocalRef(env, inputConfig));
+ webrtc::StreamConfig dstConfig = jni::AudioProcessingStreamConfig::toNative(env, jni::JavaLocalRef(env, outputConfig));
+
+ jboolean isDstCopy = JNI_FALSE;
+
+ jbyte * srcPtr = env->GetByteArrayElements(src, NULL);
+ jbyte * dstPtr = env->GetByteArrayElements(dest, &isDstCopy);
+
+ const int16_t * srcFrame = reinterpret_cast(srcPtr);
+ int16_t * dstFrame = reinterpret_cast(dstPtr);
+
+ int result;
+
+ if (srcConfig.num_channels() == 1 && dstConfig.num_channels() == 2) {
+ // Up-mixing, only mono to stereo.
+ // For complex channel layouts a channel mixer is required.
+
+ const size_t srcNumSamples = srcConfig.num_samples();
+ const size_t dstNumChannels = dstConfig.num_channels();
+ const size_t frameSize = srcNumSamples * dstNumChannels;
+
+ if (frameSize > webrtc::AudioFrame::kMaxDataSizeSamples) {
+ return -9;
+ }
+
+ for (int i = static_cast(srcNumSamples) - 1; i >= 0; i--) {
+ for (size_t j = 0; j < dstNumChannels; ++j) {
+ dstFrame[dstNumChannels * i + j] = srcFrame[i];
+ }
+ }
+
+ srcConfig.set_num_channels(dstNumChannels);
+
+ result = apm->ProcessStream(dstFrame, srcConfig, dstConfig, dstFrame);
+ }
+ else {
+ // Will also down-mix if required, e.g. from stereo to mono.
+ result = apm->ProcessStream(srcFrame, srcConfig, dstConfig, dstFrame);
+ }
+
+ if (isDstCopy == JNI_TRUE) {
+ jsize dstLength = env->GetArrayLength(dest);
+
+ env->SetByteArrayRegion(dest, 0, dstLength, dstPtr);
+ }
+
+ env->ReleaseByteArrayElements(src, srcPtr, JNI_ABORT);
+ env->ReleaseByteArrayElements(dest, dstPtr, JNI_ABORT);
+
+ return result;
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_processReverseStream
+(JNIEnv * env, jobject caller, jbyteArray src, jobject inputConfig, jobject outputConfig, jbyteArray dest)
+{
+ webrtc::AudioProcessing * apm = GetHandle(env, caller);
+ CHECK_HANDLEV(apm, 0);
+
+ webrtc::StreamConfig srcConfig = jni::AudioProcessingStreamConfig::toNative(env, jni::JavaLocalRef(env, inputConfig));
+ webrtc::StreamConfig dstConfig = jni::AudioProcessingStreamConfig::toNative(env, jni::JavaLocalRef(env, outputConfig));
+
+ jboolean isDstCopy = JNI_FALSE;
+
+ jbyte * srcPtr = env->GetByteArrayElements(src, nullptr);
+ jbyte * dstPtr = env->GetByteArrayElements(dest, &isDstCopy);
+
+ const int16_t * srcFrame = reinterpret_cast(srcPtr);
+ int16_t * dstFrame = reinterpret_cast(dstPtr);
+
+ int result;
+
+ if (srcConfig.num_channels() == 1 && dstConfig.num_channels() == 2) {
+ // Up-mixing, only mono to stereo.
+ // For complex channel layouts a channel mixer is required.
+
+ const size_t srcNumSamples = srcConfig.num_samples();
+ const size_t dstNumChannels = dstConfig.num_channels();
+ const size_t frameSize = srcNumSamples * dstNumChannels;
+
+ if (frameSize > webrtc::AudioFrame::kMaxDataSizeSamples) {
+ return -9;
+ }
+
+ for (int i = static_cast(srcNumSamples) - 1; i >= 0; i--) {
+ for (size_t j = 0; j < dstNumChannels; ++j) {
+ dstFrame[dstNumChannels * i + j] = srcFrame[i];
+ }
+ }
+
+ srcConfig.set_num_channels(dstNumChannels);
+
+ result = apm->ProcessReverseStream(dstFrame, srcConfig, dstConfig, dstFrame);
+ }
+ else {
+ // Will also down-mix if required, e.g. from stereo to mono.
+ result = apm->ProcessReverseStream(srcFrame, srcConfig, dstConfig, dstFrame);
+ }
+
+ if (isDstCopy == JNI_TRUE) {
+ jsize dstLength = env->GetArrayLength(dest);
+
+ env->SetByteArrayRegion(dest, 0, dstLength, dstPtr);
+ }
+
+ env->ReleaseByteArrayElements(src, srcPtr, JNI_ABORT);
+ env->ReleaseByteArrayElements(dest, dstPtr, JNI_ABORT);
+
+ return result;
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_dispose
+(JNIEnv * env, jobject caller)
+{
+ webrtc::AudioProcessing * apm = GetHandle(env, caller);
+ CHECK_HANDLE(apm);
+
+ webrtc::RefCountReleaseStatus status = apm->Release();
+
+ if (status != webrtc::RefCountReleaseStatus::kDroppedLastRef) {
+ RTC_LOG(LS_WARNING) << "Native object was not deleted. A reference is still around somewhere.";
+ }
+
+ SetHandle(env, caller, nullptr);
+
+ apm = nullptr;
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_initialize
+(JNIEnv * env, jobject caller)
+{
+ rtc::scoped_refptr apm = webrtc::BuiltinAudioProcessingBuilder().Build(webrtc::CreateEnvironment());
+
+ if (!apm) {
+ env->Throw(jni::JavaError(env, "Create AudioProcessing failed"));
+ return;
+ }
+
+ SetHandle(env, caller, apm.release());
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioProcessing_updateStats
+(JNIEnv* env, jobject caller)
+{
+ webrtc::AudioProcessing * apm = GetHandle(env, caller);
+ CHECK_HANDLE(apm);
+
+ jni::AudioProcessing::updateStats(apm->GetStatistics(), env, jni::JavaLocalRef(env, caller));
}
\ No newline at end of file
diff --git a/webrtc-jni/src/main/cpp/src/JNI_AudioResampler.cpp b/webrtc-jni/src/main/cpp/src/JNI_AudioResampler.cpp
index e5989b05..e8de6f3e 100644
--- a/webrtc-jni/src/main/cpp/src/JNI_AudioResampler.cpp
+++ b/webrtc-jni/src/main/cpp/src/JNI_AudioResampler.cpp
@@ -1,76 +1,81 @@
-/*
- * Copyright 2021 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "JNI_AudioResampler.h"
-#include "Exception.h"
-#include "JavaObject.h"
-#include "JavaRef.h"
-#include "JavaUtils.h"
-
-#include "common_audio/resampler/include/push_resampler.h"
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_dispose
-(JNIEnv * env, jobject caller)
-{
- webrtc::PushResampler * resampler = GetHandle>(env, caller);
- CHECK_HANDLE(resampler);
-
- delete resampler;
-
- SetHandle(env, caller, nullptr);
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_initialize
-(JNIEnv * env, jobject caller)
-{
- webrtc::PushResampler * resampler = new webrtc::PushResampler();
-
- SetHandle(env, caller, resampler);
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_resetInternal
-(JNIEnv* env, jobject caller, jint sourceRate, jint targetRate, jint channels)
-{
- webrtc::PushResampler * resampler = GetHandle>(env, caller);
- CHECK_HANDLE(resampler);
-
- resampler->InitializeIfNeeded(sourceRate, targetRate, channels);
-}
-
-JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_resampleInternal
-(JNIEnv * env, jobject caller, jbyteArray samplesIn, jint nSamplesIn, jbyteArray samplesOut, jint maxSamplesOut)
-{
- webrtc::PushResampler * resampler = GetHandle>(env, caller);
- CHECK_HANDLEV(resampler, -1);
-
- jboolean isDstCopy = JNI_FALSE;
-
- jbyte * srcPtr = env->GetByteArrayElements(samplesIn, nullptr);
- jbyte * dstPtr = env->GetByteArrayElements(samplesOut, &isDstCopy);
-
- size_t result = resampler->Resample(reinterpret_cast(srcPtr), nSamplesIn, reinterpret_cast(dstPtr), maxSamplesOut);
-
- if (isDstCopy == JNI_TRUE) {
- jsize dstLength = env->GetArrayLength(samplesOut);
-
- env->SetByteArrayRegion(samplesOut, 0, dstLength, dstPtr);
- }
-
- env->ReleaseByteArrayElements(samplesIn, srcPtr, JNI_ABORT);
- env->ReleaseByteArrayElements(samplesOut, dstPtr, JNI_ABORT);
-
- return static_cast(result);
-}
+/*
+ * Copyright 2021 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "JNI_AudioResampler.h"
+#include "Exception.h"
+#include "JavaObject.h"
+#include "JavaRef.h"
+#include "JavaUtils.h"
+
+#include "common_audio/resampler/include/push_resampler.h"
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_dispose
+(JNIEnv * env, jobject caller)
+{
+ webrtc::PushResampler * resampler = GetHandle>(env, caller);
+ CHECK_HANDLE(resampler);
+
+ delete resampler;
+
+ SetHandle(env, caller, nullptr);
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_initialize
+(JNIEnv * env, jobject caller)
+{
+ webrtc::PushResampler * resampler = new webrtc::PushResampler();
+
+ SetHandle(env, caller, resampler);
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_initialize
+(JNIEnv* env, jobject caller, jint srcSamplesPerChannel, jint dstSamplesPerChannel, jint channels)
+{
+ webrtc::PushResampler * resampler = new webrtc::PushResampler(srcSamplesPerChannel, dstSamplesPerChannel, channels);
+
+ SetHandle(env, caller, resampler);
+}
+
+JNIEXPORT jint JNICALL Java_dev_onvoid_webrtc_media_audio_AudioResampler_resampleInternal
+(JNIEnv * env, jobject caller, jbyteArray samplesIn, jint srcSamplesPerChannel, jbyteArray samplesOut, jint dstSamplesPerChannel, jint channels)
+{
+ webrtc::PushResampler * resampler = GetHandle>(env, caller);
+ CHECK_HANDLEV(resampler, -1);
+
+ jboolean isDstCopy = JNI_FALSE;
+
+ jbyte * srcPtr = env->GetByteArrayElements(samplesIn, nullptr);
+ jbyte * dstPtr = env->GetByteArrayElements(samplesOut, &isDstCopy);
+
+ int16_t * src16Ptr = reinterpret_cast(srcPtr);
+ int16_t * dst16Ptr = reinterpret_cast(dstPtr);
+
+ webrtc::InterleavedView src(src16Ptr, srcSamplesPerChannel, channels);
+ webrtc::InterleavedView dst(dst16Ptr, dstSamplesPerChannel, channels);
+
+ size_t result = resampler->Resample(src, dst);
+
+ if (isDstCopy == JNI_TRUE) {
+ jsize dstLength = env->GetArrayLength(samplesOut);
+
+ env->SetByteArrayRegion(samplesOut, 0, dstLength, dstPtr);
+ }
+
+ env->ReleaseByteArrayElements(samplesIn, srcPtr, JNI_ABORT);
+ env->ReleaseByteArrayElements(samplesOut, dstPtr, JNI_ABORT);
+
+ return static_cast(result);
+}
diff --git a/webrtc-jni/src/main/cpp/src/JNI_DesktopCapturer.cpp b/webrtc-jni/src/main/cpp/src/JNI_DesktopCapturer.cpp
index 94e3f2c7..e1df6ed9 100644
--- a/webrtc-jni/src/main/cpp/src/JNI_DesktopCapturer.cpp
+++ b/webrtc-jni/src/main/cpp/src/JNI_DesktopCapturer.cpp
@@ -85,6 +85,15 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_desktop_DesktopCapture
capturer->setFocusSelectedSource(focus);
}
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_desktop_DesktopCapturer_setMaxFrameRate
+(JNIEnv * env, jobject caller, jint maxFrameRate)
+{
+ jni::DesktopCapturer * capturer = GetHandle(env, caller);
+ CHECK_HANDLE(capturer);
+
+ capturer->SetMaxFrameRate(maxFrameRate);
+}
+
JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_desktop_DesktopCapturer_start
(JNIEnv * env, jobject caller, jobject jcallback)
{
diff --git a/webrtc-jni/src/main/cpp/src/JNI_MediaStream.cpp b/webrtc-jni/src/main/cpp/src/JNI_MediaStream.cpp
index 14c2c909..efd192f9 100644
--- a/webrtc-jni/src/main/cpp/src/JNI_MediaStream.cpp
+++ b/webrtc-jni/src/main/cpp/src/JNI_MediaStream.cpp
@@ -1,121 +1,121 @@
-/*
- * Copyright 2019 Alex Andres
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "JNI_MediaStream.h"
-#include "api/WebRTCUtils.h"
-#include "JavaError.h"
-#include "JavaFactories.h"
-#include "JavaString.h"
-#include "JavaUtils.h"
-
-#include "api/media_stream_interface.h"
-#include "rtc_base/logging.h"
-
-JNIEXPORT jstring JNICALL Java_dev_onvoid_webrtc_media_MediaStream_id
-(JNIEnv * env, jobject caller)
-{
- webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
- CHECK_HANDLEV(stream, nullptr);
-
- return jni::JavaString::toJava(env, stream->id());
-}
-
-JNIEXPORT jobjectArray JNICALL Java_dev_onvoid_webrtc_media_MediaStream_getAudioTracks
-(JNIEnv * env, jobject caller)
-{
- webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
- CHECK_HANDLEV(stream, nullptr);
-
- jni::JavaLocalRef objectArray;
-
- try {
- objectArray = jni::createObjectArray(env, stream->GetAudioTracks());
- }
- catch (...) {
- ThrowCxxJavaException(env);
- }
-
- return objectArray;
-}
-
-JNIEXPORT jobjectArray JNICALL Java_dev_onvoid_webrtc_media_MediaStream_getVideoTracks
-(JNIEnv * env, jobject caller)
-{
- webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
- CHECK_HANDLEV(stream, nullptr);
-
- jni::JavaLocalRef objectArray;
-
- try {
- objectArray = jni::createObjectArray(env, stream->GetVideoTracks());
- }
- catch (...) {
- ThrowCxxJavaException(env);
- }
-
- return objectArray;
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_MediaStream_addTrack
-(JNIEnv * env, jobject caller, jobject jTrack)
-{
- webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
- CHECK_HANDLE(stream);
-
- webrtc::MediaStreamTrackInterface * track = GetHandle(env, jTrack);
- CHECK_HANDLE(track);
-
- if (webrtc::AudioTrackInterface * t = dynamic_cast(track)) {
- stream->AddTrack(t);
- }
- else if (webrtc::VideoTrackInterface * t = dynamic_cast(track)) {
- stream->AddTrack(t);
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_MediaStream_removeTrack
-(JNIEnv * env, jobject caller, jobject jTrack)
-{
- webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
- CHECK_HANDLE(stream);
-
- webrtc::MediaStreamTrackInterface * track = GetHandle(env, jTrack);
- CHECK_HANDLE(track);
-
- if (webrtc::AudioTrackInterface * t = dynamic_cast(track)) {
- stream->RemoveTrack(t);
- }
- else if (webrtc::VideoTrackInterface * t = dynamic_cast(track)) {
- stream->RemoveTrack(t);
- }
-}
-
-JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_MediaStream_dispose
-(JNIEnv * env, jobject caller)
-{
- webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
- CHECK_HANDLE(stream);
-
- rtc::RefCountReleaseStatus status = stream->Release();
-
- if (status != rtc::RefCountReleaseStatus::kDroppedLastRef) {
- RTC_LOG(LS_WARNING) << "Native object was not deleted. A reference is still around somewhere.";
- }
-
- SetHandle(env, caller, nullptr);
-
- stream = nullptr;
+/*
+ * Copyright 2019 Alex Andres
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "JNI_MediaStream.h"
+#include "api/WebRTCUtils.h"
+#include "JavaError.h"
+#include "JavaFactories.h"
+#include "JavaString.h"
+#include "JavaUtils.h"
+
+#include "api/media_stream_interface.h"
+#include "rtc_base/logging.h"
+
+JNIEXPORT jstring JNICALL Java_dev_onvoid_webrtc_media_MediaStream_id
+(JNIEnv * env, jobject caller)
+{
+ webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
+ CHECK_HANDLEV(stream, nullptr);
+
+ return jni::JavaString::toJava(env, stream->id());
+}
+
+JNIEXPORT jobjectArray JNICALL Java_dev_onvoid_webrtc_media_MediaStream_getAudioTracks
+(JNIEnv * env, jobject caller)
+{
+ webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
+ CHECK_HANDLEV(stream, nullptr);
+
+ jni::JavaLocalRef objectArray;
+
+ try {
+ objectArray = jni::createObjectArray(env, stream->GetAudioTracks());
+ }
+ catch (...) {
+ ThrowCxxJavaException(env);
+ }
+
+ return objectArray;
+}
+
+JNIEXPORT jobjectArray JNICALL Java_dev_onvoid_webrtc_media_MediaStream_getVideoTracks
+(JNIEnv * env, jobject caller)
+{
+ webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
+ CHECK_HANDLEV(stream, nullptr);
+
+ jni::JavaLocalRef objectArray;
+
+ try {
+ objectArray = jni::createObjectArray(env, stream->GetVideoTracks());
+ }
+ catch (...) {
+ ThrowCxxJavaException(env);
+ }
+
+ return objectArray;
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_MediaStream_addTrack
+(JNIEnv * env, jobject caller, jobject jTrack)
+{
+ webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
+ CHECK_HANDLE(stream);
+
+ webrtc::MediaStreamTrackInterface * track = GetHandle(env, jTrack);
+ CHECK_HANDLE(track);
+
+ if (webrtc::AudioTrackInterface * t = dynamic_cast(track)) {
+ stream->AddTrack(rtc::scoped_refptr(t));
+ }
+ else if (webrtc::VideoTrackInterface * t = dynamic_cast(track)) {
+ stream->AddTrack(rtc::scoped_refptr(t));
+ }
+}
+
+JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_MediaStream_removeTrack
+(JNIEnv * env, jobject caller, jobject jTrack)
+{
+ webrtc::MediaStreamInterface * stream = GetHandle(env, caller);
+ CHECK_HANDLE(stream);
+
+ webrtc::MediaStreamTrackInterface * track = GetHandle(env, jTrack);
+ CHECK_HANDLE(track);
+
+ if (webrtc::AudioTrackInterface * t = dynamic_cast(track)) {
+ stream->RemoveTrack(rtc::scoped_refptr(t));
+ }
+ else if (webrtc::VideoTrackInterface * t = dynamic_cast(track)) {
+ stream->RemoveTrack(rtc::scoped_refptr