AI automatically translates all comments in the code into English (#3917)

This commit is contained in:
alex
2024-09-19 14:53:50 +08:00
committed by GitHub
parent 046de691cb
commit 4152dcd409
279 changed files with 10602 additions and 3038 deletions

View File

@@ -18,6 +18,9 @@ namespace mediakit{
/**
* 通用 rtmp解码类
* Generic rtmp decoder class
* [AUTO-TRANSLATED:b04614f4]
*/
class CommonRtmpDecoder : public RtmpCodec {
public:
@@ -25,18 +28,28 @@ public:
/**
* 构造函数
* Constructor
* [AUTO-TRANSLATED:41469869]
*/
CommonRtmpDecoder(const Track::Ptr &track) : RtmpCodec(track) {}
/**
* 输入Rtmp并解码
* @param rtmp Rtmp数据包
* Input Rtmp and decode
* @param rtmp Rtmp data packet
* [AUTO-TRANSLATED:43b1eae8]
*/
void inputRtmp(const RtmpPacket::Ptr &rtmp) override;
};
/**
* 通用 rtmp编码类
* Generic rtmp encoder class
* [AUTO-TRANSLATED:4616a2a8]
*/
class CommonRtmpEncoder : public RtmpCodec {
public:
@@ -46,6 +59,10 @@ public:
/**
* 输入帧数据
* Input frame data
* [AUTO-TRANSLATED:d13bc7f2]
*/
bool inputFrame(const Frame::Ptr &frame) override;

View File

@@ -26,7 +26,8 @@ void CommonRtpDecoder::obtainFrame() {
bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){
auto payload_size = rtp->getPayloadSize();
if (payload_size <= 0) {
//无实际负载
// 无实际负载 [AUTO-TRANSLATED:305af48f]
// No actual load
return false;
}
auto payload = rtp->getPayload();
@@ -34,19 +35,23 @@ bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){
auto seq = rtp->getSeq();
if (_last_stamp != stamp || _frame->_buffer.size() > _max_frame_size) {
//时间戳发生变化或者缓存超过MAX_FRAME_SIZE则清空上帧数据
// 时间戳发生变化或者缓存超过MAX_FRAME_SIZE则清空上帧数据 [AUTO-TRANSLATED:96f15576]
// If the timestamp changes or the cache exceeds MAX_FRAME_SIZE, clear the previous frame data
if (!_frame->_buffer.empty()) {
//有有效帧,则输出
// 有有效帧,则输出 [AUTO-TRANSLATED:f3ff1bda]
// If there is a valid frame, output it
RtpCodec::inputFrame(_frame);
}
//新的一帧数据
// 新的一帧数据 [AUTO-TRANSLATED:5b5f3a35]
// New frame data
obtainFrame();
_frame->_dts = rtp->getStampMS();
_last_stamp = stamp;
_drop_flag = false;
} else if (_last_seq != 0 && (uint16_t)(_last_seq + 1) != seq) {
//时间戳未发生变化但是seq却不连续说明中间rtp丢包了那么整帧应该废弃
// 时间戳未发生变化但是seq却不连续说明中间rtp丢包了那么整帧应该废弃 [AUTO-TRANSLATED:577bf835]
// If the timestamp does not change, but the seq is not continuous, it means that the RTP packet has been lost in the middle, so the entire frame should be discarded
WarnL << "rtp丢包:" << _last_seq << " -> " << seq;
_drop_flag = true;
_frame->_buffer.clear();

View File

@@ -18,6 +18,9 @@ namespace mediakit{
/**
* 通用 rtp解码类
* Generic rtp decoder class
* [AUTO-TRANSLATED:41b57089]
*/
class CommonRtpDecoder : public RtpCodec {
public:
@@ -27,6 +30,11 @@ public:
* 构造函数
* @param codec 编码id
* @param max_frame_size 允许的最大帧大小
* Constructor
* @param codec codec id
* @param max_frame_size maximum allowed frame size
* [AUTO-TRANSLATED:c6b0414f]
*/
CommonRtpDecoder(CodecId codec, size_t max_frame_size = 2 * 1024);
@@ -34,6 +42,11 @@ public:
* 输入rtp并解码
* @param rtp rtp数据包
* @param key_pos 此参数内部强制转换为false,请忽略之
* Input rtp and decode
* @param rtp rtp data packet
* @param key_pos This parameter is internally forced to false, please ignore it
* [AUTO-TRANSLATED:2993fcbe]
*/
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override;
@@ -51,6 +64,9 @@ private:
/**
* 通用 rtp编码类
* Generic rtp encoder class
* [AUTO-TRANSLATED:bb3991a5]
*/
class CommonRtpEncoder : public RtpCodec {
public:
@@ -58,6 +74,10 @@ public:
/**
* 输入帧数据并编码成rtp
* Input frame data and encode into rtp
* [AUTO-TRANSLATED:02bc9009]
*/
bool inputFrame(const Frame::Ptr &frame) override;
};

View File

@@ -45,7 +45,8 @@ void Factory::registerPlugin(const CodecPlugin &plugin) {
Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
auto codec = getCodecId(track->_codec);
if (codec == CodecInvalid) {
// 根据传统的payload type 获取编码类型以及采样率等信息
// 根据传统的payload type 获取编码类型以及采样率等信息 [AUTO-TRANSLATED:d01ca068]
// Get the encoding type, sampling rate, and other information based on the traditional payload type
codec = RtpPayload::getCodecId(track->_pt);
}
auto it = s_plugins.find(codec);
@@ -83,7 +84,8 @@ RtpCodec::Ptr Factory::getRtpDecoderByCodecId(CodecId codec) {
return it->second->getRtpDecoderByCodecId();
}
/////////////////////////////rtmp相关///////////////////////////////////////////
// ///////////////////////////rtmp相关/////////////////////////////////////////// [AUTO-TRANSLATED:da9645df]
// ///////////////////////////rtmp related///////////////////////////////////////////
static CodecId getVideoCodecIdByAmf(const AMFValue &val){
if (val.type() == AMF_STRING) {
@@ -197,7 +199,8 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) {
Frame::Ptr Factory::getFrameFromPtr(CodecId codec, const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
auto it = s_plugins.find(codec);
if (it == s_plugins.end()) {
// 创建不支持codec的frame
// 创建不支持codec的frame [AUTO-TRANSLATED:00936c6c]
// Create a frame that does not support the codec
return std::make_shared<FrameFromPtr>(codec, (char *)data, bytes, dts, pts);
}
return it->second->getFrameFromPtr(data, bytes, dts, pts);

View File

@@ -44,6 +44,9 @@ class Factory {
public:
/**
* 注册插件,非线程安全的
* Register plugin, not thread-safe
* [AUTO-TRANSLATED:43e22d01]
*/
static void registerPlugin(const CodecPlugin &plugin);
@@ -53,17 +56,31 @@ public:
* @param sample_rate 采样率视频固定为90000
* @param channels 音频通道数
* @param sample_bit 音频采样位数
* Get track by codec_id
* @param codecId codec id
* @param sample_rate sample rate, video is fixed to 90000
* @param channels number of audio channels
* @param sample_bit audio sample bit
* [AUTO-TRANSLATED:397b982e]
*/
static Track::Ptr getTrackByCodecId(CodecId codecId, int sample_rate = 0, int channels = 0, int sample_bit = 0);
////////////////////////////////rtsp相关//////////////////////////////////
// //////////////////////////////rtsp相关////////////////////////////////// [AUTO-TRANSLATED:884055ec]
// //////////////////////////////rtsp相关//////////////////////////////////
/**
* 根据sdp生成Track对象
* Generate Track object based on sdp
* [AUTO-TRANSLATED:79a99990]
*/
static Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track);
/**
* 根据c api 抽象的Track生成具体Track对象
* Generate specific Track object based on Track abstracted from c api
* [AUTO-TRANSLATED:991e7721]
*/
static Track::Ptr getTrackByAbstractTrack(const Track::Ptr& track);
@@ -71,43 +88,72 @@ public:
* 根据codec id生成rtp编码器
* @param codec_id 编码id
* @param pt rtp payload type
* Generate rtp encoder based on codec id
* @param codec_id codec id
* @param pt rtp payload type
* [AUTO-TRANSLATED:3895b39c]
*/
static RtpCodec::Ptr getRtpEncoderByCodecId(CodecId codec_id, uint8_t pt);
/**
* 根据Track生成Rtp解包器
* Generate Rtp unpacker based on Track
* [AUTO-TRANSLATED:50dbf826]
*/
static RtpCodec::Ptr getRtpDecoderByCodecId(CodecId codec);
////////////////////////////////rtmp相关//////////////////////////////////
// //////////////////////////////rtmp相关////////////////////////////////// [AUTO-TRANSLATED:df02d6fb]
// //////////////////////////////rtmp相关//////////////////////////////////
/**
* 根据amf对象获取视频相应的Track
* @param amf rtmp metadata中的videocodecid的值
* Get the corresponding video Track based on the amf object
* @param amf the value of videocodecid in rtmp metadata
* [AUTO-TRANSLATED:c0c632c1]
*/
static Track::Ptr getVideoTrackByAmf(const AMFValue &amf);
/**
* 根据amf对象获取音频相应的Track
* @param amf rtmp metadata中的audiocodecid的值
* Get the corresponding audio Track based on the amf object
* @param amf the value of audiocodecid in rtmp metadata
* [AUTO-TRANSLATED:fc34f9e4]
*/
static Track::Ptr getAudioTrackByAmf(const AMFValue& amf, int sample_rate, int channels, int sample_bit);
/**
* 根据Track获取Rtmp的编码器
* @param track 媒体描述对象
* Get the Rtmp encoder based on Track
* @param track media description object
* [AUTO-TRANSLATED:81fc38af]
*/
static RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track);
/**
* 根据Track获取Rtmp的解码器
* @param track 媒体描述对象
* Get the Rtmp decoder based on Track
* @param track media description object
* [AUTO-TRANSLATED:0744b09e]
*/
static RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track);
/**
* 根据codecId获取rtmp的codec描述
* Get the rtmp codec description based on codecId
* [AUTO-TRANSLATED:67c749b7]
*/
static AMFValue getAmfByCodecId(CodecId codecId);

View File

@@ -42,7 +42,8 @@ FrameStamp::FrameStamp(Frame::Ptr frame, Stamp &stamp, int modify_stamp)
{
setIndex(frame->getIndex());
_frame = std::move(frame);
// kModifyStampSystem时采用系统时间戳kModifyStampRelative采用相对时间戳
// kModifyStampSystem时采用系统时间戳kModifyStampRelative采用相对时间戳 [AUTO-TRANSLATED:54dd5685]
// When using kModifyStampSystem, the system timestamp is used, and when using kModifyStampRelative, the relative timestamp is used.
stamp.revise(_frame->dts(), _frame->pts(), _dts, _pts, modify_stamp == ProtocolOption::kModifyStampSystem);
}
@@ -94,7 +95,8 @@ int getMpegIdByCodec(CodecId codec) {
CodecId getCodecByMpegId(int mpeg_id) {
if (mpeg_id == PSI_STREAM_RESERVED || mpeg_id == 0xBD) {
// 海康的 PS 流中会有0xBD 的包
// 海康的 PS 流中会有0xBD 的包 [AUTO-TRANSLATED:32a250cb]
// Hikvision's PS stream will have 0xBD packets.
return CodecInvalid;
}
@@ -165,7 +167,8 @@ static size_t constexpr kMaxFrameCacheSize = 100;
bool FrameMerger::willFlush(const Frame::Ptr &frame) const{
if (_frame_cache.empty()) {
//缓存为空
// 缓存为空 [AUTO-TRANSLATED:b9505a19]
// Cache is empty.
return false;
}
if (!frame) {
@@ -173,29 +176,34 @@ bool FrameMerger::willFlush(const Frame::Ptr &frame) const{
}
switch (_type) {
case none : {
//frame不是完整的帧我们合并为一帧
// frame不是完整的帧我们合并为一帧 [AUTO-TRANSLATED:00e9f200]
// The frame is not a complete frame, we merge it into one frame.
bool new_frame = false;
switch (frame->getCodecId()) {
case CodecH264:
case CodecH265: {
//如果是新的一帧,前面的缓存需要输出
// 如果是新的一帧,前面的缓存需要输出 [AUTO-TRANSLATED:b4deff81]
// If it is a new frame, the previous cache needs to be output.
new_frame = frame->prefixSize();
break;
}
default: break;
}
//遇到新帧、或时间戳变化或缓存太多防止内存溢出则flush输出
// 遇到新帧、或时间戳变化或缓存太多防止内存溢出则flush输出 [AUTO-TRANSLATED:0292964a]
// When encountering a new frame, or a timestamp change, or too much cache, flush the output to prevent memory overflow.
return new_frame || _frame_cache.back()->dts() != frame->dts() || _frame_cache.size() > kMaxFrameCacheSize;
}
case mp4_nal_size:
case h264_prefix: {
if (!_have_decode_able_frame) {
//缓存中没有有效的能解码的帧所以这次不flush
// 缓存中没有有效的能解码的帧所以这次不flush [AUTO-TRANSLATED:5d860722]
// There are no valid frames that can be decoded in the cache, so no flush this time.
return _frame_cache.size() > kMaxFrameCacheSize;
}
if (_frame_cache.back()->dts() != frame->dts() || frame->decodeAble() || frame->configFrame()) {
//时间戳变化了,或新的一帧或遇到config帧立即flush
// 时间戳变化了,或新的一帧或遇到config帧立即flush [AUTO-TRANSLATED:8c2523b1]
// When the timestamp changes, or a new frame, or a config frame is encountered, flush immediately.
return true;
}
return _frame_cache.size() > kMaxFrameCacheSize;
@@ -207,8 +215,10 @@ bool FrameMerger::willFlush(const Frame::Ptr &frame) const{
void FrameMerger::doMerge(BufferLikeString &merged, const Frame::Ptr &frame) const{
switch (_type) {
case none : {
//此处是合并ps解析输出的流解析出的流可能是半帧或多帧不能简单的根据nal type过滤
//此流程只用于合并ps解析输出为H264/H265后面流程有split和忽略无效帧操作
// 此处是合并ps解析输出的流解析出的流可能是半帧或多帧不能简单的根据nal type过滤 [AUTO-TRANSLATED:4a231bdc]
// Here, the PS parsing output stream is merged. The parsed stream may be half a frame or multiple frames, and cannot be simply filtered according to the nal type.
// 此流程只用于合并ps解析输出为H264/H265后面流程有split和忽略无效帧操作 [AUTO-TRANSLATED:2d40274e]
// This process is only used to merge PS parsing output into H264/H265. The subsequent process has split and ignore invalid frame operations.
merged.append(frame->data(), frame->size());
break;
}
@@ -251,7 +261,8 @@ bool FrameMerger::inputFrame(const Frame::Ptr &frame, onOutput cb, BufferLikeStr
bool have_key_frame = back->keyFrame();
if (_frame_cache.size() != 1 || _type == mp4_nal_size || buffer) {
//在MP4模式下一帧数据也需要在前添加nalu_size
// 在MP4模式下一帧数据也需要在前添加nalu_size [AUTO-TRANSLATED:4a7e5c20]
// In MP4 mode, a frame of data also needs to add nalu_size in front.
BufferLikeString tmp;
BufferLikeString &merged = buffer ? *buffer : tmp;
@@ -301,6 +312,9 @@ void FrameMerger::flush() {
}
/**
* 写帧接口转function辅助类
* Write frame interface to function, auxiliary class
* [AUTO-TRANSLATED:ce04a5e9]
*/
class FrameWriterInterfaceHelper : public FrameWriterInterface {
public:
@@ -309,11 +323,18 @@ public:
/**
* inputFrame后触发onWriteFrame回调
* Trigger onWriteFrame callback after inputFrame
* [AUTO-TRANSLATED:169e5944]
*/
FrameWriterInterfaceHelper(onWriteFrame cb) { _callback = std::move(cb); }
/**
* 写入帧数据
* Write frame data
* [AUTO-TRANSLATED:d46c6fc2]
*/
bool inputFrame(const Frame::Ptr &frame) override { return _callback(frame); }

View File

@@ -55,11 +55,17 @@ typedef enum {
/**
* 字符串转媒体类型转
* String to media type conversion
* [AUTO-TRANSLATED:59850011]
*/
TrackType getTrackType(const std::string &str);
/**
* 媒体类型转字符串
* Media type to string conversion
* [AUTO-TRANSLATED:0456e0e2]
*/
const char* getTrackString(TrackType type);
@@ -67,41 +73,67 @@ const char* getTrackString(TrackType type);
* 根据SDP中描述获取codec_id
* @param str
* @return
* Get codec_id from SDP description
* @param str
* @return
* [AUTO-TRANSLATED:024f2ed1]
*/
CodecId getCodecId(const std::string &str);
/**
* 获取编码器名称
* Get encoder name
* [AUTO-TRANSLATED:0253534b]
*/
const char *getCodecName(CodecId codecId);
/**
* 获取音视频类型
* Get audio/video type
* [AUTO-TRANSLATED:e2f06ac2]
*/
TrackType getTrackType(CodecId codecId);
/**
* 根据codecid获取mov object id
* Get mov object id by codecid
* [AUTO-TRANSLATED:c315b87d]
*/
int getMovIdByCodec(CodecId codecId);
/**
* 根据mov object id获取CodecId
* Get CodecId by mov object id
* [AUTO-TRANSLATED:de2237a1]
*/
CodecId getCodecByMovId(int object_id);
/**
* 根据codecid获取mpeg id
* Get mpeg id by codecid
* [AUTO-TRANSLATED:d365eac7]
*/
int getMpegIdByCodec(CodecId codec);
/**
* 根据mpeg id获取CodecId
* Get CodecId by mpeg id
* [AUTO-TRANSLATED:ca190565]
*/
CodecId getCodecByMpegId(int mpeg_id);
/**
* 编码信息的抽象接口
* Abstract interface for encoding information
* [AUTO-TRANSLATED:c3b14625]
*/
class CodecInfo {
public:
@@ -111,31 +143,49 @@ public:
/**
* 获取编解码器类型
* Get codec type
* [AUTO-TRANSLATED:2dbf103b]
*/
virtual CodecId getCodecId() const = 0;
/**
* 获取编码器名称
* Get encoder name
* [AUTO-TRANSLATED:a92f41f6]
*/
const char *getCodecName() const;
/**
* 获取音视频类型
* Get audio/video type
* [AUTO-TRANSLATED:ff8ba95b]
*/
TrackType getTrackType() const;
/**
* 获取音视频类型描述
* Get audio/video type description
* [AUTO-TRANSLATED:a460e432]
*/
std::string getTrackTypeStr() const;
/**
* 设置track index, 用于支持多track
* Set track index, for multi-track support
* [AUTO-TRANSLATED:da5bdb91]
*/
void setIndex(int index) { _index = index; }
/**
* 获取track index, 用于支持多track
* Get track index, for multi-track support
* [AUTO-TRANSLATED:1e96c587]
*/
int getIndex() const { return _index < 0 ? (int)getTrackType() : _index; }
@@ -145,6 +195,9 @@ private:
/**
* 帧类型的抽象接口
* Abstract interface for frame types
* [AUTO-TRANSLATED:eb166e7e]
*/
class Frame : public toolkit::Buffer, public CodecInfo {
public:
@@ -152,32 +205,51 @@ public:
/**
* 返回解码时间戳,单位毫秒
* Return decoding timestamp, in milliseconds
* [AUTO-TRANSLATED:00072dad]
*/
virtual uint64_t dts() const = 0;
/**
* 返回显示时间戳,单位毫秒
* Return display timestamp, in milliseconds
* [AUTO-TRANSLATED:c7eecb91]
*/
virtual uint64_t pts() const { return dts(); }
/**
* 前缀长度譬如264前缀为0x00 00 00 01,那么前缀长度就是4
* aac前缀则为7个字节
* Prefix length, for example, the 264 prefix is 0x00 00 00 01, so the prefix length is 4
* aac prefix is 7 bytes
* [AUTO-TRANSLATED:6334f58e]
*/
virtual size_t prefixSize() const = 0;
/**
* 返回是否为关键帧
* Return whether it is a key frame
* [AUTO-TRANSLATED:2e52426a]
*/
virtual bool keyFrame() const = 0;
/**
* 是否为配置帧譬如sps pps vps
* Whether it is a configuration frame, such as sps pps vps
* [AUTO-TRANSLATED:595c7ecf]
*/
virtual bool configFrame() const = 0;
/**
* 是否可以缓存
* Whether it can be cached
* [AUTO-TRANSLATED:5c35d3e0]
*/
virtual bool cacheAble() const { return true; }
@@ -185,29 +257,44 @@ public:
* 该帧是否可以丢弃
* SEI/AUD帧可以丢弃
* 默认都不能丢帧
* Whether this frame can be dropped
* SEI/AUD frames can be dropped
* By default, no frames can be dropped
* [AUTO-TRANSLATED:42957087]
*/
virtual bool dropAble() const { return false; }
/**
* 是否为可解码帧
* sps pps等帧不能解码
* Whether it is a decodable frame
* sps pps frames cannot be decoded
* [AUTO-TRANSLATED:52f093c7]
*/
virtual bool decodeAble() const {
if (getTrackType() != TrackVideo) {
//非视频帧都可以解码
// 非视频帧都可以解码 [AUTO-TRANSLATED:24aa4342]
// Non-video frames can be decoded
return true;
}
//默认非sps pps帧都可以解码
// 默认非sps pps帧都可以解码 [AUTO-TRANSLATED:b14d1e34]
// By default, non-sps pps frames can be decoded
return !configFrame();
}
/**
* 返回可缓存的frame
* Return the cacheable frame
* [AUTO-TRANSLATED:88fb9c3e]
*/
static Ptr getCacheAbleFrame(const Ptr &frame);
private:
//对象个数统计
// 对象个数统计 [AUTO-TRANSLATED:3b43e8c2]
// Object count statistics
toolkit::ObjectStatistic<Frame> _statistic;
};
@@ -250,7 +337,8 @@ public:
toolkit::BufferLikeString _buffer;
private:
//对象个数统计
// 对象个数统计 [AUTO-TRANSLATED:3b43e8c2]
// Object count statistics
toolkit::ObjectStatistic<FrameImp> _statistic;
protected:
@@ -258,7 +346,8 @@ protected:
FrameImp() = default;
};
// 包装一个指针成不可缓存的frame
// 包装一个指针成不可缓存的frame [AUTO-TRANSLATED:c3e5d65e]
// Wrap a pointer into a non-cacheable frame
class FrameFromPtr : public Frame {
public:
using Ptr = std::shared_ptr<FrameFromPtr>;
@@ -311,6 +400,12 @@ protected:
* ZLMediaKit会先把这种复合帧split成单个帧然后再处理
* 一个复合帧可以通过无内存拷贝的方式切割成多个子Frame
* 提供该类的目的是切割复合帧时防止内存拷贝,提高性能
* A Frame class can have multiple frames (AAC), and the timestamp will change
* ZLMediaKit will first split this composite frame into single frames and then process it
* A composite frame can be split into multiple sub-Frames without memory copy
* The purpose of providing this class is to prevent memory copy when splitting composite frames, improving performance
* [AUTO-TRANSLATED:4010c0a5]
*/
template <typename Parent>
class FrameInternalBase : public Parent {
@@ -333,6 +428,12 @@ private:
* ZLMediaKit会先把这种复合帧split成单个帧然后再处理
* 一个复合帧可以通过无内存拷贝的方式切割成多个子Frame
* 提供该类的目的是切割复合帧时防止内存拷贝,提高性能
* A Frame class can have multiple frames, they are separated by 0x 00 00 01
* ZLMediaKit will first split this composite frame into single frames and then process it
* A composite frame can be split into multiple sub-Frames without memory copy
* The purpose of providing this class is to prevent memory copy when splitting composite frames, improving performance
* [AUTO-TRANSLATED:ed49148b]
*/
template <typename Parent>
class FrameInternal : public FrameInternalBase<Parent> {
@@ -342,7 +443,8 @@ public:
: FrameInternalBase<Parent>(parent_frame, ptr, size, parent_frame->dts(), parent_frame->pts(), prefix_size) {}
};
// 管理一个指针生命周期并生产一个frame
// 管理一个指针生命周期并生产一个frame [AUTO-TRANSLATED:449d107b]
// Manage the lifetime of a pointer and produce a frame
class FrameAutoDelete : public FrameFromPtr {
public:
template <typename... ARGS>
@@ -353,7 +455,8 @@ public:
bool cacheAble() const override { return true; }
};
// 把一个不可缓存的frame声明为可缓存的
// 把一个不可缓存的frame声明为可缓存的 [AUTO-TRANSLATED:2c8d0659]
// Declare a non-cacheable frame as cacheable
template <typename Parent>
class FrameToCache : public Parent {
public:
@@ -365,7 +468,8 @@ public:
}
};
// 该对象的功能是把一个不可缓存的帧转换成可缓存的帧
// 该对象的功能是把一个不可缓存的帧转换成可缓存的帧 [AUTO-TRANSLATED:5851119b]
// The function of this object is to convert a non-cacheable frame into a cacheable frame
class FrameCacheAble : public FrameFromPtr {
public:
using Ptr = std::shared_ptr<FrameCacheAble>;
@@ -397,6 +501,9 @@ public:
/**
* 可以被缓存
* Can be cached
* [AUTO-TRANSLATED:7f9cec13]
*/
bool cacheAble() const override { return true; }
bool keyFrame() const override { return _key; }
@@ -412,7 +519,8 @@ private:
toolkit::Buffer::Ptr _buffer;
};
//该类实现frame级别的时间戳覆盖
// 该类实现frame级别的时间戳覆盖 [AUTO-TRANSLATED:77c28d0f]
// This class implements frame-level timestamp overwrite
class FrameStamp : public Frame {
public:
using Ptr = std::shared_ptr<FrameStamp>;
@@ -439,6 +547,9 @@ private:
/**
* 该对象可以把Buffer对象转换成可缓存的Frame对象
* This object can convert a Buffer object into a cacheable Frame object
* [AUTO-TRANSLATED:3c5786b8]
*/
template <typename Parent>
class FrameFromBuffer : public Parent {
@@ -450,6 +561,14 @@ public:
* @param pts 显示时间戳
* @param prefix 帧前缀长度
* @param offset buffer有效数据偏移量
* Construct frame
* @param buf Data cache
* @param dts Decode timestamp
* @param pts Display timestamp
* @param prefix Frame prefix length
* @param offset Buffer valid data offset
* [AUTO-TRANSLATED:6afec0f1]
*/
FrameFromBuffer(toolkit::Buffer::Ptr buf, uint64_t dts, uint64_t pts, size_t prefix = 0, size_t offset = 0)
: Parent(buf->data() + offset, buf->size() - offset, dts, pts, prefix) {
@@ -464,6 +583,15 @@ public:
* @param prefix 帧前缀长度
* @param offset buffer有效数据偏移量
* @param codec 帧类型
* Construct frame
* @param buf Data cache
* @param dts Decode timestamp
* @param pts Display timestamp
* @param prefix Frame prefix length
* @param offset Buffer valid data offset
* @param codec Frame type
* [AUTO-TRANSLATED:f1c42e38]
*/
FrameFromBuffer(CodecId codec, toolkit::Buffer::Ptr buf, uint64_t dts, uint64_t pts, size_t prefix = 0, size_t offset = 0)
: Parent(codec, buf->data() + offset, buf->size() - offset, dts, pts, prefix) {
@@ -472,6 +600,9 @@ public:
/**
* 该帧可缓存
* This frame is cacheable
* [AUTO-TRANSLATED:e089250f]
*/
bool cacheAble() const override { return true; }
@@ -481,6 +612,9 @@ private:
/**
* 合并一些时间戳相同的frame
* Merge some frames with the same timestamp
* [AUTO-TRANSLATED:392a23df]
*/
class FrameMerger {
public:
@@ -497,6 +631,10 @@ public:
/**
* 刷新输出缓冲注意此时会调用FrameMerger::inputFrame传入的onOutput回调
* 请注意回调捕获参数此时是否有效
* Refresh the output buffer, note that FrameMerger::inputFrame's onOutput callback will be called at this time
* Please note whether the callback capture parameters are valid at this time
* [AUTO-TRANSLATED:18c25a14]
*/
void flush();
void clear();
@@ -515,6 +653,9 @@ private:
/**
* 写帧接口的抽象接口类
* Abstract interface class for write frame interface
* [AUTO-TRANSLATED:dbe6a33c]
*/
class FrameWriterInterface {
public:
@@ -523,17 +664,26 @@ public:
/**
* 写入帧数据
* Write frame data
* [AUTO-TRANSLATED:d46c6fc2]
*/
virtual bool inputFrame(const Frame::Ptr &frame) = 0;
/**
* 刷新输出所有frame缓存
* Flush all frame caches in the output
* [AUTO-TRANSLATED:adaea568]
*/
virtual void flush() {};
};
/**
* 支持代理转发的帧环形缓存
* Frame circular buffer that supports proxy forwarding
* [AUTO-TRANSLATED:06bf1541]
*/
class FrameDispatcher : public FrameWriterInterface {
public:
@@ -541,6 +691,9 @@ public:
/**
* 添加代理
* Add proxy
* [AUTO-TRANSLATED:0be3c076]
*/
FrameWriterInterface* addDelegate(FrameWriterInterface::Ptr delegate) {
std::lock_guard<std::recursive_mutex> lck(_mtx);
@@ -551,6 +704,9 @@ public:
/**
* 删除代理
* Delete proxy
* [AUTO-TRANSLATED:c2c915aa]
*/
void delDelegate(FrameWriterInterface *ptr) {
std::lock_guard<std::recursive_mutex> lck(_mtx);
@@ -559,6 +715,9 @@ public:
/**
* 写入帧并派发
* Write frame and dispatch
* [AUTO-TRANSLATED:a3e7e6db]
*/
bool inputFrame(const Frame::Ptr &frame) override {
std::lock_guard<std::recursive_mutex> lck(_mtx);
@@ -574,6 +733,9 @@ public:
/**
* 返回代理个数
* Return the number of proxies
* [AUTO-TRANSLATED:93ebe7ec]
*/
size_t size() const {
std::lock_guard<std::recursive_mutex> lck(_mtx);
@@ -587,6 +749,9 @@ public:
/**
* 获取累计关键帧数
* Get the cumulative number of keyframes
* [AUTO-TRANSLATED:73cb2ab0]
*/
uint64_t getVideoKeyFrames() const {
std::lock_guard<std::recursive_mutex> lck(_mtx);
@@ -595,6 +760,9 @@ public:
/**
* 获取帧数
* Get the number of frames
* [AUTO-TRANSLATED:118b395e]
*/
uint64_t getFrames() const {
std::lock_guard<std::recursive_mutex> lck(_mtx);
@@ -619,12 +787,14 @@ public:
private:
void doStatistics(const Frame::Ptr &frame) {
if (!frame->configFrame() && !frame->dropAble()) {
// 忽略配置帧与可丢弃的帧
// 忽略配置帧与可丢弃的帧 [AUTO-TRANSLATED:da4ff7ac]
// Ignore configuration frames and discardable frames
++_frames;
int64_t out;
_stamp.revise(frame->dts(), frame->pts(), out, out);
if (frame->keyFrame() && frame->getTrackType() == TrackVideo) {
// 遇视频关键帧时统计
// 遇视频关键帧时统计 [AUTO-TRANSLATED:72b0e569]
// Statistics when encountering video keyframes
++_video_key_frames;
_gop_size = _frames - _last_frames;
_gop_interval_ms = _ticker.elapsedTime();

View File

@@ -20,6 +20,9 @@ namespace mediakit{
/**
* 媒体通道描述类,也支持帧输入输出
* Media channel description class, also supports frame input and output
* [AUTO-TRANSLATED:a3acd089]
*/
class Track : public FrameDispatcher, public CodecInfo {
public:
@@ -27,12 +30,19 @@ public:
/**
* 默认构造
* Default constructor
* [AUTO-TRANSLATED:acda54ab]
*/
Track() = default;
/**
* 复制拷贝,只能拷贝派生类的信息,
* 环形缓存和代理关系不能拷贝,否则会关系紊乱
* Copy, only copy information of derived classes,
* Circular buffer and proxy relationships cannot be copied, otherwise the relationship will be disordered
* [AUTO-TRANSLATED:308e6502]
*/
Track(const Track &that) {
_bit_rate = that._bit_rate;
@@ -41,6 +51,9 @@ public:
/**
* 是否准备好准备好才能获取譬如sps pps等信息
* Whether it is ready, it can be used to get information such as sps pps
* [AUTO-TRANSLATED:6d819ef7]
*/
virtual bool ready() const = 0;
@@ -48,39 +61,65 @@ public:
* 克隆接口,用于复制本对象用
* 在调用该接口时只会复制派生类的信息
* 环形缓存和代理关系不能拷贝,否则会关系紊乱
* Clone interface, used to copy this object
* When calling this interface, only the information of the derived class will be copied
* Circular buffer and proxy relationships cannot be copied, otherwise the relationship will be disordered
* [AUTO-TRANSLATED:270874c6]
*/
virtual Track::Ptr clone() const = 0;
/**
* 更新track信息比如触发sps/pps解析
* Update track information, such as triggering sps/pps parsing
* [AUTO-TRANSLATED:324879ef]
*/
virtual bool update() { return false; }
/**
* 生成sdp
* @return sdp对象
* Generate sdp
* @return sdp object
* [AUTO-TRANSLATED:3ab2fd30]
*/
virtual Sdp::Ptr getSdp(uint8_t payload_type) const = 0;
/**
* 获取extra data, 一般用于rtmp/mp4生成
* Get extra data, generally used for rtmp/mp4 generation
* [AUTO-TRANSLATED:d8ff2cd5]
*/
virtual toolkit::Buffer::Ptr getExtraData() const { return nullptr; }
/**
* 设置extra data
* Set extra data,
* [AUTO-TRANSLATED:9e551857]
*/
virtual void setExtraData(const uint8_t *data, size_t size) {}
/**
* 返回比特率
* @return 比特率
* Return bitrate
* @return Bitrate
* [AUTO-TRANSLATED:265dda35]
*/
virtual int getBitRate() const { return _bit_rate; }
/**
* 设置比特率
* @param bit_rate 比特率
* Set bitrate
* @param bit_rate Bitrate
* [AUTO-TRANSLATED:77a43064]
*/
virtual void setBitRate(int bit_rate) { _bit_rate = bit_rate; }
@@ -90,6 +129,9 @@ private:
/**
* 视频通道描述Track类支持获取宽高fps信息
* Video channel description Track class, supports getting width, height and fps information
* [AUTO-TRANSLATED:8d1893c5]
*/
class VideoTrack : public Track {
public:
@@ -97,21 +139,33 @@ public:
/**
* 返回视频高度
* Return video height
* [AUTO-TRANSLATED:b24aabc0]
*/
virtual int getVideoHeight() const { return 0; }
/**
* 返回视频宽度
* Return video width
* [AUTO-TRANSLATED:2f3bb6e3]
*/
virtual int getVideoWidth() const { return 0; }
/**
* 返回视频fps
* Return video fps
* [AUTO-TRANSLATED:ced99aef]
*/
virtual float getVideoFps() const { return 0; }
/**
* 返回相关 sps/pps 等
* Return related sps/pps, etc.
* [AUTO-TRANSLATED:30fc4f63]
*/
virtual std::vector<Frame::Ptr> getConfigFrames() const { return std::vector<Frame::Ptr>{}; }
};
@@ -126,6 +180,13 @@ public:
* @param width 宽
* @param height 高
* @param fps 帧率
* Constructor
* @param codec_id Encoding type
* @param width Width
* @param height Height
* @param fps Frame rate
* [AUTO-TRANSLATED:b3d1ef4d]
*/
VideoTrackImp(CodecId codec_id, int width, int height, int fps) {
_codec_id = codec_id;
@@ -152,6 +213,9 @@ private:
/**
* 音频Track派生类支持采样率通道数采用位数信息
* Audio Track derived class, supports sampling rate, number of channels, and sampling bit information
* [AUTO-TRANSLATED:5f57819d]
*/
class AudioTrack : public Track {
public:
@@ -159,16 +223,25 @@ public:
/**
* 返回音频采样率
* Return audio sampling rate
* [AUTO-TRANSLATED:9af5a0a4]
*/
virtual int getAudioSampleRate() const {return 0;};
/**
* 返回音频采样位数一般为16或8
* Return audio sampling bit depth, generally 16 or 8
* [AUTO-TRANSLATED:5fedc65d]
*/
virtual int getAudioSampleBit() const {return 0;};
/**
* 返回音频通道数
* Return audio number of channels
* [AUTO-TRANSLATED:2613b317]
*/
virtual int getAudioChannel() const {return 0;};
};
@@ -183,6 +256,13 @@ public:
* @param sample_rate 采样率(HZ)
* @param channels 通道数
* @param sample_bit 采样位数一般为16
* Constructor
* @param codecId Encoding type
* @param sample_rate Sampling rate (HZ)
* @param channels Number of channels
* @param sample_bit Sampling bit depth, generally 16
* [AUTO-TRANSLATED:0ad0211f]
*/
AudioTrackImp(CodecId codecId, int sample_rate, int channels, int sample_bit){
_codecid = codecId;
@@ -193,6 +273,9 @@ public:
/**
* 返回编码类型
* Return encoding type
* [AUTO-TRANSLATED:c8731864]
*/
CodecId getCodecId() const override{
return _codecid;
@@ -200,6 +283,9 @@ public:
/**
* 是否已经初始化
* Whether it has been initialized
* [AUTO-TRANSLATED:5dc6693e]
*/
bool ready() const override {
return true;
@@ -207,6 +293,9 @@ public:
/**
* 返回音频采样率
* Return audio sampling rate
* [AUTO-TRANSLATED:9af5a0a4]
*/
int getAudioSampleRate() const override{
return _sample_rate;
@@ -214,6 +303,9 @@ public:
/**
* 返回音频采样位数一般为16或8
* Return audio sampling bit depth, generally 16 or 8
* [AUTO-TRANSLATED:5fedc65d]
*/
int getAudioSampleBit() const override{
return _sample_bit;
@@ -221,6 +313,9 @@ public:
/**
* 返回音频通道数
* Return audio number of channels
* [AUTO-TRANSLATED:2613b317]
*/
int getAudioChannel() const override{
return _channels;
@@ -243,6 +338,10 @@ public:
/**
* 获取全部的Track
* @param trackReady 是否获取全部已经准备好的Track
* Get all Tracks
* @param trackReady Whether to get all ready Tracks
* [AUTO-TRANSLATED:f0779985]
*/
virtual std::vector<Track::Ptr> getTracks(bool trackReady = true) const = 0;
@@ -250,6 +349,10 @@ public:
* 获取特定Track
* @param type track类型
* @param trackReady 是否获取全部已经准备好的Track
* Get specific Track
* @param type Track type
* @param trackReady Whether to get all ready Tracks
* [AUTO-TRANSLATED:c50781b9]
*/
Track::Ptr getTrack(TrackType type , bool trackReady = true) const {
auto tracks = getTracks(trackReady);