102 lines
2.5 KiB
C++
102 lines
2.5 KiB
C++
// VideoFrameEncoder.h
|
||
#pragma once
|
||
|
||
#include <string>
|
||
#include <memory>
|
||
#include <queue>
|
||
#include <mutex>
|
||
#include <condition_variable>
|
||
#include <functional>
|
||
|
||
extern "C" {
|
||
#include <libavformat/avformat.h>
|
||
#include <libavcodec/avcodec.h>
|
||
#include <libswscale/swscale.h>
|
||
#include <libavutil/opt.h>
|
||
#include <libavutil/imgutils.h>
|
||
#include <libavutil/time.h>
|
||
}
|
||
|
||
namespace ffmpeg {
|
||
|
||
class VideoFrameEncoder {
|
||
public:
|
||
struct Config {
|
||
int width = 1280;
|
||
int height = 720;
|
||
int fps = 30;
|
||
int bitrate = 5000000; // 5Mbps
|
||
int gop_size = 15; // GOP大小
|
||
int max_b_frames = 2; // 最大B帧数
|
||
AVPixelFormat pixel_format = AV_PIX_FMT_YUV420P;
|
||
std::string preset = "fast"; // 编码速度预设
|
||
std::string tune = "zerolatency"; // 调优参数
|
||
std::string profile = "main"; // 编码profile
|
||
std::string codec = "libx265";
|
||
};
|
||
|
||
using PacketCallback = std::function<void(AVPacket* packet, int64_t pts, int64_t dts)>;
|
||
|
||
VideoFrameEncoder();
|
||
~VideoFrameEncoder();
|
||
|
||
// 初始化编码器
|
||
int initialize(const Config& config);
|
||
|
||
// 编码一帧
|
||
int encode_frame(AVFrame* frame);
|
||
|
||
// 设置编码数据包回调
|
||
void set_packet_callback(PacketCallback callback) {
|
||
packet_callback_ = callback;
|
||
}
|
||
|
||
// 设置时间戳类型
|
||
void set_time_base(AVRational time_base) {
|
||
time_base_ = time_base;
|
||
}
|
||
|
||
// 刷新编码器(处理剩余数据)
|
||
int flush();
|
||
|
||
// 获取编码器上下文
|
||
AVCodecContext* get_codec_context() { return encoder_ctx_; }
|
||
|
||
// 获取时间基
|
||
AVRational get_time_base() const {
|
||
return encoder_ctx_ ? encoder_ctx_->time_base : AVRational{0, 1};
|
||
}
|
||
|
||
// 获取帧率
|
||
AVRational get_framerate() const {
|
||
return encoder_ctx_ ? encoder_ctx_->framerate : AVRational{0, 1};
|
||
}
|
||
|
||
// 获取当前帧索引
|
||
int64_t get_frame_index() const { return frame_index_; }
|
||
|
||
private:
|
||
Config config_;
|
||
AVCodecContext* encoder_ctx_ = nullptr;
|
||
SwsContext* sws_ctx_ = nullptr;
|
||
AVFrame* converted_frame_ = nullptr;
|
||
PacketCallback packet_callback_;
|
||
int64_t frame_index_ = 0;
|
||
AVRational time_base_ = {1, 90000}; // 默认时间基
|
||
int64_t start_time_ = 0; // 编码开始时间
|
||
|
||
// 初始化SWS上下文(格式转换)
|
||
int init_sws_context(AVFrame* frame);
|
||
|
||
// 发送数据包到回调
|
||
void send_packet(AVPacket* packet);
|
||
|
||
// 释放资源
|
||
void cleanup();
|
||
|
||
// 获取当前时间戳
|
||
int64_t get_current_timestamp();
|
||
};
|
||
|
||
} // namespace ffmpeg
|