mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 04:31:37 +08:00
for frame merge must has vlc(video codec layer) data and flush rtmp a frame must has vcl
This commit is contained in:
parent
2335043cdf
commit
a28aeb2148
@ -267,11 +267,44 @@ bool FrameMerger::shouldDrop(const Frame::Ptr &frame) const{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool FrameMerger::frameCacheHasVCL(List<Frame::Ptr> &frameCached) const{
|
||||
bool hasVCL = false;
|
||||
bool isH264OrH265 = false;
|
||||
frameCached.for_each([&hasVCL,&isH264OrH265](const Frame::Ptr &frame){
|
||||
switch (frame->getCodecId()) {
|
||||
case CodecH264:{
|
||||
auto type = H264_TYPE(frame->data()[frame->prefixSize()]);
|
||||
if(type >=H264Frame::NAL_B_P && type <= H264Frame::NAL_IDR){
|
||||
//有编码数据
|
||||
hasVCL=true;
|
||||
}
|
||||
isH264OrH265 = true;
|
||||
break;
|
||||
}
|
||||
case CodecH265: {
|
||||
//如果是新的一帧,前面的缓存需要输出
|
||||
auto type = H265_TYPE(frame->data()[frame->prefixSize()]);
|
||||
if(type>=H265Frame::NAL_TRAIL_R &&type<= H265Frame::NAL_RSV_IRAP_VCL23){
|
||||
//有编码数据
|
||||
hasVCL=true;
|
||||
}
|
||||
isH264OrH265 = true;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
});
|
||||
if(isH264OrH265){
|
||||
return hasVCL;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
void FrameMerger::inputFrame(const Frame::Ptr &frame, const onOutput &cb) {
|
||||
if(shouldDrop(frame)){
|
||||
return;
|
||||
}
|
||||
if (willFlush(frame)) {
|
||||
if (willFlush(frame) && frameCacheHasVCL(_frameCached)) {
|
||||
Frame::Ptr back = _frameCached.back();
|
||||
Buffer::Ptr merged_frame = back;
|
||||
bool have_idr = back->keyFrame();
|
||||
|
@ -476,6 +476,7 @@ private:
|
||||
bool willFlush(const Frame::Ptr &frame) const;
|
||||
void doMerge(BufferLikeString &buffer, const Frame::Ptr &frame) const;
|
||||
bool shouldDrop(const Frame::Ptr &frame) const;
|
||||
bool frameCacheHasVCL(List<Frame::Ptr> &frameCached) const;
|
||||
|
||||
private:
|
||||
int _type;
|
||||
|
@ -159,7 +159,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
auto pcData = frame->data() + frame->prefixSize();
|
||||
auto iLen = frame->size() - frame->prefixSize();
|
||||
auto type = H264_TYPE(((uint8_t*)pcData)[0]);
|
||||
if(type == H264Frame::NAL_SEI){
|
||||
if(type == H264Frame::NAL_SEI || type == H264Frame::NAL_AUD){
|
||||
return;
|
||||
}
|
||||
|
||||
@ -182,10 +182,20 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(_lastPacket && (_lastPacket->time_stamp != frame->dts() || ((pcData[1]&0x80) != 0 && type>=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR))) {
|
||||
if((frame->configFrame() || frame->keyFrame()) && _lastPacket){
|
||||
// key frame or sps pps flush frame
|
||||
RtmpCodec::inputRtmp(_lastPacket);
|
||||
_lastPacket = nullptr;
|
||||
_lastPacketHasVCL = false;
|
||||
}
|
||||
|
||||
if(_lastPacket && (_lastPacket->time_stamp != frame->dts() || ((pcData[1]&0x80) != 0 && type>=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR && _lastPacketHasVCL))) {
|
||||
RtmpCodec::inputRtmp(_lastPacket);
|
||||
_lastPacket = nullptr;
|
||||
_lastPacketHasVCL = false;
|
||||
}
|
||||
if(type>=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR){
|
||||
_lastPacketHasVCL = true;
|
||||
}
|
||||
|
||||
if(!_lastPacket) {
|
||||
|
@ -80,6 +80,7 @@ private:
|
||||
private:
|
||||
H264Track::Ptr _track;
|
||||
bool _gotSpsPps = false;
|
||||
bool _lastPacketHasVCL = false;
|
||||
RtmpPacket::Ptr _lastPacket;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user