Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/nvenc-av1-encoding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
webrtc-sys: patch
libwebrtc: patch
livekit: patch
livekit-ffi: patch
---

Add NVIDIA NVENC AV1 encoding when the GPU reports AV1 encode support.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Use this SDK to add realtime video, audio and data features to your Rust app. By
- [x] Dynacast
- [x] Hardware video enc/dec
- [x] H.264, H.265 using VideoToolbox (MacOS/iOS)
- [x] H.264, H.265 on NVidia discrete GPUs (Linux)
- [x] H.264, H.265, AV1 on NVidia discrete GPUs (Linux)
- [x] H.264, H.265 on AMD CPUs & GPUs (Linux)
- [x] H.264, H.265, AV1 on NVidia Jetson (Linux)
- Supported Platforms
Expand Down Expand Up @@ -172,6 +172,29 @@ match event {

## Building

### Linux

Building on Ubuntu 24 x86_64:

```
# install required libs
sudo apt install -y \
libglib2.0-dev build-essential clang \
libclang-dev libc6-dev pkg-config libjpeg-turbo8-dev

# install cuda-toolkit if you have an Nvidia GPU and want to use NVENC for video encoding
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt update
sudo apt install -y cuda-toolkit

# ensure CUDA_HOME env var is set
export CUDA_HOME="$(dirname "$(dirname "$(sudo find /usr/local /usr -path '*/include/cuda.h' -print 2>/dev/null | grep -v '/linux/' | sort -V | tail -1)")")"

cargo build

```

### MacOS

When building on MacOS, `-ObjC` linker flag is needed. LiveKit's WebRTC implementation make use of ObjectiveC libraries on the Mac. You may get the following error if the app isn't linked with ObjC:
Expand Down
3 changes: 2 additions & 1 deletion webrtc-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ fn main() {
"src/prohibit_libsrtp_initialization.cpp",
"src/apm.cpp",
"src/audio_mixer.cpp",
"src/av1_bitstream.cpp",
"src/packet_trailer.cpp",
"src/packet_trailer_av1.cpp",
]);
Expand Down Expand Up @@ -231,7 +232,6 @@ fn main() {
.file("src/jetson/h264_encoder_impl.cpp")
.file("src/jetson/h265_encoder_impl.cpp")
.file("src/jetson/av1_encoder_impl.cpp")
.file("src/jetson/jetson_av1_bitstream.cpp")
.file("src/jetson/jetson_encoder_factory.cpp")
.flag("-DUSE_JETSON_VIDEO_CODEC=1");

Expand Down Expand Up @@ -287,6 +287,7 @@ fn main() {
.file("src/nvidia/NvCodec/NvCodec/NvEncoder/NvEncoderCuda.cpp")
.file("src/nvidia/h264_encoder_impl.cpp")
.file("src/nvidia/h265_encoder_impl.cpp")
.file("src/nvidia/av1_encoder_impl.cpp")
.file("src/nvidia/h264_decoder_impl.cpp")
.file("src/nvidia/h265_decoder_impl.cpp")
.file("src/nvidia/nvidia_decoder_factory.cpp")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

#include "jetson_av1_bitstream.h"
#include "av1_bitstream.h"

#include <algorithm>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
*/

#ifndef WEBRTC_JETSON_AV1_BITSTREAM_H_
#define WEBRTC_JETSON_AV1_BITSTREAM_H_
#ifndef WEBRTC_AV1_BITSTREAM_H_
#define WEBRTC_AV1_BITSTREAM_H_

#include <cstddef>
#include <cstdint>
Expand Down Expand Up @@ -61,4 +61,4 @@ bool IsWebRtcParseable(const uint8_t* data, size_t len);
} // namespace av1
} // namespace livekit

#endif // WEBRTC_JETSON_AV1_BITSTREAM_H_
#endif // WEBRTC_AV1_BITSTREAM_H_
2 changes: 1 addition & 1 deletion webrtc-sys/src/jetson/av1_encoder_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "api/video/video_codec_constants.h"
#include "api/video_codecs/scalability_mode.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "jetson_av1_bitstream.h"
#include "../av1_bitstream.h"
#include "livekit/dmabuf_video_frame_buffer.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_error_codes.h"
Expand Down
32 changes: 32 additions & 0 deletions webrtc-sys/src/nvidia/NvCodec/NvCodec/NvEncoder/NvEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,38 @@ bool NvEncoder::Reconfigure(
return true;
}

bool NvEncoder::SetRates(uint32_t frameRate, uint32_t averageBitrate) {
if (!IsHWEncoderInitialized()) {
return false;
}
if (frameRate == 0) {
frameRate = 1;
}

NV_ENC_RECONFIGURE_PARAMS reconfigureParams = {};
reconfigureParams.version = NV_ENC_RECONFIGURE_PARAMS_VER;

NV_ENC_CONFIG encodeConfig = {};
encodeConfig.version = NV_ENC_CONFIG_VER;
reconfigureParams.reInitEncodeParams.version = NV_ENC_INITIALIZE_PARAMS_VER;
reconfigureParams.reInitEncodeParams.encodeConfig = &encodeConfig;

GetInitializeParams(&reconfigureParams.reInitEncodeParams);

reconfigureParams.reInitEncodeParams.frameRateNum = frameRate;
reconfigureParams.reInitEncodeParams.frameRateDen = 1;

encodeConfig.rcParams.averageBitRate = averageBitrate;
encodeConfig.rcParams.vbvBufferSize = (averageBitrate / frameRate) * 5;
encodeConfig.rcParams.vbvInitialDelay = encodeConfig.rcParams.vbvBufferSize;

try {
return Reconfigure(&reconfigureParams);
} catch (const NVENCException&) {
return false;
}
}

NV_ENC_REGISTERED_PTR NvEncoder::RegisterResource(
void* pBuffer,
NV_ENC_INPUT_RESOURCE_TYPE eResourceType,
Expand Down
7 changes: 7 additions & 0 deletions webrtc-sys/src/nvidia/NvCodec/NvCodec/NvEncoder/NvEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ class NvEncoder {
*/
bool Reconfigure(const NV_ENC_RECONFIGURE_PARAMS* pReconfigureParams);

/**
* @brief Dynamically updates the encode bitrate and framerate on the live
* session. Returns false if the encoder is not initialized or reconfigure
* fails.
*/
bool SetRates(uint32_t frameRate, uint32_t averageBitrate);

/**
* @brief This function is used to get the next available input buffer.
* Applications must call this function to obtain a pointer to the next
Expand Down
Loading
Loading