Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ int NvDecoder::HandlePictureDecode(CUVIDPICPARAMS *pPicParams) {
}
m_nPicNumInDecodeOrder[pPicParams->CurrPicIdx] = m_nDecodePicCnt++;
CUDA_DRVAPI_CALL(cuCtxPushCurrent(m_cuContext));
NVDEC_API_CALL(cuvidDecodePicture(m_hDecoder, pPicParams));
cuvidDecodePicture(m_hDecoder, pPicParams);
if (m_bForce_zero_latency && ((!pPicParams->field_pic_flag) || (pPicParams->second_field)))
{
CUVIDPARSERDISPINFO dispInfo;
Expand Down
80 changes: 77 additions & 3 deletions webrtc-sys/src/nvidia/cuda_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,58 @@ static bool load_cuda_modules() {
return true;
}

static bool check_cuda_device() {
int device_count = 0;
int driver_version = 0;

CUCTX_CUDA_CALL_ERROR(cuDriverGetVersion(&driver_version));
if (kRequiredDriverVersion > driver_version) {
RTC_LOG(LS_ERROR)
<< "CUDA driver version is not higher than the required version. "
<< driver_version;
return false;
}

CUresult result = cuInit(0);
if (result != CUDA_SUCCESS) {
RTC_LOG(LS_ERROR) << "Failed to initialize CUDA.";
return false;
}

result = cuDeviceGetCount(&device_count);
if (result != CUDA_SUCCESS) {
RTC_LOG(LS_ERROR) << "Failed to get CUDA device count.";
return false;
}

if (device_count == 0) {
RTC_LOG(LS_ERROR) << "No CUDA devices found.";
return false;
}

return true;
}

CudaContext* CudaContext::GetInstance() {
static CudaContext instance;
return &instance;
}

bool CudaContext::IsAvailable() {
return load_cuda_modules() && check_cuda_device();
}

bool CudaContext::Initialize() {
// Initialize CUDA context

bool success = load_cuda_modules();
if (!success) {
std::cout << "Failed to load CUDA modules. maybe the NVIDIA driver is not installed?" << std::endl;
RTC_LOG(LS_ERROR) << "Failed to load CUDA modules. maybe the NVIDIA driver "
"is not installed?";
return false;
}

int numDevices = 0;
int num_devices = 0;
CUdevice cu_device = 0;
CUcontext context = nullptr;

Expand All @@ -84,7 +126,23 @@ bool CudaContext::Initialize() {
return false;
}

CUCTX_CUDA_CALL_ERROR(cuInit(0));
CUresult result = cuInit(0);
if (result != CUDA_SUCCESS) {
RTC_LOG(LS_ERROR) << "Failed to initialize CUDA.";
return false;
}

result = cuDeviceGetCount(&num_devices);
if (result != CUDA_SUCCESS) {
RTC_LOG(LS_ERROR) << "Failed to get CUDA device count.";
return false;
}

if (num_devices == 0) {
RTC_LOG(LS_ERROR) << "No CUDA devices found.";
return false;
}

CUCTX_CUDA_CALL_ERROR(cuDeviceGet(&cu_device, 0));

char device_name[80];
Expand All @@ -104,6 +162,22 @@ bool CudaContext::Initialize() {
return true;
}

CUcontext CudaContext::GetContext() const {
RTC_DCHECK(cu_context_ != nullptr);
// Ensure the context is current
CUcontext current;
if (cuCtxGetCurrent(&current) != CUDA_SUCCESS) {
throw;
}
if (cu_context_ == current) {
return cu_context_;
}
if (cuCtxSetCurrent(cu_context_) != CUDA_SUCCESS) {
throw;
}
return cu_context_;
}

void CudaContext::Shutdown() {
// Shutdown CUDA context
if (cu_context_) {
Expand Down
9 changes: 6 additions & 3 deletions webrtc-sys/src/nvidia/cuda_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ namespace livekit {
class CudaContext {
public:
CudaContext() = default;
~CudaContext() { Shutdown(); }
~CudaContext() = default;

static bool IsAvailable();

static CudaContext* GetInstance();
bool Initialize();
bool IsInitialized() const { return cu_context_ != nullptr; }
CUcontext GetContext() const { return cu_context_; }
CUdevice GetDevice() const { return cu_device_; }
CUcontext GetContext() const;

void Shutdown();

private:
Expand Down
1 change: 0 additions & 1 deletion webrtc-sys/src/nvidia/h264_encoder_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ int32_t NvidiaH264EncoderImpl::InitEncode(

int32_t NvidiaH264EncoderImpl::RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) {
RTC_DCHECK(callback);
encoded_image_callback_ = callback;
return WEBRTC_VIDEO_CODEC_OK;
}
Expand Down
12 changes: 5 additions & 7 deletions webrtc-sys/src/nvidia/nvidia_decoder_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <modules/video_coding/codecs/h264/include/h264.h>

#include <memory>
#include <iostream>

#include "cuda_context.h"
#include "h264_decoder_impl.h"
Expand Down Expand Up @@ -65,7 +64,7 @@ std::vector<SdpVideoFormat> SupportedNvDecoderCodecs(CUcontext context) {
}

NvidiaVideoDecoderFactory::NvidiaVideoDecoderFactory()
: cu_context_(std::make_unique<livekit::CudaContext>()) {
: cu_context_(livekit::CudaContext::GetInstance()) {
if (cu_context_->Initialize()) {
supported_formats_ = SupportedNvDecoderCodecs(cu_context_->GetContext());
} else {
Expand All @@ -78,12 +77,11 @@ NvidiaVideoDecoderFactory::NvidiaVideoDecoderFactory()
NvidiaVideoDecoderFactory::~NvidiaVideoDecoderFactory() {}

bool NvidiaVideoDecoderFactory::IsSupported() {
// Check if the CUDA context can be initialized.
auto cu_context = std::make_unique<livekit::CudaContext>();
if (!cu_context->Initialize()) {
std::cout << "Failed to initialize CUDA context." << std::endl;
if (!livekit::CudaContext::IsAvailable()) {
RTC_LOG(LS_WARNING) << "Cuda Context is not available.";
return false;
}

std::cout << "Nvidia Decoder is supported." << std::endl;
return true;
}
Expand All @@ -96,7 +94,7 @@ std::unique_ptr<VideoDecoder> NvidiaVideoDecoderFactory::Create(
if (format.IsSameCodec(supported_format)) {
// If the format is supported, create and return the encoder.
if (!cu_context_) {
cu_context_ = std::make_unique<livekit::CudaContext>();
cu_context_ = livekit::CudaContext::GetInstance();
if (!cu_context_->Initialize()) {
RTC_LOG(LS_ERROR) << "Failed to initialize CUDA context.";
return nullptr;
Expand Down
2 changes: 1 addition & 1 deletion webrtc-sys/src/nvidia/nvidia_decoder_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class NvidiaVideoDecoderFactory : public VideoDecoderFactory {

private:
std::vector<SdpVideoFormat> supported_formats_;
std::unique_ptr<livekit::CudaContext> cu_context_;
livekit::CudaContext* cu_context_;
};

} // namespace webrtc
Expand Down
9 changes: 3 additions & 6 deletions webrtc-sys/src/nvidia/nvidia_encoder_factory.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "nvidia_encoder_factory.h"

#include <memory>
#include <iostream>

#include "cuda_context.h"
#include "h264_encoder_impl.h"
Expand Down Expand Up @@ -30,10 +29,8 @@ NvidiaVideoEncoderFactory::NvidiaVideoEncoderFactory() {
NvidiaVideoEncoderFactory::~NvidiaVideoEncoderFactory() {}

bool NvidiaVideoEncoderFactory::IsSupported() {
// Check if the CUDA context can be initialized.
auto cu_context = std::make_unique<livekit::CudaContext>();
if (!cu_context->Initialize()) {
std::cout << "Failed to initialize CUDA context." << std::endl;
if (!livekit::CudaContext::IsAvailable()) {
RTC_LOG(LS_WARNING) << "Cuda Context is not available.";
return false;
}

Expand All @@ -49,7 +46,7 @@ std::unique_ptr<VideoEncoder> NvidiaVideoEncoderFactory::Create(
if (format.IsSameCodec(supported_format)) {
// If the format is supported, create and return the encoder.
if (!cu_context_) {
cu_context_ = std::make_unique<livekit::CudaContext>();
cu_context_ = livekit::CudaContext::GetInstance();
if (!cu_context_->Initialize()) {
RTC_LOG(LS_ERROR) << "Failed to initialize CUDA context.";
return nullptr;
Expand Down
2 changes: 1 addition & 1 deletion webrtc-sys/src/nvidia/nvidia_encoder_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class NvidiaVideoEncoderFactory : public VideoEncoderFactory {

private:
std::vector<SdpVideoFormat> supported_formats_;
std::unique_ptr<livekit::CudaContext> cu_context_;
livekit::CudaContext* cu_context_ = nullptr;
};

} // namespace webrtc
Expand Down
1 change: 0 additions & 1 deletion webrtc-sys/src/vaapi/h264_encoder_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ int32_t VAAPIH264EncoderWrapper::InitEncode(

int32_t VAAPIH264EncoderWrapper::RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) {
RTC_DCHECK(callback);
encoded_image_callback_ = callback;
return WEBRTC_VIDEO_CODEC_OK;
}
Expand Down
4 changes: 2 additions & 2 deletions webrtc-sys/src/vaapi/vaapi_display_drm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>

#ifdef IN_LIBVA
#include "va/drm/va_drm.h"
Expand Down Expand Up @@ -111,7 +110,8 @@ namespace livekit {
bool VaapiDisplayDrm::Open() {
va_display_ = va_open_display_drm(&drm_fd_);
if (!va_display_) {
std::cout << "Failed to open VA display. Maybe the AMD video driver or libva-dev/libdrm-dev is not installed?" << std::endl;
RTC_LOG(LS_ERROR) << "Failed to open VA drm display. Maybe the AMD video "
"driver or libva-dev/libdrm-dev is not installed?";
return false;
}
return true;
Expand Down
8 changes: 4 additions & 4 deletions webrtc-sys/src/vaapi/vaapi_encoder_factory.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#include "vaapi_encoder_factory.h"

#include <memory>
#include <iostream>

#include "h264_encoder_impl.h"

#include <iostream>
#include "rtc_base/logging.h"

#if defined(WIN32)
#include "vaapi_display_win32.h"
using VaapiDisplay = livekit::VaapiDisplayWin32;
#elif defined(__linux__)
#include "vaapi_display_drm.h"
using VaapiDisplay = livekit::VaapiDisplayDrm ;
using VaapiDisplay = livekit::VaapiDisplayDrm;
#endif

namespace webrtc {
Expand Down Expand Up @@ -41,7 +41,7 @@ bool VAAPIVideoEncoderFactory::IsSupported() {
// This could involve checking if the VAAPI display can be opened.
VaapiDisplay vaapi_display;
if (!vaapi_display.Open()) {
std::cerr << "Failed to open VAAPI display." << std::endl;
RTC_LOG(LS_WARNING) << "Failed to open VAAPI display.";
return false;
}

Expand Down
30 changes: 15 additions & 15 deletions webrtc-sys/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ add_definitions(-DWEBRTC_LIBRARY_IMPL)
add_definitions(-DWEBRTC_ENABLE_AVX2)

include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/../libwebrtc/linux-x64-release/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../libwebrtc/linux-x64-debug/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../libwebrtc/linux-x64-release/include/third_party/abseil-cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../libwebrtc/linux-x64-release/include/third_party/libyuv/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/nvidia/NvCodec/include"
Expand All @@ -63,19 +63,19 @@ add_executable(${BINARY_NAME}
"fileutils.cc"
"cpu/cpu_linux.cc"

#"benchmark_nvidia.cc"
#"../src/nvidia/NvCodec/NvCodec/NvDecoder/NvDecoder.cpp"
#"../src/nvidia/NvCodec/NvCodec/NvEncoder/NvEncoder.cpp"
#"../src/nvidia/NvCodec/NvCodec/NvEncoder/NvEncoderCuda.cpp"
#"../src/nvidia/h264_encoder_impl.cpp"
#"../src/nvidia/h264_decoder_impl.cpp"
#"../src/nvidia/nvidia_decoder_factory.cpp"
#"../src/nvidia/nvidia_encoder_factory.cpp"
#"../src/nvidia/cuda_context.cpp"
#"../src/nvidia/implib/libcuda.so.init.c"
#"../src/nvidia/implib/libcuda.so.tramp.S"
#"../src/nvidia/implib/libnvcuvid.so.init.c"
#"../src/nvidia/implib/libnvcuvid.so.tramp.S"
"benchmark_nvidia.cc"
"../src/nvidia/NvCodec/NvCodec/NvDecoder/NvDecoder.cpp"
"../src/nvidia/NvCodec/NvCodec/NvEncoder/NvEncoder.cpp"
"../src/nvidia/NvCodec/NvCodec/NvEncoder/NvEncoderCuda.cpp"
"../src/nvidia/h264_encoder_impl.cpp"
"../src/nvidia/h264_decoder_impl.cpp"
"../src/nvidia/nvidia_decoder_factory.cpp"
"../src/nvidia/nvidia_encoder_factory.cpp"
"../src/nvidia/cuda_context.cpp"
"../src/nvidia/implib/libcuda.so.init.c"
"../src/nvidia/implib/libcuda.so.tramp.S"
"../src/nvidia/implib/libnvcuvid.so.init.c"
"../src/nvidia/implib/libnvcuvid.so.tramp.S"

"benchmark_vaapi.cc"
"../src/vaapi/vaapi_display_drm.cpp"
Expand All @@ -89,4 +89,4 @@ add_executable(${BINARY_NAME}
)

target_link_libraries(${BINARY_NAME} ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(${BINARY_NAME} dl)
target_link_libraries(${BINARY_NAME} dl)
Loading
Loading