ps.h
5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <stdint.h>
#include <string>
#include <memory.h>
#define H264_ID 0x1b
#define H265_ID 0x24
#define MPEG_ID 0x10
#define SVACV_ID 0x80
#define G711_ID 0x90
#define SVACA_ID 0x9b
const uint8_t PS_HEAD[] = {
/*PS头*/
0x00, 0x00, 0x01, 0xba,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*时间戳*/
0x01, 0x47, 0xb3,
0xf8
};
const uint8_t SYS_MAP_HEAD[] = {
/*PS_SYS头*/
0x00, 0x00, 0x01, 0xbb,
0x00, 0x0c, /*sys头长度,不含自己,6+3*流的数目*/
0x80, 0xa3, 0xd9, /*速率*/
0x04, 0xe1, /*音频流数,视频流数加3个1标识*/
0xff, /**/
0xb9, 0xe0, 0x00, 0xb8, 0xc0, 0x40, /*流信息,b9视频,b8音频*/
/*PS_MAP头*/
0x00, 0x00, 0x01, 0xbc,
0x00, 0x12, /*psm长度*/
0xe1, 0xff, /**/
0x00, 0x00, 0x00, 0x08, /*固定2路流*/
0x1b, 0xe0, 0x00, 0x00, /*视频,第一个字节(0x1b), 跟具不同的视频编码改变即可封装不同的流,见开头宏定义*/
0x90, 0xc0, 0x00, 0x00, /*音频,同视频*/
0x00, 0x00, 0x00, 0x00 /*4b CRC,暂时没设置*/
};
const uint8_t PES_HEAD[] = {
/*PS_PES头*/
0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, /*pes长度*/
0x80, 0xc0, /*附加信息*/
0x0a, /*附加信息长度*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*pts和pds*/
};
void SetHeaderTimeStamp(uint8_t *dest, uint64_t pts)
{
uint8_t *scr_buf = dest + 4;
scr_buf[0] = 0x40 | (((uint8_t)(pts >> 30) & 0x07) << 3) | 0x04 | ((uint8_t)(pts >> 28) & 0x03);
scr_buf[1] = (uint8_t)((pts >> 20) & 0xff);
scr_buf[2] = (((uint8_t)(pts >> 15) & 0x1f) << 3) | 0x04 | ((uint8_t)(pts >> 13) & 0x03);
scr_buf[3] = (uint8_t)((pts >> 5) & 0xff);
scr_buf[4] = (((uint8_t)pts & 0x1f) << 3) | 0x04;
scr_buf[5] = 1;
}
// 设置PES头中的PTS和DTS字段
void SetPESTimeStamp(uint8_t *buff, uint64_t ts)
{
buff += 9;
// PTS
buff[0] = (uint8_t)(((ts >> 30) & 0x07) << 1) | 0x30 | 0x01;
buff[1] = (uint8_t)((ts >> 22) & 0xff);
buff[2] = (uint8_t)(((ts >> 15) & 0xff) << 1) | 0x01;
buff[3] = (uint8_t)((ts >> 7) & 0xff);
buff[4] = (uint8_t)((ts & 0xff) << 1) | 0x01;
// DTS
buff[5] = (uint8_t)(((ts >> 30) & 0x07) << 1) | 0x10 | 0x01;
buff[6] = (uint8_t)((ts >> 22) & 0xff);
buff[7] = (uint8_t)(((ts >> 15) & 0xff) << 1) | 0x01;
buff[8] = (uint8_t)((ts >> 7) & 0xff);
buff[9] = (uint8_t)((ts & 0xff) << 1) | 0x01;
}
int GetSinglePESHeader(uint8_t *header, uint64_t mtime, uint16_t farmLen)
{
farmLen += 13;
memcpy(header, PES_HEAD, sizeof(PES_HEAD));
*(header+4) = (uint8_t)(farmLen>>8);
*(header+5) = (uint8_t)farmLen;
SetPESTimeStamp(header, mtime);
return sizeof(PES_HEAD);
}
int GetPSHeader(uint8_t *header, uint64_t mtime, uint16_t farmLen, int streamType, int farmType)
{
if(streamType == 2) //语音包
{
GetSinglePESHeader(header, mtime, farmLen);
*(header+3) = 0xc0;
return sizeof(PES_HEAD);
}
else if(farmType == 1) //I帧
{
memcpy(header, PS_HEAD, sizeof(PS_HEAD));
SetHeaderTimeStamp(header, mtime);
header += sizeof(PS_HEAD);
memcpy(header, SYS_MAP_HEAD, sizeof(SYS_MAP_HEAD));
header += sizeof(SYS_MAP_HEAD);
GetSinglePESHeader(header, mtime, farmLen);
return sizeof(PS_HEAD) + sizeof(SYS_MAP_HEAD) + sizeof(PES_HEAD);
}
else
{
memcpy(header, PS_HEAD, sizeof(PS_HEAD));
SetHeaderTimeStamp(header, mtime);
header += sizeof(PS_HEAD);
GetSinglePESHeader(header, mtime, farmLen);
return sizeof(PS_HEAD) + sizeof(PES_HEAD);
}
}
unsigned char PSFrameBuffer[10*1024*1024]; //转换后的ps帧缓存区
int TransPSFrame(char *pFrame, int nFrameLength, int nIFrameFlag, int nStreamType, u_int nTimeStamp)
{
if(!pFrame || !nFrameLength)
return 0;
// 每个pes最多65400数据
int PesLenth = nFrameLength > 65400 ? 65400 : nFrameLength;
// 第一个pes需要有ps头,其它不需要,音频直接打包pes(00 00 01 c0)
int psHeadLen = GetPSHeader(PSFrameBuffer, nTimeStamp, PesLenth, nStreamType, nIFrameFlag);
memcpy(PSFrameBuffer + psHeadLen, pFrame, PesLenth);
int psSize = psHeadLen + PesLenth;
int pod = PesLenth;
nFrameLength -= PesLenth;
while (nFrameLength > 0)
{
PesLenth = nFrameLength > 65400 ? 65400 : nFrameLength;
psHeadLen = GetSinglePESHeader(PSFrameBuffer + psSize, nTimeStamp, PesLenth);
memcpy(PSFrameBuffer + psSize + psHeadLen, pFrame + pod, PesLenth);
psSize += (PesLenth + psHeadLen);
pod += PesLenth;
nFrameLength -= PesLenth;
}
//static FILE *fp = fopen("my.ps", "wb");
//if(fp)
// fwrite(PSFrameBuffer, 1, psSize, fp);
return psSize;
}