修复rtmp增长时间戳相关bug

This commit is contained in:
xiongziliang 2020-08-01 10:20:27 +08:00
parent fdbed9e83b
commit b4a3b608ab
2 changed files with 46 additions and 50 deletions

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* *
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit). * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
@ -130,8 +130,6 @@ public:
uint8_t typeId; uint8_t typeId;
uint32_t bodySize = 0; uint32_t bodySize = 0;
uint32_t timeStamp = 0; uint32_t timeStamp = 0;
bool hasAbsStamp = false;
bool hasExtStamp = false;
uint32_t deltaStamp = 0; uint32_t deltaStamp = 0;
uint32_t streamId; uint32_t streamId;
uint32_t chunkId; uint32_t chunkId;
@ -153,8 +151,6 @@ public:
typeId = that.typeId; typeId = that.typeId;
bodySize = that.bodySize; bodySize = that.bodySize;
timeStamp = that.timeStamp; timeStamp = that.timeStamp;
hasAbsStamp = that.hasAbsStamp;
hasExtStamp = that.hasExtStamp;
deltaStamp = that.deltaStamp; deltaStamp = that.deltaStamp;
streamId = that.streamId; streamId = that.streamId;
chunkId = that.chunkId; chunkId = that.chunkId;

View File

@ -514,35 +514,35 @@ void RtmpProtocol::handle_rtmp() {
while (!_strRcvBuf.empty()) { while (!_strRcvBuf.empty()) {
uint8_t flags = _strRcvBuf[0]; uint8_t flags = _strRcvBuf[0];
int iOffset = 0; int iOffset = 0;
static const size_t HEADER_LENGTH[] = { 12, 8, 4, 1 }; static const size_t HEADER_LENGTH[] = {12, 8, 4, 1};
size_t iHeaderLen = HEADER_LENGTH[flags >> 6]; size_t iHeaderLen = HEADER_LENGTH[flags >> 6];
_iNowChunkID = flags & 0x3f; _iNowChunkID = flags & 0x3f;
switch (_iNowChunkID) { switch (_iNowChunkID) {
case 0: { case 0: {
//0 值表示二字节形式,并且 ID 范围 64 - 319 //0 值表示二字节形式,并且 ID 范围 64 - 319
//(第二个字节 + 64)。 //(第二个字节 + 64)。
if (_strRcvBuf.size() < 2) { if (_strRcvBuf.size() < 2) {
//need more data //need more data
return; return;
}
_iNowChunkID = 64 + (uint8_t) (_strRcvBuf[1]);
iOffset = 1;
} }
_iNowChunkID = 64 + (uint8_t) (_strRcvBuf[1]); break;
iOffset = 1; case 1: {
} //1 值表示三字节形式,并且 ID 范围为 64 - 65599
break; //((第三个字节) * 256 + 第二个字节 + 64)。
case 1: { if (_strRcvBuf.size() < 3) {
//1 值表示三字节形式,并且 ID 范围为 64 - 65599 //need more data
//((第三个字节) * 256 + 第二个字节 + 64)。 return;
if (_strRcvBuf.size() < 3) { }
//need more data _iNowChunkID = 64 + ((uint8_t) (_strRcvBuf[2]) << 8) + (uint8_t) (_strRcvBuf[1]);
return; iOffset = 2;
} }
_iNowChunkID = 64 + ((uint8_t) (_strRcvBuf[2]) << 8) + (uint8_t) (_strRcvBuf[1]); break;
iOffset = 2; default:
} //带有 2 值的块流 ID 被保留,用于下层协议控制消息和命令。
break; break;
default:
//带有 2 值的块流 ID 被保留,用于下层协议控制消息和命令。
break;
} }
if (_strRcvBuf.size() < iHeaderLen + iOffset) { if (_strRcvBuf.size() < iHeaderLen + iOffset) {
@ -553,18 +553,16 @@ void RtmpProtocol::handle_rtmp() {
auto &chunkData = _mapChunkData[_iNowChunkID]; auto &chunkData = _mapChunkData[_iNowChunkID];
chunkData.chunkId = _iNowChunkID; chunkData.chunkId = _iNowChunkID;
switch (iHeaderLen) { switch (iHeaderLen) {
case 12: case 12:
chunkData.hasAbsStamp = true; chunkData.streamId = load_le32(header.streamId);
chunkData.streamId = load_le32(header.streamId); case 8:
case 8: chunkData.bodySize = load_be24(header.bodySize);
chunkData.bodySize = load_be24(header.bodySize); chunkData.typeId = header.typeId;
chunkData.typeId = header.typeId; case 4:
case 4: chunkData.deltaStamp = load_be24(header.timeStamp);
chunkData.deltaStamp = load_be24(header.timeStamp);
chunkData.hasExtStamp = chunkData.deltaStamp == 0xFFFFFF;
} }
if (chunkData.hasExtStamp) { if (chunkData.deltaStamp == 0xFFFFFF) {
if (_strRcvBuf.size() < iHeaderLen + iOffset + 4) { if (_strRcvBuf.size() < iHeaderLen + iOffset + 4) {
//need more data //need more data
return; return;
@ -572,32 +570,34 @@ void RtmpProtocol::handle_rtmp() {
chunkData.deltaStamp = load_be32(_strRcvBuf.data() + iOffset + iHeaderLen); chunkData.deltaStamp = load_be32(_strRcvBuf.data() + iOffset + iHeaderLen);
iOffset += 4; iOffset += 4;
} }
if (chunkData.bodySize < chunkData.strBuf.size()) { if (chunkData.bodySize < chunkData.strBuf.size()) {
throw std::runtime_error("非法的bodySize"); throw std::runtime_error("非法的bodySize");
} }
auto iMore = min(_iChunkLenIn, chunkData.bodySize - chunkData.strBuf.size()); auto iMore = min(_iChunkLenIn, chunkData.bodySize - chunkData.strBuf.size());
if (_strRcvBuf.size() < iHeaderLen + iOffset + iMore) { if (_strRcvBuf.size() < iHeaderLen + iOffset + iMore) {
//need more data //need more data
return; return;
} }
if (iHeaderLen == 12) {
//绝对时间戳
chunkData.timeStamp = chunkData.deltaStamp;
} else {
//时间戳增量
chunkData.timeStamp += chunkData.deltaStamp;
}
chunkData.strBuf.append(_strRcvBuf, iHeaderLen + iOffset, iMore); chunkData.strBuf.append(_strRcvBuf, iHeaderLen + iOffset, iMore);
_strRcvBuf.erase(0, iHeaderLen + iOffset + iMore); _strRcvBuf.erase(0, iHeaderLen + iOffset + iMore);
if (chunkData.strBuf.size() == chunkData.bodySize) { if (chunkData.strBuf.size() == chunkData.bodySize) {
//frame is ready //frame is ready
_iNowStreamID = chunkData.streamId; _iNowStreamID = chunkData.streamId;
chunkData.timeStamp = chunkData.deltaStamp + (chunkData.hasAbsStamp ? 0 : chunkData.timeStamp); if (chunkData.bodySize) {
if(chunkData.bodySize){
handle_rtmpChunk(chunkData); handle_rtmpChunk(chunkData);
} }
chunkData.strBuf.clear(); chunkData.strBuf.clear();
chunkData.hasAbsStamp = false;
chunkData.hasExtStamp = false;
chunkData.deltaStamp = 0;
} }
} }
} }