支持pts/dts

This commit is contained in:
xiongziliang 2018-11-17 17:26:38 +08:00
parent 68da7c2fb7
commit a12ed95aa4
8 changed files with 60 additions and 45 deletions

View File

@ -63,7 +63,7 @@ public:
uint32_t size() const override { uint32_t size() const override {
return aac_frame_length; return aac_frame_length;
} }
uint32_t stamp() const override { uint32_t dts() const override {
return timeStamp; return timeStamp;
} }
uint32_t prefixSize() const override{ uint32_t prefixSize() const override{

View File

@ -82,9 +82,28 @@ public:
typedef std::shared_ptr<Frame> Ptr; typedef std::shared_ptr<Frame> Ptr;
virtual ~Frame(){} 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();
}
/** /**
* 2640x00 00 00 01,4 * 2640x00 00 00 01,4
@ -271,7 +290,7 @@ public:
uint32_t size() const override { uint32_t size() const override {
return buffer_size; return buffer_size;
} }
uint32_t stamp() const override { uint32_t dts() const override {
return timeStamp; return timeStamp;
} }
uint32_t prefixSize() const override{ uint32_t prefixSize() const override{

View File

@ -59,7 +59,7 @@ public:
uint32_t size() const override { uint32_t size() const override {
return buffer.size(); return buffer.size();
} }
uint32_t stamp() const override { uint32_t dts() const override {
return timeStamp; return timeStamp;
} }
uint32_t prefixSize() const override{ uint32_t prefixSize() const override{

View File

@ -78,7 +78,7 @@ public:
return buffer.size(); return buffer.size();
} }
uint32_t stamp() const override { uint32_t dts() const override {
return timeStamp; return timeStamp;
} }

View File

@ -132,17 +132,18 @@ bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, i
return true; 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){ if(_ui32LastStamp == 0){
_ui32LastStamp = timeStamp; _ui32LastStamp = dts;
} }
int stampInc = timeStamp - _ui32LastStamp; int stampInc = dts - _ui32LastStamp;
auto type = H264_TYPE(((uint8_t*)data)[4]); auto type = H264_TYPE(((uint8_t*)(frame->data() + frame->prefixSize()))[0]);
switch (type) { switch (type) {
case H264Frame::NAL_SPS: //SPS case H264Frame::NAL_SPS: //SPS
if (stampInc >= _ui32SegmentDuration * 1000) { if (stampInc >= _ui32SegmentDuration * 1000) {
_ui32LastStamp = timeStamp; _ui32LastStamp = dts;
//关闭文件 //关闭文件
_ts.clear(); _ts.clear();
auto strTmpFileName = StrPrinter << _strOutputPrefix << '-' << (++_ui64TsCnt) << ".ts" << endl; 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 case H264Frame::NAL_B_P: //P
//insert aud frame before p and SPS frame //insert aud frame before p and SPS frame
if(timeStamp != _ui32LastFrameStamp){ if(dts != _ui32LastFrameStamp){
_ts.inputH264("\x0\x0\x0\x1\x9\xf0", 6, timeStamp * 90); _ts.inputH264("\x0\x0\x0\x1\x9\xf0", 6, dts * 90L , frame->pts() * 90L);
} }
case H264Frame::NAL_IDR: //IDR case H264Frame::NAL_IDR: //IDR
case H264Frame::NAL_PPS: //PPS case H264Frame::NAL_PPS: //PPS
_ts.inputH264((char *) data, length, timeStamp * 90); _ts.inputH264(frame->data(), frame->size(), dts * 90L , frame->pts() * 90L);
break; break;
default: default:
break; break;
} }
_ui32LastFrameStamp = timeStamp; _ui32LastFrameStamp = dts;
} }
void HLSMaker::inputAAC(void *data, uint32_t length, uint32_t timeStamp) { void HLSMaker::inputAAC(const Frame::Ptr &frame) {
_ts.inputAAC((char *) data, length, timeStamp * 90); _ts.inputAAC(frame->data(), frame->size(), frame->dts() * 90L , frame->pts() * 90L);
} }
bool HLSMaker::removets() { bool HLSMaker::removets() {
@ -192,7 +193,7 @@ void HLSMaker::onTrackFrame(const Frame::Ptr &frame) {
switch (frame->getCodecId()){ switch (frame->getCodecId()){
case CodecH264:{ case CodecH264:{
if( frame->prefixSize() != 0){ if( frame->prefixSize() != 0){
inputH264(frame->data(), frame->size(),frame->stamp()); inputH264(frame);
}else{ }else{
WarnL << "h264必须要有头4个或3个字节的前缀"; WarnL << "h264必须要有头4个或3个字节的前缀";
} }
@ -200,7 +201,7 @@ void HLSMaker::onTrackFrame(const Frame::Ptr &frame) {
break; break;
case CodecAAC:{ case CodecAAC:{
if( frame->prefixSize() == 7) { if( frame->prefixSize() == 7) {
inputAAC(frame->data(), frame->size(), frame->stamp()); inputAAC(frame);
}else{ }else{
WarnL << "adts必须要有头7个字节的adts头"; WarnL << "adts必须要有头7个字节的adts头";
} }

View File

@ -35,6 +35,8 @@
#include "Util/logger.h" #include "Util/logger.h"
#include "Common/config.h" #include "Common/config.h"
#include "Common/MediaSink.h" #include "Common/MediaSink.h"
#include "Extension/Frame.h"
using namespace toolkit; using namespace toolkit;
namespace mediakit { namespace mediakit {
@ -55,15 +57,8 @@ protected:
*/ */
void onTrackFrame(const Frame::Ptr &frame) override ; void onTrackFrame(const Frame::Ptr &frame) override ;
private: private:
//时间戳参考频率1000 void inputH264(const Frame::Ptr &frame);
void inputH264(void *pData, void inputAAC(const Frame::Ptr &frame);
uint32_t ui32Length,
uint32_t ui32TimeStamp);
//时间戳参考频率1000
void inputAAC(void *pData,
uint32_t ui32Length,
uint32_t ui32TimeStamp);
bool write_index_file(int iFirstSegment, bool write_index_file(int iFirstSegment,
unsigned int uiLastSegment, unsigned int uiLastSegment,

View File

@ -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->discontinuty_indicator = 0;
pTsAdaptationField->random_access_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->adaptation_field_extension_flag = 0;
//需要自己算 //需要自己算
pTsAdaptationField->pcr = ui64VideoPts * 300; pTsAdaptationField->pcr = ui64VideoDts * 300;
pTsAdaptationField->adaptation_field_length = 7; //占用7位 pTsAdaptationField->adaptation_field_length = 7; //占用7位
pTsAdaptationField->opcr = 0; pTsAdaptationField->opcr = 0;
@ -298,14 +298,14 @@ void TSMaker::WriteAdaptive_flags_Head( Ts_Adaptation_field * pTsAdaptationField
pTsAdaptationField->private_data_len = 0; 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) { if (m_pOutVideoTs == NULL) {
return false; return false;
} }
m_pVideo_pes->ES = const_cast<char *>(pcData); m_pVideo_pes->ES = const_cast<char *>(pcData);
m_pVideo_pes->ESlen = ui32Len; m_pVideo_pes->ESlen = ui32Len;
Ts_Adaptation_field ts_adaptation_field_Head; 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->packet_start_code_prefix = 0x000001;
m_pVideo_pes->stream_id = TS_H264_STREAM_ID; //E0~EF表示是视频的,C0~DF是音频,H264-- E0 m_pVideo_pes->stream_id = TS_H264_STREAM_ID; //E0~EF表示是视频的,C0~DF是音频,H264-- E0
m_pVideo_pes->marker_bit = 0x02; 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_CRC_flag = 0x00;
m_pVideo_pes->PES_extension_flag = 0x00; m_pVideo_pes->PES_extension_flag = 0x00;
m_pVideo_pes->PES_header_data_length = 0x0A; //后面的数据包括了PTS和 DTS所占的字节数 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; m_pVideo_pes->ESlen = 0;
return ui32Len; 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) { if (m_pOutVideoTs == NULL) {
return 0; 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_CRC_flag = 0x00;
m_pAudio_pes->PES_extension_flag = 0x00; m_pAudio_pes->PES_extension_flag = 0x00;
m_pAudio_pes->PES_header_data_length = 0x0A; //后面的数据包括了PTS 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; m_pAudio_pes->ESlen = 0;
return ui32Len; return ui32Len;
} }
@ -468,7 +468,7 @@ void TSMaker::CreateAdaptive_Ts(Ts_Adaptation_field * pTsAdaptationField, unsign
} }
return; 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; TsPacketHeader ts_header;
unsigned int uiAdaptiveLength = 0; //要填写0XFF的长度 unsigned int uiAdaptiveLength = 0; //要填写0XFF的长度
unsigned int uiFirstPacketLoadLength = 188 - 4 - 1 - pTsAdaptationFieldHead->adaptation_field_length - 19; //分片包的第一个包的负载长度 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; | pTsPes->PES_CRC_flag << 1 | pTsPes->PES_extension_flag;
pucTSBuf += 8; pucTSBuf += 8;
switch (pTsPes->PTS_DTS_flags) { 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[6] = (((0x1 << 4) | ((ui64Dts >> 29) & 0x0E) | 0x01) & 0xff);
pucTSBuf[7] = (((((ui64Dts >> 14) & 0xfffe) | 0x01) >> 8) & 0xff); pucTSBuf[7] = (((((ui64Dts >> 14) & 0xfffe) | 0x01) >> 8) & 0xff);
pucTSBuf[8] = ((((ui64Dts >> 14) & 0xfffe) | 0x01) & 0xff); pucTSBuf[8] = ((((ui64Dts >> 14) & 0xfffe) | 0x01) & 0xff);
pucTSBuf[9] = ((((ui64Dts << 1) & 0xfffe) | 0x01) >> 8) & 0xff; pucTSBuf[9] = ((((ui64Dts << 1) & 0xfffe) | 0x01) >> 8) & 0xff;
pucTSBuf[10] = (((ui64Dts << 1) & 0xfffe) | 0x01) & 0xff; pucTSBuf[10] = (((ui64Dts << 1) & 0xfffe) | 0x01) & 0xff;
case 0x02: //pts only case 0x02: //pts only
pucTSBuf[1] = (((0x3 << 4) | ((ui64Dts >> 29) & 0x0E) | 0x01) & 0xff); pucTSBuf[1] = (((0x3 << 4) | ((ui64Pts >> 29) & 0x0E) | 0x01) & 0xff);
pucTSBuf[2] = (((((ui64Dts >> 14) & 0xfffe) | 0x01) >> 8) & 0xff); pucTSBuf[2] = (((((ui64Pts >> 14) & 0xfffe) | 0x01) >> 8) & 0xff);
pucTSBuf[3] = ((((ui64Dts >> 14) & 0xfffe) | 0x01) & 0xff); pucTSBuf[3] = ((((ui64Pts >> 14) & 0xfffe) | 0x01) & 0xff);
pucTSBuf[4] = (((((ui64Dts << 1) & 0xfffe) | 0x01) >> 8) & 0xff); pucTSBuf[4] = (((((ui64Pts << 1) & 0xfffe) | 0x01) >> 8) & 0xff);
pucTSBuf[5] = ((((ui64Dts << 1) & 0xfffe) | 0x01) & 0xff); pucTSBuf[5] = ((((ui64Pts << 1) & 0xfffe) | 0x01) & 0xff);
break; break;
default: default:
break; break;

View File

@ -239,8 +239,8 @@ public:
TSMaker(); TSMaker();
virtual ~TSMaker(); virtual ~TSMaker();
bool init(const string &strFilename, uint32_t ui32BufSize); bool init(const string &strFilename, uint32_t ui32BufSize);
int inputH264(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 ui64Time); int inputAAC(const char *pcData, uint32_t ui32Len, uint64_t ui64Dts , uint64_t ui64Pts);
void clear(); void clear();
private: private:
string m_strFilename; string m_strFilename;
@ -260,7 +260,7 @@ private:
void WriteAdaptive_flags_Head(Ts_Adaptation_field * pAdaptationField, uint64_t ui64VideoPts); void WriteAdaptive_flags_Head(Ts_Adaptation_field * pAdaptationField, uint64_t ui64VideoPts);
void WriteAdaptive_flags_Tail(Ts_Adaptation_field * pAdaptationField); //填写自适应段标志帧尾的 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); void CreateAdaptive_Ts(Ts_Adaptation_field * pAdaptationField, unsigned char * pcTs, unsigned int uiAdaptiveLength);
}; };