支持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 {
return aac_frame_length;
}
uint32_t stamp() const override {
uint32_t dts() const override {
return timeStamp;
}
uint32_t prefixSize() const override{

View File

@ -82,9 +82,28 @@ public:
typedef std::shared_ptr<Frame> 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();
}
/**
* 2640x00 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{

View File

@ -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{

View File

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

View File

@ -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头";
}

View File

@ -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,

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->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<char *>(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;

View File

@ -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);
};