diff --git a/src/Extension/AAC.h b/src/Extension/AAC.h index 516bcbf8..69f7621e 100644 --- a/src/Extension/AAC.h +++ b/src/Extension/AAC.h @@ -63,7 +63,7 @@ public: uint32_t size() const override { return aac_frame_length; } - uint32_t stamp() const override { + uint32_t dts() const override { return timeStamp; } uint32_t prefixSize() const override{ diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index 18dff05d..d19b30f1 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -82,9 +82,28 @@ public: typedef std::shared_ptr Ptr; virtual ~Frame(){} /** - * 时间戳 + * 时间戳,已经废弃,请使用dts() 、pts()接口 */ - virtual uint32_t stamp() const = 0; + inline uint32_t stamp() const { + return dts(); + }; + + + /** + * 返回解码时间戳,单位毫秒 + * @return + */ + virtual uint32_t dts() const = 0; + + + + /** + * 返回显示时间戳,单位毫秒 + * @return + */ + virtual uint32_t pts() const { + return dts(); + } /** * 前缀长度,譬如264前缀为0x00 00 00 01,那么前缀长度就是4 @@ -271,7 +290,7 @@ public: uint32_t size() const override { return buffer_size; } - uint32_t stamp() const override { + uint32_t dts() const override { return timeStamp; } uint32_t prefixSize() const override{ diff --git a/src/Extension/H264.h b/src/Extension/H264.h index 09960787..a71e4f49 100644 --- a/src/Extension/H264.h +++ b/src/Extension/H264.h @@ -59,7 +59,7 @@ public: uint32_t size() const override { return buffer.size(); } - uint32_t stamp() const override { + uint32_t dts() const override { return timeStamp; } uint32_t prefixSize() const override{ diff --git a/src/Extension/H265.h b/src/Extension/H265.h index 7b44fc0a..0eb94390 100644 --- a/src/Extension/H265.h +++ b/src/Extension/H265.h @@ -78,7 +78,7 @@ public: return buffer.size(); } - uint32_t stamp() const override { + uint32_t dts() const override { return timeStamp; } diff --git a/src/MediaFile/HLSMaker.cpp b/src/MediaFile/HLSMaker.cpp index 39461a15..83c37bf5 100644 --- a/src/MediaFile/HLSMaker.cpp +++ b/src/MediaFile/HLSMaker.cpp @@ -132,17 +132,18 @@ bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, i return true; } -void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp) { +void HLSMaker::inputH264(const Frame::Ptr &frame) { + auto dts = frame->dts(); if(_ui32LastStamp == 0){ - _ui32LastStamp = timeStamp; + _ui32LastStamp = dts; } - int stampInc = timeStamp - _ui32LastStamp; - auto type = H264_TYPE(((uint8_t*)data)[4]); + int stampInc = dts - _ui32LastStamp; + auto type = H264_TYPE(((uint8_t*)(frame->data() + frame->prefixSize()))[0]); switch (type) { case H264Frame::NAL_SPS: //SPS if (stampInc >= _ui32SegmentDuration * 1000) { - _ui32LastStamp = timeStamp; + _ui32LastStamp = dts; //关闭文件 _ts.clear(); auto strTmpFileName = StrPrinter << _strOutputPrefix << '-' << (++_ui64TsCnt) << ".ts" << endl; @@ -160,22 +161,22 @@ void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp) { } case H264Frame::NAL_B_P: //P //insert aud frame before p and SPS frame - if(timeStamp != _ui32LastFrameStamp){ - _ts.inputH264("\x0\x0\x0\x1\x9\xf0", 6, timeStamp * 90); + if(dts != _ui32LastFrameStamp){ + _ts.inputH264("\x0\x0\x0\x1\x9\xf0", 6, dts * 90L , frame->pts() * 90L); } case H264Frame::NAL_IDR: //IDR case H264Frame::NAL_PPS: //PPS - _ts.inputH264((char *) data, length, timeStamp * 90); + _ts.inputH264(frame->data(), frame->size(), dts * 90L , frame->pts() * 90L); break; default: break; } - _ui32LastFrameStamp = timeStamp; + _ui32LastFrameStamp = dts; } -void HLSMaker::inputAAC(void *data, uint32_t length, uint32_t timeStamp) { - _ts.inputAAC((char *) data, length, timeStamp * 90); +void HLSMaker::inputAAC(const Frame::Ptr &frame) { + _ts.inputAAC(frame->data(), frame->size(), frame->dts() * 90L , frame->pts() * 90L); } bool HLSMaker::removets() { @@ -192,7 +193,7 @@ void HLSMaker::onTrackFrame(const Frame::Ptr &frame) { switch (frame->getCodecId()){ case CodecH264:{ if( frame->prefixSize() != 0){ - inputH264(frame->data(), frame->size(),frame->stamp()); + inputH264(frame); }else{ WarnL << "h264必须要有头4个或3个字节的前缀"; } @@ -200,7 +201,7 @@ void HLSMaker::onTrackFrame(const Frame::Ptr &frame) { break; case CodecAAC:{ if( frame->prefixSize() == 7) { - inputAAC(frame->data(), frame->size(), frame->stamp()); + inputAAC(frame); }else{ WarnL << "adts必须要有头7个字节的adts头"; } diff --git a/src/MediaFile/HLSMaker.h b/src/MediaFile/HLSMaker.h index 3cb6a9c9..c07d70d9 100644 --- a/src/MediaFile/HLSMaker.h +++ b/src/MediaFile/HLSMaker.h @@ -35,6 +35,8 @@ #include "Util/logger.h" #include "Common/config.h" #include "Common/MediaSink.h" +#include "Extension/Frame.h" + using namespace toolkit; namespace mediakit { @@ -55,15 +57,8 @@ protected: */ void onTrackFrame(const Frame::Ptr &frame) override ; private: - //时间戳:参考频率1000 - void inputH264(void *pData, - uint32_t ui32Length, - uint32_t ui32TimeStamp); - - //时间戳:参考频率1000 - void inputAAC(void *pData, - uint32_t ui32Length, - uint32_t ui32TimeStamp); + void inputH264(const Frame::Ptr &frame); + void inputAAC(const Frame::Ptr &frame); bool write_index_file(int iFirstSegment, unsigned int uiLastSegment, diff --git a/src/MediaFile/TSMaker.cpp b/src/MediaFile/TSMaker.cpp index 9c8538f0..52ea0ae4 100644 --- a/src/MediaFile/TSMaker.cpp +++ b/src/MediaFile/TSMaker.cpp @@ -278,7 +278,7 @@ void TSMaker::TsHeader2buffer(TsPacketHeader* pTsHeader, unsigned char* pucBuffe } -void TSMaker::WriteAdaptive_flags_Head( Ts_Adaptation_field * pTsAdaptationField, uint64_t ui64VideoPts) { +void TSMaker::WriteAdaptive_flags_Head( Ts_Adaptation_field * pTsAdaptationField, uint64_t ui64VideoDts) { //填写自适应段 pTsAdaptationField->discontinuty_indicator = 0; pTsAdaptationField->random_access_indicator = 0; @@ -290,7 +290,7 @@ void TSMaker::WriteAdaptive_flags_Head( Ts_Adaptation_field * pTsAdaptationField pTsAdaptationField->adaptation_field_extension_flag = 0; //需要自己算 - pTsAdaptationField->pcr = ui64VideoPts * 300; + pTsAdaptationField->pcr = ui64VideoDts * 300; pTsAdaptationField->adaptation_field_length = 7; //占用7位 pTsAdaptationField->opcr = 0; @@ -298,14 +298,14 @@ void TSMaker::WriteAdaptive_flags_Head( Ts_Adaptation_field * pTsAdaptationField pTsAdaptationField->private_data_len = 0; } -int TSMaker::inputH264(const char* pcData, uint32_t ui32Len, uint64_t ui64Time) { +int TSMaker::inputH264(const char* pcData, uint32_t ui32Len, uint64_t ui64Dts , uint64_t ui64Pts) { if (m_pOutVideoTs == NULL) { return false; } m_pVideo_pes->ES = const_cast(pcData); m_pVideo_pes->ESlen = ui32Len; Ts_Adaptation_field ts_adaptation_field_Head; - WriteAdaptive_flags_Head(&ts_adaptation_field_Head, ui64Time); //填写自适应段标志帧头 + WriteAdaptive_flags_Head(&ts_adaptation_field_Head, ui64Dts); //填写自适应段标志帧头 m_pVideo_pes->packet_start_code_prefix = 0x000001; m_pVideo_pes->stream_id = TS_H264_STREAM_ID; //E0~EF表示是视频的,C0~DF是音频,H264-- E0 m_pVideo_pes->marker_bit = 0x02; @@ -322,12 +322,12 @@ int TSMaker::inputH264(const char* pcData, uint32_t ui32Len, uint64_t ui64Time) m_pVideo_pes->PES_CRC_flag = 0x00; m_pVideo_pes->PES_extension_flag = 0x00; m_pVideo_pes->PES_header_data_length = 0x0A; //后面的数据包括了PTS和 DTS所占的字节数 - PES2TS(m_pVideo_pes, TS_H264_PID, &ts_adaptation_field_Head, ui64Time); + PES2TS(m_pVideo_pes, TS_H264_PID, &ts_adaptation_field_Head, ui64Dts , ui64Pts); m_pVideo_pes->ESlen = 0; return ui32Len; } -int TSMaker::inputAAC(const char* pcData, uint32_t ui32Len, uint64_t ui64Pts) { +int TSMaker::inputAAC(const char* pcData, uint32_t ui32Len, uint64_t ui64Dts , uint64_t ui64Pts) { if (m_pOutVideoTs == NULL) { return 0; } @@ -351,7 +351,7 @@ int TSMaker::inputAAC(const char* pcData, uint32_t ui32Len, uint64_t ui64Pts) { m_pAudio_pes->PES_CRC_flag = 0x00; m_pAudio_pes->PES_extension_flag = 0x00; m_pAudio_pes->PES_header_data_length = 0x0A; //后面的数据包括了PTS - PES2TS(m_pAudio_pes, TS_AAC_PID, &ts_adaptation_field_Head, ui64Pts); + PES2TS(m_pAudio_pes, TS_AAC_PID, &ts_adaptation_field_Head,ui64Dts,ui64Pts); m_pAudio_pes->ESlen = 0; return ui32Len; } @@ -468,7 +468,7 @@ void TSMaker::CreateAdaptive_Ts(Ts_Adaptation_field * pTsAdaptationField, unsign } return; } -void TSMaker::PES2TS(TsPes * pTsPes, unsigned int uiPID, Ts_Adaptation_field * pTsAdaptationFieldHead, uint64_t ui64Dts) { +void TSMaker::PES2TS(TsPes * pTsPes, unsigned int uiPID, Ts_Adaptation_field * pTsAdaptationFieldHead, uint64_t ui64Dts ,uint64_t ui64Pts) { TsPacketHeader ts_header; unsigned int uiAdaptiveLength = 0; //要填写0XFF的长度 unsigned int uiFirstPacketLoadLength = 188 - 4 - 1 - pTsAdaptationFieldHead->adaptation_field_length - 19; //分片包的第一个包的负载长度 @@ -529,18 +529,18 @@ void TSMaker::PES2TS(TsPes * pTsPes, unsigned int uiPID, Ts_Adaptation_field * p | pTsPes->PES_CRC_flag << 1 | pTsPes->PES_extension_flag; pucTSBuf += 8; switch (pTsPes->PTS_DTS_flags) { - case 0x03: //both pts and ui64Dts + case 0x03: //both pts and dts pucTSBuf[6] = (((0x1 << 4) | ((ui64Dts >> 29) & 0x0E) | 0x01) & 0xff); pucTSBuf[7] = (((((ui64Dts >> 14) & 0xfffe) | 0x01) >> 8) & 0xff); pucTSBuf[8] = ((((ui64Dts >> 14) & 0xfffe) | 0x01) & 0xff); pucTSBuf[9] = ((((ui64Dts << 1) & 0xfffe) | 0x01) >> 8) & 0xff; pucTSBuf[10] = (((ui64Dts << 1) & 0xfffe) | 0x01) & 0xff; case 0x02: //pts only - pucTSBuf[1] = (((0x3 << 4) | ((ui64Dts >> 29) & 0x0E) | 0x01) & 0xff); - pucTSBuf[2] = (((((ui64Dts >> 14) & 0xfffe) | 0x01) >> 8) & 0xff); - pucTSBuf[3] = ((((ui64Dts >> 14) & 0xfffe) | 0x01) & 0xff); - pucTSBuf[4] = (((((ui64Dts << 1) & 0xfffe) | 0x01) >> 8) & 0xff); - pucTSBuf[5] = ((((ui64Dts << 1) & 0xfffe) | 0x01) & 0xff); + pucTSBuf[1] = (((0x3 << 4) | ((ui64Pts >> 29) & 0x0E) | 0x01) & 0xff); + pucTSBuf[2] = (((((ui64Pts >> 14) & 0xfffe) | 0x01) >> 8) & 0xff); + pucTSBuf[3] = ((((ui64Pts >> 14) & 0xfffe) | 0x01) & 0xff); + pucTSBuf[4] = (((((ui64Pts << 1) & 0xfffe) | 0x01) >> 8) & 0xff); + pucTSBuf[5] = ((((ui64Pts << 1) & 0xfffe) | 0x01) & 0xff); break; default: break; diff --git a/src/MediaFile/TSMaker.h b/src/MediaFile/TSMaker.h index fd420e78..20de570e 100644 --- a/src/MediaFile/TSMaker.h +++ b/src/MediaFile/TSMaker.h @@ -239,8 +239,8 @@ public: TSMaker(); virtual ~TSMaker(); bool init(const string &strFilename, uint32_t ui32BufSize); - int inputH264(const char *pcData, uint32_t ui32Len, uint64_t ui64Time); - int inputAAC(const char *pcData, uint32_t ui32Len, uint64_t ui64Time); + int inputH264(const char *pcData, uint32_t ui32Len, uint64_t ui64Dts , uint64_t ui64Pts); + int inputAAC(const char *pcData, uint32_t ui32Len, uint64_t ui64Dts , uint64_t ui64Pts); void clear(); private: string m_strFilename; @@ -260,7 +260,7 @@ private: void WriteAdaptive_flags_Head(Ts_Adaptation_field * pAdaptationField, uint64_t ui64VideoPts); void WriteAdaptive_flags_Tail(Ts_Adaptation_field * pAdaptationField); //填写自适应段标志帧尾的 - void PES2TS(TsPes * pPes, unsigned int uiPID, Ts_Adaptation_field * pAdaptationField, uint64_t ui64Pts); + void PES2TS(TsPes * pPes, unsigned int uiPID, Ts_Adaptation_field * pAdaptationField, uint64_t ui64Dts ,uint64_t ui64Pts ); void CreateAdaptive_Ts(Ts_Adaptation_field * pAdaptationField, unsigned char * pcTs, unsigned int uiAdaptiveLength); };