cmvr-es/cmvr-es/common/utils/ffmpeg/include/VideoFrameEncoder.h

102 lines
2.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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