Add hardware accerleration valiation

This commit is contained in:
dijunkun
2023-09-21 11:26:08 +08:00
parent b4318cc8d6
commit 156172accb
7 changed files with 90 additions and 14 deletions

View File

@@ -727,7 +727,10 @@ int NvDecoder::Decode(const uint8_t *pData, int nSize, int nFlags,
if (!pData || nSize == 0) { if (!pData || nSize == 0) {
packet.flags |= CUVID_PKT_ENDOFSTREAM; 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; m_cuvidStream = 0;
return m_nDecodedFrame; return m_nDecodedFrame;

View File

@@ -10,8 +10,24 @@ VideoDecoderFactory::~VideoDecoderFactory() {}
std::unique_ptr<VideoDecoder> VideoDecoderFactory::CreateVideoDecoder( std::unique_ptr<VideoDecoder> VideoDecoderFactory::CreateVideoDecoder(
bool hardware_acceleration) { bool hardware_acceleration) {
if (hardware_acceleration) { if (hardware_acceleration) {
return std::make_unique<NvidiaVideoDecoder>(NvidiaVideoDecoder()); if (CheckIsHardwareAccerlerationSupported()) {
return std::make_unique<NvidiaVideoDecoder>(NvidiaVideoDecoder());
} else {
return nullptr;
}
} else { } else {
return std::make_unique<FfmpegVideoDecoder>(FfmpegVideoDecoder()); return std::make_unique<FfmpegVideoDecoder>(FfmpegVideoDecoder());
} }
}
bool VideoDecoderFactory::CheckIsHardwareAccerlerationSupported() {
CUresult cuResult;
CUvideoctxlock cudaCtxLock;
cuResult = cuvidCtxLockCreate(&cudaCtxLock, 0);
if (cuResult != CUDA_SUCCESS) {
return false;
}
return true;
} }

View File

@@ -9,6 +9,8 @@ class VideoDecoderFactory {
static std::unique_ptr<VideoDecoder> CreateVideoDecoder( static std::unique_ptr<VideoDecoder> CreateVideoDecoder(
bool hardware_acceleration); bool hardware_acceleration);
static bool CheckIsHardwareAccerlerationSupported();
}; };
#endif #endif

View File

@@ -10,8 +10,29 @@ VideoEncoderFactory::~VideoEncoderFactory() {}
std::unique_ptr<VideoEncoder> VideoEncoderFactory::CreateVideoEncoder( std::unique_ptr<VideoEncoder> VideoEncoderFactory::CreateVideoEncoder(
bool hardware_acceleration) { bool hardware_acceleration) {
if (hardware_acceleration) { if (hardware_acceleration) {
return std::make_unique<NvidiaVideoEncoder>(NvidiaVideoEncoder()); if (CheckIsHardwareAccerlerationSupported()) {
return std::make_unique<NvidiaVideoEncoder>(NvidiaVideoEncoder());
} else {
return nullptr;
}
} else { } else {
return std::make_unique<FFmpegVideoEncoder>(FFmpegVideoEncoder()); return std::make_unique<FFmpegVideoEncoder>(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;
}

View File

@@ -9,6 +9,8 @@ class VideoEncoderFactory {
static std::unique_ptr<VideoEncoder> CreateVideoEncoder( static std::unique_ptr<VideoEncoder> CreateVideoEncoder(
bool hardware_acceleration); bool hardware_acceleration);
static bool CheckIsHardwareAccerlerationSupported();
}; };
#endif #endif

View File

@@ -67,7 +67,7 @@ int PeerConnection::Init(PeerConnectionParams params,
on_receive_video_ = [this](const char *data, size_t size, const char *user_id, on_receive_video_ = [this](const char *data, size_t size, const char *user_id,
size_t user_id_size) { size_t user_id_size) {
int num_frame_returned = video_decoder->Decode( int num_frame_returned = video_decoder_->Decode(
(uint8_t *)data, size, (uint8_t *)data, size,
[this, user_id, user_id_size](VideoFrame video_frame) { [this, user_id, user_id_size](VideoFrame video_frame) {
if (on_receive_video_buffer_) { if (on_receive_video_buffer_) {
@@ -109,15 +109,45 @@ int PeerConnection::Init(PeerConnectionParams params,
do { do {
} while (SignalStatus::Connected != GetSignalStatus()); } 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]; 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; return 0;
} }
@@ -315,7 +345,7 @@ int PeerConnection::SendVideoData(const char *data, size_t size) {
return -1; return -1;
} }
int ret = video_encoder->Encode( int ret = video_encoder_->Encode(
(uint8_t *)data, size, [this](char *encoded_frame, size_t size) -> int { (uint8_t *)data, size, [this](char *encoded_frame, size_t size) -> int {
for (auto &ice_trans : ice_transmission_list_) { for (auto &ice_trans : ice_transmission_list_) {
// LOG_ERROR("H264 frame size: [{}]", size); // LOG_ERROR("H264 frame size: [{}]", size);

View File

@@ -54,6 +54,8 @@ class PeerConnection {
int Init(PeerConnectionParams params, const std::string &transmission_id, int Init(PeerConnectionParams params, const std::string &transmission_id,
const std::string &user_id); const std::string &user_id);
int CreateVideoCodec(bool hardware_acceleration);
void ProcessSignal(const std::string &signal); void ProcessSignal(const std::string &signal);
int RequestTransmissionMemberList(const std::string &transmission_id); int RequestTransmissionMemberList(const std::string &transmission_id);
@@ -102,8 +104,8 @@ class PeerConnection {
char *nv12_data_ = nullptr; char *nv12_data_ = nullptr;
private: private:
std::unique_ptr<VideoEncoder> video_encoder = nullptr; std::unique_ptr<VideoEncoder> video_encoder_ = nullptr;
std::unique_ptr<VideoDecoder> video_decoder = nullptr; std::unique_ptr<VideoDecoder> video_decoder_ = nullptr;
bool hardware_accelerated_encode_ = false; bool hardware_accelerated_encode_ = false;
bool hardware_accelerated_decode_ = false; bool hardware_accelerated_decode_ = false;
}; };