mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 12:37:09 +08:00
Merge branch 'dev' of https://gitee.com/xia-chu/ZLMediaKit into dev_test
This commit is contained in:
commit
430229fe94
@ -267,11 +267,44 @@ bool FrameMerger::shouldDrop(const Frame::Ptr &frame) const{
|
|||||||
}
|
}
|
||||||
return false;
|
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) {
|
void FrameMerger::inputFrame(const Frame::Ptr &frame, const onOutput &cb) {
|
||||||
if(shouldDrop(frame)){
|
if(shouldDrop(frame)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (willFlush(frame)) {
|
if (willFlush(frame) && frameCacheHasVCL(_frameCached)) {
|
||||||
Frame::Ptr back = _frameCached.back();
|
Frame::Ptr back = _frameCached.back();
|
||||||
Buffer::Ptr merged_frame = back;
|
Buffer::Ptr merged_frame = back;
|
||||||
bool have_idr = back->keyFrame();
|
bool have_idr = back->keyFrame();
|
||||||
|
@ -476,6 +476,7 @@ private:
|
|||||||
bool willFlush(const Frame::Ptr &frame) const;
|
bool willFlush(const Frame::Ptr &frame) const;
|
||||||
void doMerge(BufferLikeString &buffer, const Frame::Ptr &frame) const;
|
void doMerge(BufferLikeString &buffer, const Frame::Ptr &frame) const;
|
||||||
bool shouldDrop(const Frame::Ptr &frame) const;
|
bool shouldDrop(const Frame::Ptr &frame) const;
|
||||||
|
bool frameCacheHasVCL(List<Frame::Ptr> &frameCached) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _type;
|
int _type;
|
||||||
|
@ -159,7 +159,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
auto pcData = frame->data() + frame->prefixSize();
|
auto pcData = frame->data() + frame->prefixSize();
|
||||||
auto iLen = frame->size() - frame->prefixSize();
|
auto iLen = frame->size() - frame->prefixSize();
|
||||||
auto type = H264_TYPE(((uint8_t*)pcData)[0]);
|
auto type = H264_TYPE(((uint8_t*)pcData)[0]);
|
||||||
if(type == H264Frame::NAL_SEI){
|
if(type == H264Frame::NAL_SEI || type == H264Frame::NAL_AUD){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,10 +182,20 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(frame->configFrame() && _lastPacket &&_lastPacketHasVCL){
|
||||||
if(_lastPacket && (_lastPacket->time_stamp != frame->dts() || ((pcData[1]&0x80) != 0 && type>=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR))) {
|
//sps pps flush frame
|
||||||
RtmpCodec::inputRtmp(_lastPacket);
|
RtmpCodec::inputRtmp(_lastPacket);
|
||||||
_lastPacket = nullptr;
|
_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) {
|
if(!_lastPacket) {
|
||||||
|
@ -80,6 +80,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
H264Track::Ptr _track;
|
H264Track::Ptr _track;
|
||||||
bool _gotSpsPps = false;
|
bool _gotSpsPps = false;
|
||||||
|
bool _lastPacketHasVCL = false;
|
||||||
RtmpPacket::Ptr _lastPacket;
|
RtmpPacket::Ptr _lastPacket;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,9 +169,21 @@ void H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
return;// 防止sei aud 作为一帧
|
return;// 防止sei aud 作为一帧
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_lastPacket && (_lastPacket->time_stamp != frame->dts() || (type >=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR && (pcData[2]>>7 &0x01) !=0))) {
|
if(frame->configFrame() && _lastPacket &&_lastPacketHasVCL){
|
||||||
|
// sps pps flush frame
|
||||||
RtmpCodec::inputRtmp(_lastPacket);
|
RtmpCodec::inputRtmp(_lastPacket);
|
||||||
_lastPacket = nullptr;
|
_lastPacket = nullptr;
|
||||||
|
_lastPacketHasVCL = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lastPacket && (_lastPacket->time_stamp != frame->dts() || (_lastPacketHasVCL &&type>=H265Frame::NAL_TRAIL_R &&type<= H265Frame::NAL_RSV_IRAP_VCL23 && (pcData[2]>>7 &0x01) !=0))) {
|
||||||
|
RtmpCodec::inputRtmp(_lastPacket);
|
||||||
|
_lastPacket = nullptr;
|
||||||
|
_lastPacketHasVCL = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type>=H265Frame::NAL_TRAIL_R &&type<= H265Frame::NAL_RSV_IRAP_VCL23){
|
||||||
|
_lastPacketHasVCL = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_lastPacket) {
|
if(!_lastPacket) {
|
||||||
@ -179,7 +191,9 @@ void H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
int8_t flags = FLV_CODEC_H265;
|
int8_t flags = FLV_CODEC_H265;
|
||||||
bool is_config = false;
|
bool is_config = false;
|
||||||
flags |= (((frame->configFrame() || frame->keyFrame()) ? FLV_KEY_FRAME : FLV_INTER_FRAME) << 4);
|
flags |= (((frame->configFrame() || frame->keyFrame()) ? FLV_KEY_FRAME : FLV_INTER_FRAME) << 4);
|
||||||
|
// to do
|
||||||
|
// 必须是IDR帧才能是关键帧,否则有可能开始帧会花屏 SPS PPS VPS 打头的是一般I帧,但不一定是IDR帧
|
||||||
|
// RtmpCodec::inputRtmp 时需要判断 是否是IDR帧,做出相应的修改
|
||||||
_lastPacket = RtmpPacket::create();
|
_lastPacket = RtmpPacket::create();
|
||||||
_lastPacket->buffer.push_back(flags);
|
_lastPacket->buffer.push_back(flags);
|
||||||
_lastPacket->buffer.push_back(!is_config);
|
_lastPacket->buffer.push_back(!is_config);
|
||||||
|
@ -84,6 +84,7 @@ private:
|
|||||||
string _pps;
|
string _pps;
|
||||||
H265Track::Ptr _track;
|
H265Track::Ptr _track;
|
||||||
RtmpPacket::Ptr _lastPacket;
|
RtmpPacket::Ptr _lastPacket;
|
||||||
|
bool _lastPacketHasVCL = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
@ -68,7 +68,13 @@ foreach(TEST_SRC ${TEST_SRC_LIST})
|
|||||||
if(WIN32)
|
if(WIN32)
|
||||||
set_target_properties(${TEST_EXE_NAME} PROPERTIES COMPILE_FLAGS ${VS_FALGS} )
|
set_target_properties(${TEST_EXE_NAME} PROPERTIES COMPILE_FLAGS ${VS_FALGS} )
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
target_link_libraries(${TEST_EXE_NAME} -Wl,--start-group ${LINK_LIB_LIST} -Wl,--end-group)
|
||||||
|
else ()
|
||||||
target_link_libraries(${TEST_EXE_NAME} ${LINK_LIB_LIST})
|
target_link_libraries(${TEST_EXE_NAME} ${LINK_LIB_LIST})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
#target_link_libraries(${TEST_EXE_NAME} ${LINK_LIB_LIST})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if(MSVC AND SDL2_FOUND AND AVCODEC_FOUND AND AVUTIL_FOUND)
|
if(MSVC AND SDL2_FOUND AND AVCODEC_FOUND AND AVUTIL_FOUND)
|
||||||
|
Loading…
Reference in New Issue
Block a user