ES-->PES包格式 打包

论坛 期权论坛 脚本     
匿名网站用户   2020-12-19 17:23   121   0



PES是打包过的ES,已经插入PTS和DTS,一般是一个pes包为一帧图像

PES包格式:

PES再打包成TS流或PS流,往往一个PES会分存到多个ts包中,

start_code: 0x00 00 01

PES 长: 为这个字节之后整个pes 长度--es 长度+剩余ps报头长

stream_id: --- video (1110xxxx) audio (110xxxxx) 所以打包的时候 h264 定义为0xE0 G711 音频定义为0xC0 其中后4位 xxxx 都为私有协议使用。

pes包头长: 整个pes 报头长字节 (不包括es长度)- 9;

信息区:包含附加信息以及PTS和DTS PTS ,DTS 都为5个字节的信息,所以pes 头一共长度为9+10 = 19 byte,至少是19个字节,后面可以自己进行扩展。

PS流:


每一个pes header包含pts和dts,在解码时,pes-->es,音视频的同步,除了使用pts和dts以外,还会用到SCR(system clock reference),在编码时,都是由STC(system time clock)生成

ps包长度是可变的

TS也是有多个pes组合而成,ts包由包头和包数据2部分组成,长度固定,包头长4bytes,包数据和自使用区共占184bytes


打包代码

typedef unsigned char BYTE;

typedef unsigned intUINT;
typedef unsigned long long UINT64;

// define the pes head PTS head for is little end type !!!!
static void setPTS(pPTS_tag t, UINT64 _ui64PTS, UINT64 _ui64DTS)
{
t->PTS1 = (_ui64PTS >> 30) & 0x07;
t->PTS21 = (_ui64PTS >> 22) & 0xFF;
t->PTS22 = (_ui64PTS >> 15) & 0x7F;
t->PTS31 = (_ui64PTS >> 7) & 0xFF;
t->PTS32 = _ui64PTS & 0x7F;


t->DTS1 = (_ui64DTS >> 30) & 0x07;
t->DTS21 = (_ui64DTS >> 22) & 0xFF;
t->DTS22 = (_ui64DTS >> 15) & 0x7F;
t->DTS31 = (_ui64DTS >> 7) & 0xFF;
t->DTS32 = _ui64DTS & 0x7F;
}

//size = 10 for PTS DTS info
typedef struct PTS_tag
{
BYTE marker_bit:1;
BYTE PTS1:3;
BYTE fix_bit:4;

BYTE PTS21;

BYTE marker_bit1:1;
BYTE PTS22:7;

BYTE PTS31;

BYTE marker_bit2:1;
BYTE PTS32:7;

/////////////////
BYTE marker_bit3:1;
BYTE DTS1:3;
BYTE fix_bit2:4;

BYTE DTS21;

BYTE marker_bit4:1;
BYTE DTS22:7;

BYTE DTS31;

BYTE marker_bit5:1;
BYTE DTS32:7;
} __attribute__ ((packed)) *pPTS_tag;

typedef struct PES_HEADER_tag//size =9
{
BYTE packet_start_code_prefix[3];
BYTE stream_id;
BYTE PES_packet_length[2];

BYTE original_or_copy:1;
BYTE copyright:1;
BYTE data_alignment_indicator:1;
BYTE PES_priority:1;
BYTE PES_scrambling_control:2;
BYTE fix_bit:2;

BYTE PES_extension_flag:1;
BYTE PES_CRC_flag:1;
BYTE additional_copy_info_flag:1;
BYTE DSM_trick_mode_flag:1;
BYTE ES_rate_flag:1;
BYTE ESCR_flag:1;
BYTE PTS_DTS_flags:2;

BYTE PES_header_data_length;
} __attribute__ ((packed)) *pPES_HEADER_tag;

int make_pes_head(BYTE *_pHeader,UINT _iDataLen,UINT _iFrameIndex,UINT _iFrameRate,int stream_id)

{

PES_HEADER_tag ePESHeader;


ePESHeader.packet_start_code_prefix[0] = 0x00;
ePESHeader.packet_start_code_prefix[1] = 0x00;
ePESHeader.packet_start_code_prefix[2] = 0x01;
ePESHeader.stream_id = stream_id;//标志是视频还是音频


ePESHeader.PES_packet_length[0] = (_iDataLen+13) >> 8;
ePESHeader.PES_packet_length[1] = (_iDataLen+13) & 0xFF;


ePESHeader.PES_scrambling_control = 0;
ePESHeader.PES_priority = 0;
ePESHeader.data_alignment_indicator = 1;
ePESHeader.copyright = 0;
ePESHeader.original_or_copy = 0;
ePESHeader.PTS_DTS_flags = 3;
ePESHeader.ESCR_flag = 0;
ePESHeader.ES_rate_flag = 0;
ePESHeader.DSM_trick_mode_flag = 0;
ePESHeader.additional_copy_info_flag = 0;
ePESHeader.PES_CRC_flag = 0;
ePESHeader.PES_extension_flag = 0;
ePESHeader.PES_header_data_length = 10;

memcpy(_pHeader,&ePESHeader,sizeof(PES_HEADER_tag));


PTS_tag ePTS;
float fInterval = 0;
UINT64 ui64SCR = 0;
fInterval = 90000.0/_iFrameRate;//33.3333333333;
ui64SCR = fInterval * _iFrameIndex;
//填写PTS,DTS
ePTS.setPTS(ui64SCR+3600,ui64SCR);


memcpy(_pHeader + sizeof(PES_HEADER_tag),&ePTS,sizeof(PTS_tag));
int size = sizeof(PES_HEADER_tag);
size +=sizeof(PTS_tag);


return sizeof(PES_HEADER_tag)+sizeof(PTS_tag);//19字节
}


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP