diff --git a/src/Extension/H264.h b/src/Extension/H264.h index a71e4f49..8c658f3e 100644 --- a/src/Extension/H264.h +++ b/src/Extension/H264.h @@ -62,6 +62,11 @@ public: uint32_t dts() const override { return timeStamp; } + + uint32_t pts() const override { + return ptsStamp ? ptsStamp : timeStamp; + } + uint32_t prefixSize() const override{ return iPrefixSize; } @@ -80,6 +85,7 @@ public: public: uint16_t sequence; uint32_t timeStamp; + uint32_t ptsStamp = 0; unsigned char type; string buffer; uint32_t iPrefixSize = 4; diff --git a/src/RtmpMuxer/H264RtmpCodec.cpp b/src/RtmpMuxer/H264RtmpCodec.cpp index 4e994afa..1c29d4dc 100644 --- a/src/RtmpMuxer/H264RtmpCodec.cpp +++ b/src/RtmpMuxer/H264RtmpCodec.cpp @@ -54,9 +54,13 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) { return false; } - if (_sps.size()) { + if (_sps.size() && pkt->strBuf.size() > 9) { uint32_t iTotalLen = pkt->strBuf.size(); uint32_t iOffset = 5; + uint8_t *cts_ptr = (uint8_t *) (pkt->strBuf.data() + 2); + int32_t cts = (((cts_ptr[0] << 16) | (cts_ptr[1] << 8) | (cts_ptr[2])) + 0xff800000) ^ 0xff800000; + auto pts = pkt->timeStamp + cts; + while(iOffset + 4 < iTotalLen){ uint32_t iFrameLen; memcpy(&iFrameLen, pkt->strBuf.data() + iOffset, 4); @@ -65,7 +69,7 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) { if(iFrameLen + iOffset > iTotalLen){ break; } - onGetH264_l(pkt->strBuf.data() + iOffset, iFrameLen, pkt->timeStamp); + onGetH264_l(pkt->strBuf.data() + iOffset, iFrameLen, pkt->timeStamp , pts); iOffset += iFrameLen; } } @@ -73,25 +77,26 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) { } -inline void H264RtmpDecoder::onGetH264_l(const char* pcData, int iLen, uint32_t ui32TimeStamp) { +inline void H264RtmpDecoder::onGetH264_l(const char* pcData, int iLen, uint32_t dts,uint32_t pts) { switch (H264_TYPE(pcData[0])) { case H264Frame::NAL_IDR: { //I frame - onGetH264(_sps.data(), _sps.length(), ui32TimeStamp); - onGetH264(_pps.data(), _pps.length(), ui32TimeStamp); + onGetH264(_sps.data(), _sps.length(), dts , pts); + onGetH264(_pps.data(), _pps.length(), dts , pts); } case H264Frame::NAL_B_P: { //I or P or B frame - onGetH264(pcData, iLen, ui32TimeStamp); + onGetH264(pcData, iLen, dts , pts); } break; default: break; } } -inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t ui32TimeStamp) { +inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dts,uint32_t pts) { _h264frame->type = H264_TYPE(pcData[0]); - _h264frame->timeStamp = ui32TimeStamp; + _h264frame->timeStamp = dts; + _h264frame->ptsStamp = pts; _h264frame->buffer.assign("\x0\x0\x0\x1", 4); //添加264头 _h264frame->buffer.append(pcData, iLen); @@ -167,7 +172,9 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) { _lastPacket->strBuf.clear(); _lastPacket->strBuf.push_back(flags); _lastPacket->strBuf.push_back(!is_config); - _lastPacket->strBuf.append("\x0\x0\x0", 3); + auto cts = frame->pts() - frame->dts(); + cts = htonl(cts); + _lastPacket->strBuf.append((char *)&cts + 1, 3); _lastPacket->chunkId = CHUNK_VIDEO; _lastPacket->streamId = STREAM_MEDIA; diff --git a/src/RtmpMuxer/H264RtmpCodec.h b/src/RtmpMuxer/H264RtmpCodec.h index 5d08081a..aee46d08 100644 --- a/src/RtmpMuxer/H264RtmpCodec.h +++ b/src/RtmpMuxer/H264RtmpCodec.h @@ -60,8 +60,8 @@ public: } protected: bool decodeRtmp(const RtmpPacket::Ptr &Rtmp); - void onGetH264_l(const char *pcData, int iLen, uint32_t ui32TimeStamp); - void onGetH264(const char *pcData, int iLen, uint32_t ui32TimeStamp); + void onGetH264_l(const char *pcData, int iLen, uint32_t dts,uint32_t pts); + void onGetH264(const char *pcData, int iLen, uint32_t dts,uint32_t pts); H264Frame::Ptr obtainFrame(); protected: H264Frame::Ptr _h264frame;