diff --git a/src/media/video/decode/nvcodec/NvDecoder.cpp b/src/media/video/decode/nvcodec/NvDecoder.cpp index c9cd87e..4ecd395 100644 --- a/src/media/video/decode/nvcodec/NvDecoder.cpp +++ b/src/media/video/decode/nvcodec/NvDecoder.cpp @@ -727,7 +727,10 @@ int NvDecoder::Decode(const uint8_t *pData, int nSize, int nFlags, if (!pData || nSize == 0) { packet.flags |= CUVID_PKT_ENDOFSTREAM; } - NVDEC_API_CALL(cuvidParseVideoData(m_hParser, &packet)); + // NVDEC_API_CALL(cuvidParseVideoData(m_hParser, &packet)); + if (CUDA_SUCCESS != cuvidParseVideoData(m_hParser, &packet)) { + return 0; + } m_cuvidStream = 0; return m_nDecodedFrame; diff --git a/src/media/video/decode/video_decoder_factory.cpp b/src/media/video/decode/video_decoder_factory.cpp index 1003db6..13033ed 100644 --- a/src/media/video/decode/video_decoder_factory.cpp +++ b/src/media/video/decode/video_decoder_factory.cpp @@ -10,8 +10,24 @@ VideoDecoderFactory::~VideoDecoderFactory() {} std::unique_ptr VideoDecoderFactory::CreateVideoDecoder( bool hardware_acceleration) { if (hardware_acceleration) { - return std::make_unique(NvidiaVideoDecoder()); + if (CheckIsHardwareAccerlerationSupported()) { + return std::make_unique(NvidiaVideoDecoder()); + } else { + return nullptr; + } } else { return std::make_unique(FfmpegVideoDecoder()); } +} + +bool VideoDecoderFactory::CheckIsHardwareAccerlerationSupported() { + CUresult cuResult; + + CUvideoctxlock cudaCtxLock; + cuResult = cuvidCtxLockCreate(&cudaCtxLock, 0); + if (cuResult != CUDA_SUCCESS) { + return false; + } + + return true; } \ No newline at end of file diff --git a/src/media/video/decode/video_decoder_factory.h b/src/media/video/decode/video_decoder_factory.h index 33ac0be..ae903e1 100644 --- a/src/media/video/decode/video_decoder_factory.h +++ b/src/media/video/decode/video_decoder_factory.h @@ -9,6 +9,8 @@ class VideoDecoderFactory { static std::unique_ptr CreateVideoDecoder( bool hardware_acceleration); + + static bool CheckIsHardwareAccerlerationSupported(); }; #endif \ No newline at end of file diff --git a/src/media/video/encode/video_encoder_factory.cpp b/src/media/video/encode/video_encoder_factory.cpp index d3f1609..a4adfae 100644 --- a/src/media/video/encode/video_encoder_factory.cpp +++ b/src/media/video/encode/video_encoder_factory.cpp @@ -10,8 +10,29 @@ VideoEncoderFactory::~VideoEncoderFactory() {} std::unique_ptr VideoEncoderFactory::CreateVideoEncoder( bool hardware_acceleration) { if (hardware_acceleration) { - return std::make_unique(NvidiaVideoEncoder()); + if (CheckIsHardwareAccerlerationSupported()) { + return std::make_unique(NvidiaVideoEncoder()); + } else { + return nullptr; + } } else { return std::make_unique(FFmpegVideoEncoder()); } } + +bool VideoEncoderFactory::CheckIsHardwareAccerlerationSupported() { + CUresult cuResult; + NV_ENCODE_API_FUNCTION_LIST functionList = {NV_ENCODE_API_FUNCTION_LIST_VER}; + + cuResult = cuInit(0); + if (cuResult != CUDA_SUCCESS) { + return false; + } + + NVENCSTATUS nvEncStatus = NvEncodeAPICreateInstance(&functionList); + if (nvEncStatus != NV_ENC_SUCCESS) { + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/media/video/encode/video_encoder_factory.h b/src/media/video/encode/video_encoder_factory.h index 9a125d8..c2d3a96 100644 --- a/src/media/video/encode/video_encoder_factory.h +++ b/src/media/video/encode/video_encoder_factory.h @@ -9,6 +9,8 @@ class VideoEncoderFactory { static std::unique_ptr CreateVideoEncoder( bool hardware_acceleration); + + static bool CheckIsHardwareAccerlerationSupported(); }; #endif \ No newline at end of file diff --git a/src/pc/peer_connection.cpp b/src/pc/peer_connection.cpp index e709b2a..51cef0c 100644 --- a/src/pc/peer_connection.cpp +++ b/src/pc/peer_connection.cpp @@ -67,7 +67,7 @@ int PeerConnection::Init(PeerConnectionParams params, on_receive_video_ = [this](const char *data, size_t size, const char *user_id, size_t user_id_size) { - int num_frame_returned = video_decoder->Decode( + int num_frame_returned = video_decoder_->Decode( (uint8_t *)data, size, [this, user_id, user_id_size](VideoFrame video_frame) { if (on_receive_video_buffer_) { @@ -109,15 +109,45 @@ int PeerConnection::Init(PeerConnectionParams params, do { } while (SignalStatus::Connected != GetSignalStatus()); - video_encoder = - VideoEncoderFactory::CreateVideoEncoder(hardware_acceleration_); - video_encoder->Init(); - video_decoder = - VideoDecoderFactory::CreateVideoDecoder(hardware_acceleration_); - video_decoder->Init(); - nv12_data_ = new char[1280 * 720 * 3 / 2]; + if (0 != CreateVideoCodec(hardware_acceleration_)) { + return -1; + } + + return 0; +} + +int PeerConnection::CreateVideoCodec(bool hardware_acceleration) { + video_encoder_ = + VideoEncoderFactory::CreateVideoEncoder(hardware_acceleration_); + if (hardware_acceleration_ && !video_encoder_) { + video_encoder_ = VideoEncoderFactory::CreateVideoEncoder(false); + if (!video_encoder_) { + return -1; + } + } + if (0 != video_encoder_->Init()) { + video_encoder_ = VideoEncoderFactory::CreateVideoEncoder(false); + if (!video_encoder_ || 0 != video_encoder_->Init()) { + return -1; + } + } + + video_decoder_ = + VideoDecoderFactory::CreateVideoDecoder(hardware_acceleration_); + if (hardware_acceleration_ && !video_decoder_) { + video_decoder_ = VideoDecoderFactory::CreateVideoDecoder(false); + if (!video_decoder_) { + return -1; + } + } + if (0 != video_decoder_->Init()) { + video_decoder_ = VideoDecoderFactory::CreateVideoDecoder(false); + if (!video_decoder_ || video_decoder_->Init()) { + return -1; + } + } return 0; } @@ -315,7 +345,7 @@ int PeerConnection::SendVideoData(const char *data, size_t size) { return -1; } - int ret = video_encoder->Encode( + int ret = video_encoder_->Encode( (uint8_t *)data, size, [this](char *encoded_frame, size_t size) -> int { for (auto &ice_trans : ice_transmission_list_) { // LOG_ERROR("H264 frame size: [{}]", size); diff --git a/src/pc/peer_connection.h b/src/pc/peer_connection.h index b416583..0bc8bc3 100644 --- a/src/pc/peer_connection.h +++ b/src/pc/peer_connection.h @@ -54,6 +54,8 @@ class PeerConnection { int Init(PeerConnectionParams params, const std::string &transmission_id, const std::string &user_id); + int CreateVideoCodec(bool hardware_acceleration); + void ProcessSignal(const std::string &signal); int RequestTransmissionMemberList(const std::string &transmission_id); @@ -102,8 +104,8 @@ class PeerConnection { char *nv12_data_ = nullptr; private: - std::unique_ptr video_encoder = nullptr; - std::unique_ptr video_decoder = nullptr; + std::unique_ptr video_encoder_ = nullptr; + std::unique_ptr video_decoder_ = nullptr; bool hardware_accelerated_encode_ = false; bool hardware_accelerated_decode_ = false; };