1、修复生成的rtmp无法被flash播放的问题

2、修复RTSP有B帧时,相对时间戳计算异常的问题
This commit is contained in:
xiongziliang 2020-01-13 11:51:29 +08:00
parent db146406c3
commit 66ec67bfb9
4 changed files with 21 additions and 12 deletions

View File

@ -27,25 +27,27 @@
#include "Stamp.h" #include "Stamp.h"
#define MAX_DELTA_STAMP 300 #define MAX_DELTA_STAMP 300
#define ABS(x) ((x) > 0 ? (x) : (-x))
namespace mediakit { namespace mediakit {
int64_t DeltaStamp::deltaStamp(int64_t stamp) { int64_t DeltaStamp::deltaStamp(int64_t stamp) {
if(!_last_stamp){ if(!_last_stamp){
//第一次计算时间戳增量,时间戳增量为0 //第一次计算时间戳增量,时间戳增量为0
if(stamp){
_last_stamp = stamp; _last_stamp = stamp;
}
return 0; return 0;
} }
int64_t ret = stamp - _last_stamp; int64_t ret = stamp - _last_stamp;
if(ret >= 0){ if(ABS(ret) < MAX_DELTA_STAMP){
//时间戳增量为正,返回之 //时间戳变化不明显
_last_stamp = stamp; _last_stamp = stamp;
//在直播情况下时间戳增量不得大于MAX_DELTA_STAMP return ret;
return ret < MAX_DELTA_STAMP ? ret : (_playback ? ret : 0);
} }
//时间戳增量为负,说明时间戳回环了或回退 //时间戳变化太明显可能回环了或者seek
_last_stamp = stamp; _last_stamp = stamp;
return _playback ? ret : 0; return _playback ? ret : 0;
} }

View File

@ -49,6 +49,7 @@ public:
NAL_SPS = 7, NAL_SPS = 7,
NAL_PPS = 8, NAL_PPS = 8,
NAL_IDR = 5, NAL_IDR = 5,
NAL_SEI = 6,
} NalType; } NalType;
char *data() const override{ char *data() const override{

View File

@ -140,6 +140,10 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
} }
} }
if(type == H264Frame::NAL_SEI){
return;
}
if(_lastPacket && _lastPacket->timeStamp != frame->stamp()) { if(_lastPacket && _lastPacket->timeStamp != frame->stamp()) {
RtmpCodec::inputRtmp(_lastPacket, _lastPacket->isVideoKeyFrame()); RtmpCodec::inputRtmp(_lastPacket, _lastPacket->isVideoKeyFrame());
_lastPacket = nullptr; _lastPacket = nullptr;
@ -149,7 +153,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
//I or P or B frame //I or P or B frame
int8_t flags = 7; //h.264 int8_t flags = 7; //h.264
bool is_config = false; bool is_config = false;
flags |= ((frame->keyFrame() ? FLV_KEY_FRAME : FLV_INTER_FRAME) << 4); flags |= (((frame->configFrame() || frame->keyFrame()) ? FLV_KEY_FRAME : FLV_INTER_FRAME) << 4);
_lastPacket = ResourcePoolHelper<RtmpPacket>::obtainObj(); _lastPacket = ResourcePoolHelper<RtmpPacket>::obtainObj();
_lastPacket->strBuf.clear(); _lastPacket->strBuf.clear();

View File

@ -226,6 +226,8 @@ inline bool MP4Reader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) {
MP4Duration pRenderingOffset; MP4Duration pRenderingOffset;
if(MP4ReadSample(_hMP4File, _video_trId, iIdx + 1, &pBytes, &numBytes,NULL,NULL,&pRenderingOffset,&_bSyncSample)){ if(MP4ReadSample(_hMP4File, _video_trId, iIdx + 1, &pBytes, &numBytes,NULL,NULL,&pRenderingOffset,&_bSyncSample)){
if (!justSeekSyncFrame) { if (!justSeekSyncFrame) {
uint32_t dts = (double) _video_ms * iIdx / _video_num_samples;
uint32_t pts = dts + pRenderingOffset / 90;
uint32_t iOffset = 0; uint32_t iOffset = 0;
while (iOffset < numBytes) { while (iOffset < numBytes) {
uint32_t iFrameLen; uint32_t iFrameLen;
@ -235,8 +237,7 @@ inline bool MP4Reader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) {
break; break;
} }
memcpy(pBytes + iOffset, "\x0\x0\x0\x1", 4); memcpy(pBytes + iOffset, "\x0\x0\x0\x1", 4);
uint32_t dts = (double) _video_ms * iIdx / _video_num_samples; writeH264(pBytes + iOffset, iFrameLen + 4, dts, pts);
writeH264(pBytes + iOffset, iFrameLen + 4, dts, dts + pRenderingOffset / 90);
iOffset += (iFrameLen + 4); iOffset += (iFrameLen + 4);
} }
}else if(_bSyncSample){ }else if(_bSyncSample){
@ -260,9 +261,10 @@ inline bool MP4Reader::readAudioSample(int iTimeInc,bool justSeekSyncFrame) {
uint8_t *pBytes = _adts.buffer + 7; uint8_t *pBytes = _adts.buffer + 7;
if(MP4ReadSample(_hMP4File, _audio_trId, i + 1, &pBytes, &numBytes)){ if(MP4ReadSample(_hMP4File, _audio_trId, i + 1, &pBytes, &numBytes)){
if (!justSeekSyncFrame) { if (!justSeekSyncFrame) {
uint32_t dts = (double) _audio_ms * i / _audio_num_samples;
_adts.aac_frame_length = 7 + numBytes; _adts.aac_frame_length = 7 + numBytes;
writeAdtsHeader(_adts, _adts.buffer); writeAdtsHeader(_adts, _adts.buffer);
writeAAC(_adts.buffer, _adts.aac_frame_length, (double) _audio_ms * i / _audio_num_samples); writeAAC(_adts.buffer, _adts.aac_frame_length, dts);
} }
}else{ }else{
ErrorL << "读取音频失败:" << i+ 1; ErrorL << "读取音频失败:" << i+ 1;