From a794cd43b9df96e99883b8001eb195b01ea0eca1 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Wed, 20 Sep 2023 17:44:29 +0800 Subject: [PATCH] Use factory to create encoder/decoder --- ...peg_decoder.cpp => ffmpeg_video_decoder.cpp} | 10 +++++----- ...{ffmpeg_decoder.h => ffmpeg_video_decoder.h} | 12 ++++++------ ...{nv_decoder.cpp => nvidia_video_decoder.cpp} | 10 +++++----- .../{nv_decoder.h => nvidia_video_decoder.h} | 12 ++++++------ src/media/video/decode/video_decoder.h | 16 ++++++++++++++++ .../video/decode/video_decoder_factory.cpp | 17 +++++++++++++++++ src/media/video/decode/video_decoder_factory.h | 16 ++++++++++++++++ ...peg_encoder.cpp => ffmpeg_video_encoder.cpp} | 14 +++++++------- ...{ffmpeg_encoder.h => ffmpeg_video_encoder.h} | 12 +++++++----- ...{nv_encoder.cpp => nvidia_video_encoder.cpp} | 14 +++++++------- .../{nv_encoder.h => nvidia_video_encoder.h} | 11 ++++++----- src/media/video/encode/video_encoder.h | 16 ++++++++++++++++ .../video/encode/video_encoder_factory.cpp | 17 +++++++++++++++++ src/media/video/encode/video_encoder_factory.h | 16 ++++++++++++++++ src/pc/peer_connection.cpp | 15 +++++++++++---- src/pc/peer_connection.h | 14 +++++++++----- xmake.lua | 8 ++++++-- 17 files changed, 173 insertions(+), 57 deletions(-) rename src/media/video/decode/ffmpeg/{ffmpeg_decoder.cpp => ffmpeg_video_decoder.cpp} (95%) rename src/media/video/decode/ffmpeg/{ffmpeg_decoder.h => ffmpeg_video_decoder.h} (77%) rename src/media/video/decode/nvcodec/{nv_decoder.cpp => nvidia_video_decoder.cpp} (89%) rename src/media/video/decode/nvcodec/{nv_decoder.h => nvidia_video_decoder.h} (62%) create mode 100644 src/media/video/decode/video_decoder.h create mode 100644 src/media/video/decode/video_decoder_factory.cpp create mode 100644 src/media/video/decode/video_decoder_factory.h rename src/media/video/encode/ffmpeg/{ffmpeg_encoder.cpp => ffmpeg_video_encoder.cpp} (91%) rename src/media/video/encode/ffmpeg/{ffmpeg_encoder.h => ffmpeg_video_encoder.h} (85%) rename src/media/video/encode/nvcodec/{nv_encoder.cpp => nvidia_video_encoder.cpp} (93%) rename src/media/video/encode/nvcodec/{nv_encoder.h => nvidia_video_encoder.h} (82%) create mode 100644 src/media/video/encode/video_encoder.h create mode 100644 src/media/video/encode/video_encoder_factory.cpp create mode 100644 src/media/video/encode/video_encoder_factory.h diff --git a/src/media/video/decode/ffmpeg/ffmpeg_decoder.cpp b/src/media/video/decode/ffmpeg/ffmpeg_video_decoder.cpp similarity index 95% rename from src/media/video/decode/ffmpeg/ffmpeg_decoder.cpp rename to src/media/video/decode/ffmpeg/ffmpeg_video_decoder.cpp index 476e91e..a652c08 100644 --- a/src/media/video/decode/ffmpeg/ffmpeg_decoder.cpp +++ b/src/media/video/decode/ffmpeg/ffmpeg_video_decoder.cpp @@ -1,4 +1,4 @@ -#include "ffmpeg_decoder.h" +#include "ffmpeg_video_decoder.h" #include "log.h" @@ -10,7 +10,7 @@ extern "C" { #include }; -VideoDecoder::VideoDecoder() { +FfmpegVideoDecoder::FfmpegVideoDecoder() { if (SAVE_ENCODER_STREAM) { file_ = fopen("decode_stream.yuv", "w+b"); if (!file_) { @@ -19,7 +19,7 @@ VideoDecoder::VideoDecoder() { } } -VideoDecoder::~VideoDecoder() { +FfmpegVideoDecoder::~FfmpegVideoDecoder() { if (SAVE_ENCODER_STREAM && file_) { fflush(file_); fclose(file_); @@ -38,7 +38,7 @@ VideoDecoder::~VideoDecoder() { av_free(codec_ctx_); } -int VideoDecoder::Init() { +int FfmpegVideoDecoder::Init() { // av_log_set_level(AV_LOG_DEBUG); codec_id_ = AV_CODEC_ID_H264; @@ -80,7 +80,7 @@ int VideoDecoder::Init() { return 0; } -int VideoDecoder::Decode( +int FfmpegVideoDecoder::Decode( const uint8_t *data, int size, std::function on_receive_decoded_frame) { if (!first_) { diff --git a/src/media/video/decode/ffmpeg/ffmpeg_decoder.h b/src/media/video/decode/ffmpeg/ffmpeg_video_decoder.h similarity index 77% rename from src/media/video/decode/ffmpeg/ffmpeg_decoder.h rename to src/media/video/decode/ffmpeg/ffmpeg_video_decoder.h index 28da5eb..a005c26 100644 --- a/src/media/video/decode/ffmpeg/ffmpeg_decoder.h +++ b/src/media/video/decode/ffmpeg/ffmpeg_video_decoder.h @@ -1,5 +1,5 @@ -#ifndef _FFMPEG_DECODER_H_ -#define _FFMPEG_DECODER_H_ +#ifndef _FFMPEG_VIDEO_DECODER_H_ +#define _FFMPEG_VIDEO_DECODER_H_ #ifdef _WIN32 extern "C" { @@ -17,12 +17,12 @@ extern "C" { #include -#include "frame.h" +#include "video_decoder.h" -class VideoDecoder { +class FfmpegVideoDecoder : public VideoDecoder { public: - VideoDecoder(); - ~VideoDecoder(); + FfmpegVideoDecoder(); + ~FfmpegVideoDecoder(); public: int Init(); diff --git a/src/media/video/decode/nvcodec/nv_decoder.cpp b/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp similarity index 89% rename from src/media/video/decode/nvcodec/nv_decoder.cpp rename to src/media/video/decode/nvcodec/nvidia_video_decoder.cpp index f9e6b89..6edb54c 100644 --- a/src/media/video/decode/nvcodec/nv_decoder.cpp +++ b/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp @@ -1,10 +1,10 @@ -#include "nv_decoder.h" +#include "nvidia_video_decoder.h" #include "log.h" #define SAVE_ENCODER_STREAM 0 -VideoDecoder::VideoDecoder() { +NvidiaVideoDecoder::NvidiaVideoDecoder() { if (SAVE_ENCODER_STREAM) { file_ = fopen("decode_stream.h264", "w+b"); if (!file_) { @@ -12,7 +12,7 @@ VideoDecoder::VideoDecoder() { } } } -VideoDecoder::~VideoDecoder() { +NvidiaVideoDecoder::~NvidiaVideoDecoder() { if (SAVE_ENCODER_STREAM && file_) { fflush(file_); fclose(file_); @@ -20,7 +20,7 @@ VideoDecoder::~VideoDecoder() { } } -int VideoDecoder::Init() { +int NvidiaVideoDecoder::Init() { ck(cuInit(0)); int nGpu = 0; int iGpu = 0; @@ -43,7 +43,7 @@ int VideoDecoder::Init() { return 0; } -int VideoDecoder::Decode( +int NvidiaVideoDecoder::Decode( const uint8_t *data, int size, std::function on_receive_decoded_frame) { if (!decoder) { diff --git a/src/media/video/decode/nvcodec/nv_decoder.h b/src/media/video/decode/nvcodec/nvidia_video_decoder.h similarity index 62% rename from src/media/video/decode/nvcodec/nv_decoder.h rename to src/media/video/decode/nvcodec/nvidia_video_decoder.h index c089dde..712deda 100644 --- a/src/media/video/decode/nvcodec/nv_decoder.h +++ b/src/media/video/decode/nvcodec/nvidia_video_decoder.h @@ -1,15 +1,15 @@ -#ifndef _NV_DECODER_H_ -#define _NV_DECODER_H_ +#ifndef _NVIDIA_VIDEO_DECODER_H_ +#define _NVIDIA_VIDEO_DECODER_H_ #include #include "NvDecoder.h" -#include "frame.h" +#include "video_decoder.h" -class VideoDecoder { +class NvidiaVideoDecoder : public VideoDecoder { public: - VideoDecoder(); - ~VideoDecoder(); + NvidiaVideoDecoder(); + ~NvidiaVideoDecoder(); public: int Init(); diff --git a/src/media/video/decode/video_decoder.h b/src/media/video/decode/video_decoder.h new file mode 100644 index 0000000..4676c80 --- /dev/null +++ b/src/media/video/decode/video_decoder.h @@ -0,0 +1,16 @@ +#ifndef _VIDEO_DECODER_H_ +#define _VIDEO_DECODER_H_ + +#include + +#include "frame.h" + +class VideoDecoder { + public: + virtual int Init() = 0; + virtual int Decode( + const uint8_t *data, int size, + std::function on_receive_decoded_frame) = 0; +}; + +#endif \ No newline at end of file diff --git a/src/media/video/decode/video_decoder_factory.cpp b/src/media/video/decode/video_decoder_factory.cpp new file mode 100644 index 0000000..3ef1c4e --- /dev/null +++ b/src/media/video/decode/video_decoder_factory.cpp @@ -0,0 +1,17 @@ +#include "video_decoder_factory.h" + +#include "ffmpeg/ffmpeg_video_decoder.h" +#include "nvcodec/nvidia_video_decoder.h" + +VideoDecoderFactory::VideoDecoderFactory() {} + +VideoDecoderFactory::~VideoDecoderFactory() {} + +VideoDecoder *VideoDecoderFactory::CreateVideoDecoder( + bool hardware_acceleration) { + if (hardware_acceleration) { + return new NvidiaVideoDecoder(); + } else { + return new FfmpegVideoDecoder(); + } +} \ 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 new file mode 100644 index 0000000..0782070 --- /dev/null +++ b/src/media/video/decode/video_decoder_factory.h @@ -0,0 +1,16 @@ +#ifndef _VIDEO_DECODER_FACTORY_H_ +#define _VIDEO_DECODER_FACTORY_H_ + +#include "video_decoder.h" +class VideoDecoderFactory { + public: + VideoDecoderFactory(); + ~VideoDecoderFactory(); + + static VideoDecoder *CreateVideoDecoder(bool hardware_acceleration); + + private: + bool hardware_acceleration_ = false; +}; + +#endif \ No newline at end of file diff --git a/src/media/video/encode/ffmpeg/ffmpeg_encoder.cpp b/src/media/video/encode/ffmpeg/ffmpeg_video_encoder.cpp similarity index 91% rename from src/media/video/encode/ffmpeg/ffmpeg_encoder.cpp rename to src/media/video/encode/ffmpeg/ffmpeg_video_encoder.cpp index cdc6606..0369cc4 100644 --- a/src/media/video/encode/ffmpeg/ffmpeg_encoder.cpp +++ b/src/media/video/encode/ffmpeg/ffmpeg_video_encoder.cpp @@ -1,4 +1,4 @@ -#include "ffmpeg_encoder.h" +#include "ffmpeg_video_encoder.h" #include @@ -6,7 +6,7 @@ #define SAVE_ENCODER_STREAM 0 -VideoEncoder::VideoEncoder() { +FFmpegVideoEncoder::FFmpegVideoEncoder() { if (SAVE_ENCODER_STREAM) { file_ = fopen("encode_stream.h264", "w+b"); if (!file_) { @@ -14,7 +14,7 @@ VideoEncoder::VideoEncoder() { } } } -VideoEncoder::~VideoEncoder() { +FFmpegVideoEncoder::~FFmpegVideoEncoder() { if (SAVE_ENCODER_STREAM && file_) { fflush(file_); fclose(file_); @@ -29,7 +29,7 @@ VideoEncoder::~VideoEncoder() { } } -int VideoEncoder::Init() { +int FFmpegVideoEncoder::Init() { av_log_set_level(AV_LOG_ERROR); codec_ = avcodec_find_encoder(AV_CODEC_ID_H264); @@ -85,7 +85,7 @@ int VideoEncoder::Init() { return 0; } -int VideoEncoder::Encode( +int FFmpegVideoEncoder::Encode( const uint8_t *pData, int nSize, std::function on_encoded_image) { if (!codec_ctx_) { @@ -132,9 +132,9 @@ int VideoEncoder::Encode( return 0; } -int VideoEncoder::OnEncodedImage(char *encoded_packets, size_t size) { +int FFmpegVideoEncoder::OnEncodedImage(char *encoded_packets, size_t size) { LOG_INFO("OnEncodedImage not implemented"); return 0; } -void VideoEncoder::ForceIdr() {} +void FFmpegVideoEncoder::ForceIdr() {} diff --git a/src/media/video/encode/ffmpeg/ffmpeg_encoder.h b/src/media/video/encode/ffmpeg/ffmpeg_video_encoder.h similarity index 85% rename from src/media/video/encode/ffmpeg/ffmpeg_encoder.h rename to src/media/video/encode/ffmpeg/ffmpeg_video_encoder.h index 9998825..b26772e 100644 --- a/src/media/video/encode/ffmpeg/ffmpeg_encoder.h +++ b/src/media/video/encode/ffmpeg/ffmpeg_video_encoder.h @@ -1,5 +1,5 @@ -#ifndef _FFMPEG_ENCODER_H_ -#define _FFMPEG_ENCODER_H_ +#ifndef _FFMPEG_VIDEO_ENCODER_H_ +#define _FFMPEG_VIDEO_ENCODER_H_ #ifdef _WIN32 extern "C" { @@ -24,10 +24,12 @@ extern "C" { #endif #include -class VideoEncoder { +#include "video_encoder.h" + +class FFmpegVideoEncoder : public VideoEncoder { public: - VideoEncoder(); - ~VideoEncoder(); + FFmpegVideoEncoder(); + ~FFmpegVideoEncoder(); int Init(); int Encode( diff --git a/src/media/video/encode/nvcodec/nv_encoder.cpp b/src/media/video/encode/nvcodec/nvidia_video_encoder.cpp similarity index 93% rename from src/media/video/encode/nvcodec/nv_encoder.cpp rename to src/media/video/encode/nvcodec/nvidia_video_encoder.cpp index 72f8b30..2a854e8 100644 --- a/src/media/video/encode/nvcodec/nv_encoder.cpp +++ b/src/media/video/encode/nvcodec/nvidia_video_encoder.cpp @@ -1,4 +1,4 @@ -#include "nv_encoder.h" +#include "nvidia_video_encoder.h" #include @@ -6,7 +6,7 @@ #define SAVE_ENCODER_STREAM 0 -VideoEncoder::VideoEncoder() { +NvidiaVideoEncoder::NvidiaVideoEncoder() { if (SAVE_ENCODER_STREAM) { file_ = fopen("encode_stream.h264", "w+b"); if (!file_) { @@ -14,7 +14,7 @@ VideoEncoder::VideoEncoder() { } } } -VideoEncoder::~VideoEncoder() { +NvidiaVideoEncoder::~NvidiaVideoEncoder() { if (SAVE_ENCODER_STREAM && file_) { fflush(file_); fclose(file_); @@ -27,7 +27,7 @@ VideoEncoder::~VideoEncoder() { } } -int VideoEncoder::Init() { +int NvidiaVideoEncoder::Init() { // Init cuda context int num_of_GPUs = 0; CUdevice cuda_device; @@ -73,7 +73,7 @@ int VideoEncoder::Init() { return 0; } -int VideoEncoder::Encode( +int NvidiaVideoEncoder::Encode( const uint8_t *pData, int nSize, std::function on_encoded_image) { if (!encoder_) { @@ -130,12 +130,12 @@ int VideoEncoder::Encode( return 0; } -int VideoEncoder::OnEncodedImage(char *encoded_packets, size_t size) { +int NvidiaVideoEncoder::OnEncodedImage(char *encoded_packets, size_t size) { LOG_INFO("OnEncodedImage not implemented"); return 0; } -void VideoEncoder::ForceIdr() { +void NvidiaVideoEncoder::ForceIdr() { NV_ENC_RECONFIGURE_PARAMS reconfig_params; reconfig_params.version = NV_ENC_RECONFIGURE_PARAMS_VER; diff --git a/src/media/video/encode/nvcodec/nv_encoder.h b/src/media/video/encode/nvcodec/nvidia_video_encoder.h similarity index 82% rename from src/media/video/encode/nvcodec/nv_encoder.h rename to src/media/video/encode/nvcodec/nvidia_video_encoder.h index 007213e..034c629 100644 --- a/src/media/video/encode/nvcodec/nv_encoder.h +++ b/src/media/video/encode/nvcodec/nvidia_video_encoder.h @@ -1,14 +1,15 @@ -#ifndef _NV_ENCODER_H_ -#define _NV_ENCODER_H_ +#ifndef _NVIDIA_VIDEO_ENCODER_H_ +#define _NVIDIA_VIDEO_ENCODER_H_ #include #include "NvEncoderCuda.h" +#include "video_encoder.h" -class VideoEncoder { +class NvidiaVideoEncoder : public VideoEncoder { public: - VideoEncoder(); - ~VideoEncoder(); + NvidiaVideoEncoder(); + ~NvidiaVideoEncoder(); int Init(); int Encode( diff --git a/src/media/video/encode/video_encoder.h b/src/media/video/encode/video_encoder.h new file mode 100644 index 0000000..7d6941c --- /dev/null +++ b/src/media/video/encode/video_encoder.h @@ -0,0 +1,16 @@ +#ifndef _VIDEO_ENCODER_H_ +#define _VIDEO_ENCODER_H_ + +#include + +class VideoEncoder { + public: + virtual int Init() = 0; + virtual int Encode(const uint8_t* pData, int nSize, + std::function + on_encoded_image) = 0; + virtual int OnEncodedImage(char* encoded_packets, size_t size) = 0; + virtual void ForceIdr() = 0; +}; + +#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 new file mode 100644 index 0000000..49ab914 --- /dev/null +++ b/src/media/video/encode/video_encoder_factory.cpp @@ -0,0 +1,17 @@ +#include "video_encoder_factory.h" + +#include "ffmpeg/ffmpeg_video_encoder.h" +#include "nvcodec/nvidia_video_encoder.h" + +VideoEncoderFactory::VideoEncoderFactory() {} + +VideoEncoderFactory::~VideoEncoderFactory() {} + +VideoEncoder *VideoEncoderFactory::CreateVideoEncoder( + bool hardware_acceleration) { + if (hardware_acceleration) { + return new NvidiaVideoEncoder(); + } else { + return new FFmpegVideoEncoder(); + } +} diff --git a/src/media/video/encode/video_encoder_factory.h b/src/media/video/encode/video_encoder_factory.h new file mode 100644 index 0000000..ec509be --- /dev/null +++ b/src/media/video/encode/video_encoder_factory.h @@ -0,0 +1,16 @@ +#ifndef _VIDEO_ENCODER_FACTORY_H_ +#define _VIDEO_ENCODER_FACTORY_H_ + +#include "video_encoder.h" +class VideoEncoderFactory { + public: + VideoEncoderFactory(); + ~VideoEncoderFactory(); + + static VideoEncoder *CreateVideoEncoder(bool hardware_acceleration); + + private: + bool hardware_acceleration_ = false; +}; + +#endif \ No newline at end of file diff --git a/src/pc/peer_connection.cpp b/src/pc/peer_connection.cpp index 5d2b941..ad7929c 100644 --- a/src/pc/peer_connection.cpp +++ b/src/pc/peer_connection.cpp @@ -60,7 +60,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 = 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_) { @@ -101,8 +101,15 @@ int PeerConnection::Init(PeerConnectionParams params, do { } while (SignalStatus::Connected != GetSignalStatus()); - VideoEncoder::Init(); - VideoDecoder::Init(); + + video_encoder = + VideoEncoderFactory::CreateVideoEncoder(hardware_accelerated_encode_); + video_encoder->Init(); + video_decoder = + VideoDecoderFactory::CreateVideoDecoder(hardware_accelerated_decode_); + video_decoder->Init(); + // VideoEncoder::Init(); + // VideoDecoder::Init(); nv12_data_ = new char[1280 * 720 * 3 / 2]; return 0; @@ -302,7 +309,7 @@ int PeerConnection::SendVideoData(const char *data, size_t size) { return -1; } - int ret = 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 a653e93..18aa129 100644 --- a/src/pc/peer_connection.h +++ b/src/pc/peer_connection.h @@ -8,10 +8,8 @@ #include "ice_transmission.h" #ifdef _WIN32 -#include "ffmpeg_decoder.h" -#include "ffmpeg_encoder.h" -// #include "nv_decoder.h" -// #include "nv_encoder.h" +#include "video_decoder_factory.h" +#include "video_encoder_factory.h" #endif #include "ws_transmission.h" @@ -31,7 +29,7 @@ typedef struct { NetStatusReport net_status_report; } PeerConnectionParams; -class PeerConnection : public VideoEncoder, VideoDecoder { +class PeerConnection { public: PeerConnection(); ~PeerConnection(); @@ -100,6 +98,12 @@ class PeerConnection : public VideoEncoder, VideoDecoder { OnReceiveBuffer on_receive_audio_buffer_; OnReceiveBuffer on_receive_data_buffer_; char *nv12_data_ = nullptr; + + private: + VideoEncoder *video_encoder = nullptr; + VideoDecoder *video_decoder = nullptr; + bool hardware_accelerated_encode_ = true; + bool hardware_accelerated_decode_ = true; }; #endif \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index 0602505..cc8faff 100644 --- a/xmake.lua +++ b/xmake.lua @@ -104,12 +104,16 @@ target("media") add_deps("log", "frame") if is_os("windows") or is_os(("linux")) then add_packages("cuda") - add_files("src/media/video/encode/nvcodec/*.cpp", + add_files("src/media/video/encode/*.cpp", + "src/media/video/decode/*.cpp", + "src/media/video/encode/nvcodec/*.cpp", "src/media/video/decode/nvcodec/*.cpp", "src/media/video/encode/ffmpeg/*.cpp", "src/media/video/decode/ffmpeg/*.cpp" ) - add_includedirs("src/media/video/encode/nvcodec", + add_includedirs("src/media/video/encode", + "src/media/video/decode", + "src/media/video/encode/nvcodec", "src/media/video/decode/nvcodec", "src/media/video/encode/ffmpeg", "src/media/video/decode/ffmpeg",