-
Notifications
You must be signed in to change notification settings - Fork 4
/
rtp_sender.cpp
163 lines (132 loc) · 4.75 KB
/
rtp_sender.cpp
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
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "rtp_sender.h"
#include "z_udp.h"
#include "z_bits.h"
#include "h264_nal.h"
int send_rtp(const char* ip,const char* port,const char* filename){
int fd = udp_client(ip,port);
if(fd < 0){
printf("create client failed!\n");
return -1;
}
int on = 1;
/*
* 设置广播属性
*/
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
fprintf(stderr, "initSvr: Socket options set error.\n");
return -1;
}
FILE* fp = fopen(filename,"rb");
if(fp == NULL){
return -1;
}
const int frameRate = 5;
uint16_t seq_num = 0;
uint32_t time_stamp = 0;
uint8_t* nalu = new uint8_t[NAL_MAX_SIZE];
uint8_t* send_data = new uint8_t[NAL_MAX_SIZE + 64];
size_t send_len = 0;
int len = 0;
bool flag = false;
H264Reader reader(fp);
while(reader.ReadNalu(nalu,&len)){
rtp_header_t* rtp_hdr = 0;
fu_indicator_t* fu_ind = NULL;
fu_header_t* fu_hdr = NULL;
if(len <= RTP_PAYLOAD_MAX_SIZE){
rtp_hdr = (rtp_header_t*)send_data;
fu_ind = (fu_indicator_t*)send_data + RTP_HEADER_SIZE;
rtp_hdr->csrc_len = 0;
rtp_hdr->extension = 0;
//rtp_hdr->marker = 0;
rtp_hdr->padding = 0;
rtp_hdr->version = 2;
rtp_hdr->payload_type = H264_Type;
rtp_hdr->seq_no = htons(++seq_num % UINT16_MAX);
rtp_hdr->timestamp = htonl(time_stamp);
rtp_hdr->ssrc = htonl( SSRC_NUM);
#ifdef RTP_STANDARD
*((unsigned char*)fu_ind) = nalu[0];
//fu_ind->f = (nalu[0] & 0x01) ; /* bit0 */
//fu_ind->nri = (nalu[0] & 0x03) >> 1; /* bit1~2 */
//fu_ind->type = (nalu[0] & 0xF1) >> 3;
#else
fu_ind->f = (nalu[0] & 0x80) >> 7; /* bit0 */
fu_ind->nri = (nalu[0] & 0x60) >> 5; /* bit1~2 */
fu_ind->type = (nalu[0] & 0x1f);
#endif
memcpy(send_data + RTP_HEADER_SIZE + FU_INDICATOR_SIZE,
nalu + 1,len - 1);
send_len = RTP_HEADER_SIZE + FU_INDICATOR_SIZE + len - 1;
udp_send(fd,send_data,send_len);
}
else{
int num = 0;
if(len % RTP_PAYLOAD_MAX_SIZE == 0){
num = len / RTP_PAYLOAD_MAX_SIZE;
}
else{
num = len / RTP_PAYLOAD_MAX_SIZE + 1;
}
uint8_t* data = nalu + 1;
for(int i = 0; i < num; ++i){
rtp_hdr = (rtp_header_t*)send_data;
fu_ind = (fu_indicator_t*)send_data + RTP_HEADER_SIZE;
fu_hdr = (fu_header_t*)send_data + RTP_HEADER_SIZE + FU_INDICATOR_SIZE;
rtp_hdr->csrc_len = 0;
rtp_hdr->extension = 0;
rtp_hdr->marker = 0;
rtp_hdr->padding = 0;
rtp_hdr->payload_type = H264_Type;
rtp_hdr->seq_no = htons(++seq_num % UINT16_MAX);
rtp_hdr->ssrc = htonl( SSRC_NUM);
rtp_hdr->timestamp = htonl(time_stamp);
rtp_hdr->version = 2;
#ifdef RTP_STANDARD
fu_ind->f = (nalu[0] & 0x01) ; /* bit0 */
fu_ind->nri = (nalu[0] & 0x06) >> 1; /* bit1~2 */
fu_ind->type = 28;
#else
fu_ind->f = (nalu[0] & 0x80) >> 7;
fu_ind->nri = (nalu[0] & 0x60) >> 5;
fu_ind->type = 28;
#endif
#ifdef RTP_STANDARD
fu_hdr->type = (nalu[0] & 0xF1) >> 3;
#else
fu_hdr->type = nalu[0] & 0x1f;
#endif
fu_hdr->s = 0;
fu_hdr->e = 0;
fu_hdr->r = 0;
size_t realLen = RTP_PAYLOAD_MAX_SIZE;
if(i == 0){
fu_hdr->s = 1;
fu_hdr->e = 0;
realLen -= 1; // 因为nalu头部已经被塞到fu字段中了
}
else if(i == num -1){
rtp_hdr->marker = 1;
fu_hdr->s = 0;
fu_hdr->e = 1;
if(len % RTP_PAYLOAD_MAX_SIZE != 0){
realLen = len % RTP_PAYLOAD_MAX_SIZE;
}
}
else{
fu_hdr->s = 0;
fu_hdr->e = 0;
}
memcpy(send_data + RTP_HEADER_SIZE + FU_INDICATOR_SIZE + FU_HEADER_SIZE,
data,
realLen);
data += realLen;
send_len = RTP_HEADER_SIZE + FU_INDICATOR_SIZE + FU_HEADER_SIZE + realLen;
udp_send(fd,send_data,send_len);
}
}
usleep(10);
time_stamp += (90000 / frameRate);
}
return 0;
}