新增媒体流flush机制:#1996

This commit is contained in:
ziyue
2022-10-16 19:49:56 +08:00
parent 80eef693c6
commit ac1abb34da
44 changed files with 287 additions and 124 deletions

View File

@@ -155,7 +155,7 @@ void FrameMerger::doMerge(BufferLikeString &merged, const Frame::Ptr &frame) con
}
}
bool FrameMerger::inputFrame(const Frame::Ptr &frame, const onOutput &cb, BufferLikeString *buffer) {
bool FrameMerger::inputFrame(const Frame::Ptr &frame, onOutput cb, BufferLikeString *buffer) {
if (willFlush(frame)) {
Frame::Ptr back = _frame_cache.back();
Buffer::Ptr merged_frame = back;
@@ -190,6 +190,7 @@ bool FrameMerger::inputFrame(const Frame::Ptr &frame, const onOutput &cb, Buffer
if (frame->decodeAble()) {
_have_decode_able_frame = true;
}
_cb = std::move(cb);
_frame_cache.emplace_back(Frame::getCacheAbleFrame(frame));
return true;
}
@@ -203,4 +204,11 @@ void FrameMerger::clear() {
_have_decode_able_frame = false;
}
void FrameMerger::flush() {
if (_cb) {
inputFrame(nullptr, std::move(_cb), nullptr);
}
clear();
}
}//namespace mediakit

View File

@@ -271,6 +271,11 @@ public:
* 写入帧数据
*/
virtual bool inputFrame(const Frame::Ptr &frame) = 0;
/**
* 刷新输出所有frame缓存
*/
virtual void flush() {};
};
/**
@@ -542,8 +547,13 @@ public:
FrameMerger(int type);
~FrameMerger() = default;
/**
* 刷新输出缓冲注意此时会调用FrameMerger::inputFrame传入的onOutput回调
* 请注意回调捕获参数此时是否有效
*/
void flush();
void clear();
bool inputFrame(const Frame::Ptr &frame, const onOutput &cb, toolkit::BufferLikeString *buffer = nullptr);
bool inputFrame(const Frame::Ptr &frame, onOutput cb, toolkit::BufferLikeString *buffer = nullptr);
private:
bool willFlush(const Frame::Ptr &frame) const;
@@ -552,6 +562,7 @@ private:
private:
int _type;
bool _have_decode_able_frame = false;
onOutput _cb;
toolkit::List<Frame::Ptr> _frame_cache;
};

View File

@@ -124,26 +124,32 @@ void H264RtmpEncoder::makeConfigPacket(){
}
}
void H264RtmpEncoder::flush() {
inputFrame(nullptr);
}
bool H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
auto data = frame->data() + frame->prefixSize();
auto len = frame->size() - frame->prefixSize();
auto type = H264_TYPE(data[0]);
switch (type) {
case H264Frame::NAL_SPS: {
if (!_got_config_frame) {
_sps = string(data, len);
makeConfigPacket();
if (frame) {
auto data = frame->data() + frame->prefixSize();
auto len = frame->size() - frame->prefixSize();
auto type = H264_TYPE(data[0]);
switch (type) {
case H264Frame::NAL_SPS: {
if (!_got_config_frame) {
_sps = string(data, len);
makeConfigPacket();
}
break;
}
break;
}
case H264Frame::NAL_PPS: {
if (!_got_config_frame) {
_pps = string(data, len);
makeConfigPacket();
case H264Frame::NAL_PPS: {
if (!_got_config_frame) {
_pps = string(data, len);
makeConfigPacket();
}
break;
}
break;
default: break;
}
default : break;
}
if (!_rtmp_packet) {

View File

@@ -62,7 +62,7 @@ public:
* @param track
*/
H264RtmpEncoder(const Track::Ptr &track);
~H264RtmpEncoder() {}
~H264RtmpEncoder() = default;
/**
* 输入264帧可以不带sps pps
@@ -70,6 +70,11 @@ public:
*/
bool inputFrame(const Frame::Ptr &frame) override;
/**
* 刷新输出所有frame缓存
*/
void flush() override;
/**
* 生成config包
*/

View File

@@ -291,6 +291,14 @@ bool H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
return true;
}
void H264RtpEncoder::flush() {
if (_last_frame) {
// 如果时间戳发生了变化那么markbit才置true
inputFrame_l(_last_frame, true);
_last_frame = nullptr;
}
}
bool H264RtpEncoder::inputFrame_l(const Frame::Ptr &frame, bool is_mark){
if (frame->keyFrame()) {
//保证每一个关键帧前都有SPS与PPS

View File

@@ -85,6 +85,11 @@ public:
*/
bool inputFrame(const Frame::Ptr &frame) override;
/**
* 刷新输出所有frame缓存
*/
void flush() override;
private:
void insertConfigFrame(uint64_t pts);
bool inputFrame_l(const Frame::Ptr &frame, bool is_mark);

View File

@@ -138,33 +138,39 @@ void H265RtmpEncoder::makeConfigPacket(){
}
}
void H265RtmpEncoder::flush() {
inputFrame(nullptr);
}
bool H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
auto data = frame->data() + frame->prefixSize();
auto len = frame->size() - frame->prefixSize();
auto type = H265_TYPE(data[0]);
switch (type) {
case H265Frame::NAL_SPS: {
if (!_got_config_frame) {
_sps = string(data, len);
makeConfigPacket();
if (frame) {
auto data = frame->data() + frame->prefixSize();
auto len = frame->size() - frame->prefixSize();
auto type = H265_TYPE(data[0]);
switch (type) {
case H265Frame::NAL_SPS: {
if (!_got_config_frame) {
_sps = string(data, len);
makeConfigPacket();
}
break;
}
break;
}
case H265Frame::NAL_PPS: {
if (!_got_config_frame) {
_pps = string(data, len);
makeConfigPacket();
case H265Frame::NAL_PPS: {
if (!_got_config_frame) {
_pps = string(data, len);
makeConfigPacket();
}
break;
}
break;
}
case H265Frame::NAL_VPS: {
if (!_got_config_frame) {
_vps = string(data, len);
makeConfigPacket();
case H265Frame::NAL_VPS: {
if (!_got_config_frame) {
_vps = string(data, len);
makeConfigPacket();
}
break;
}
break;
default: break;
}
default: break;
}
if (!_rtmp_packet) {

View File

@@ -60,7 +60,7 @@ public:
* @param track
*/
H265RtmpEncoder(const Track::Ptr &track);
~H265RtmpEncoder() {}
~H265RtmpEncoder() = default;
/**
* 输入265帧可以不带sps pps
@@ -68,6 +68,11 @@ public:
*/
bool inputFrame(const Frame::Ptr &frame) override;
/**
* 刷新输出所有frame缓存
*/
void flush() override;
/**
* 生成config包
*/