| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #pragma once
- #include "codec_abstract_codec.h"
- #include "../base/media_common.h"
- #include <mutex>
- #include <memory>
- extern "C" {
- #include <libavcodec/avcodec.h>
- #include <libavutil/hwcontext.h>
- #include <libavutil/opt.h>
- #include <libavformat/avformat.h>
- }
- namespace av {
- namespace codec {
- /**
- * 视频编码器参数
- */
- struct VideoEncoderParams : public CodecParams {
- int bitRate = 2000000; // 比特率 (bps)
- int width = 1920; // 宽度
- int height = 1080; // 高度
- int fps = 30; // 帧率
- int gopSize = 30; // GOP大小
- int maxBFrames = 0; // B帧数量
- std::string preset = "medium"; // 编码预设
- std::string tune = ""; // 调优参数
- bool lowLatency = false; // 低延迟模式
- bool hardwareAccel = true; // 硬件加速
- AVPixelFormat pixelFormat = AV_PIX_FMT_YUV420P; // 像素格式
-
- VideoEncoderParams() {
- type = MediaType::VIDEO;
- }
- };
- /**
- * 像素格式转换器
- */
- class PixelFormatConverter {
- friend class VideoEncoder;
-
- public:
- PixelFormatConverter(AVPixelFormat srcFormat, AVPixelFormat dstFormat);
- ~PixelFormatConverter();
-
- bool setSize(int width, int height);
- AVFramePtr convert(const AVFramePtr& srcFrame);
-
- private:
- struct SwsContext* swsCtx_;
- AVPixelFormat srcFormat_;
- AVPixelFormat dstFormat_;
- int width_;
- int height_;
- AVFramePtr dstFrame_;
- };
- /**
- * 视频编码器实现
- */
- class VideoEncoder : public AbstractEncoder {
- public:
- VideoEncoder();
- ~VideoEncoder() override;
- // AbstractCodec 接口实现
- ErrorCode open(const CodecParams& params) override;
- void close() override;
- ErrorCode flush() override;
- // AbstractEncoder 接口实现
- ErrorCode encode(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) override;
- ErrorCode finishEncode(std::vector<AVPacketPtr>& packets) override;
- // 视频编码器特有功能
- const VideoEncoderParams& getVideoParams() const { return videoParams_; }
-
- // 获取支持的编码器列表
- static std::vector<std::string> getSupportedEncoders();
-
- // 检查编码器是否支持硬件加速
- static bool isHardwareEncoder(const std::string& codecName);
-
- // 获取推荐的编码器
- static std::string getRecommendedEncoder();
-
- // 硬件编码器名称
- static constexpr const char* HARDWARE_ENCODERS[] = {
- "h264_nvenc", // NVIDIA
- "h264_qsv", // Intel Quick Sync
- "h264_amf", // AMD
- "h264_videotoolbox", // Apple
- };
-
- // 软件编码器名称
- static constexpr const char* SOFTWARE_ENCODERS[] = {
- "libx264",
- "libx265",
- };
- protected:
- bool validateParams(const CodecParams& params) override;
- private:
- // 初始化编码器
- ErrorCode initEncoder();
-
- // 设置编码器参数
- ErrorCode setupEncoderParams();
-
- // 设置硬件加速
- ErrorCode setupHardwareAcceleration();
-
- // 设置硬件帧上下文
- ErrorCode setupHardwareFrameContext();
-
- // 转换帧格式
- AVFramePtr convertFrame(const AVFramePtr& frame);
-
- // 转换到硬件帧
- AVFramePtr transferToHardware(const AVFramePtr& frame);
-
- // 编码单个帧
- ErrorCode encodeFrame(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets);
-
- // 接收编码后的包
- ErrorCode receivePackets(std::vector<AVPacketPtr>& packets);
-
- // 获取硬件设备类型
- AVHWDeviceType getHardwareDeviceType() const;
-
- // 获取硬件像素格式
- AVPixelFormat getHardwarePixelFormat() const;
-
- // 查找可用的编码器
- static void findUsableEncoders();
- private:
- VideoEncoderParams videoParams_; // 视频编码参数
-
- // 硬件加速相关
- bool isHardwareEncoder_; // 是否硬件编码器
- AVBufferRef* hwDeviceCtx_; // 硬件设备上下文
- AVFramePtr hwFrame_; // 硬件帧缓冲
-
- // 格式转换
- std::unique_ptr<PixelFormatConverter> converter_;
- AVFramePtr convertedFrame_; // 转换后的帧
-
- // 线程安全
- std::mutex encodeMutex_;
-
- // 支持的编码器列表
- static std::vector<std::string> supportedEncoders_;
- static std::once_flag encodersInitFlag_;
- };
- /**
- * 视频编码器工厂
- */
- class VideoEncoderFactory {
- public:
- /**
- * 创建视频编码器
- */
- static std::unique_ptr<VideoEncoder> create(const std::string& codecName = "");
-
- /**
- * 创建最佳视频编码器(自动选择硬件/软件)
- */
- static std::unique_ptr<VideoEncoder> createBest(bool preferHardware = true);
- };
- } // namespace codec
- } // namespace av
|