6
6
7
7
#include <ngx_config.h>
8
8
#include <ngx_core.h>
9
+ #include "ngx_rtmp.h"
9
10
#include "ngx_rtmp_mpegts.h"
10
11
11
12
12
- static u_char ngx_rtmp_mpegts_header [] = {
13
+ static u_char ngx_rtmp_mpegts_pat [] = {
13
14
14
15
/* TS */
15
16
0x47 , 0x40 , 0x00 , 0x10 , 0x00 ,
@@ -36,44 +37,150 @@ static u_char ngx_rtmp_mpegts_header[] = {
36
37
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
37
38
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
38
39
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
39
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
40
+ 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff
41
+ };
40
42
43
+
44
+ static u_char ngx_mpegts_ts_header [] = {
41
45
/* TS */
42
- 0x47 , 0x50 , 0x01 , 0x10 , 0x00 ,
46
+ 0x47 , 0x50 , 0x01 , 0x10 , 0x00
47
+ };
48
+
49
+ static u_char ngx_mpegts_pmt_header [] = {
43
50
/* PSI */
44
51
0x02 , 0xb0 , 0x17 , 0x00 , 0x01 , 0xc1 , 0x00 , 0x00 ,
45
52
/* PMT */
46
53
0xe1 , 0x00 ,
47
- 0xf0 , 0x00 ,
48
- 0x1b , 0xe1 , 0x00 , 0xf0 , 0x00 , /* h264 */
49
- 0x0f , 0xe1 , 0x01 , 0xf0 , 0x00 , /* aac */
50
- /*0x03, 0xe1, 0x01, 0xf0, 0x00,*/ /* mp3 */
51
- /* CRC */
52
- 0x2f , 0x44 , 0xb9 , 0x9b , /* crc for aac */
53
- /*0x4e, 0x59, 0x3d, 0x1e,*/ /* crc for mp3 */
54
- /* stuffing 157 bytes */
55
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
56
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
57
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
58
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
59
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
60
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
61
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
62
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
63
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
64
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
65
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
66
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
67
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
68
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
69
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
70
- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff
54
+ 0xf0 , 0x00
71
55
};
72
56
73
57
58
+ enum {
59
+ NGX_RTMP_MPEGTS_PID_H264 = 0 ,
60
+ NGX_RTMP_MPEGTS_PID_H265 ,
61
+ NGX_RTMP_MPEGTS_PID_AAC ,
62
+ NGX_RTMP_MPEGTS_PID_MP3
63
+ };
64
+
65
+ static u_char ngx_mpegts_pid [4 ][5 ] = {
66
+ {0x1b , 0xe1 , 0x00 , 0xf0 , 0x00 }, /* h264 */
67
+ {0x24 , 0xe1 , 0x00 , 0xf0 , 0x00 }, /* h265 */
68
+ {0x0f , 0xe1 , 0x01 , 0xf0 , 0x00 }, /* aac */
69
+ {0x03 , 0xe1 , 0x01 , 0xf0 , 0x00 } /* mp3 */
70
+ };
71
+
74
72
/* 700 ms PCR delay */
75
73
#define NGX_RTMP_HLS_DELAY 63000
76
74
75
+ static uint32_t crc32table [256 ] = {
76
+ 0x00000000 , 0x04c11db7 , 0x09823b6e , 0x0d4326d9 , 0x130476dc , 0x17c56b6b ,
77
+ 0x1a864db2 , 0x1e475005 , 0x2608edb8 , 0x22c9f00f , 0x2f8ad6d6 , 0x2b4bcb61 ,
78
+ 0x350c9b64 , 0x31cd86d3 , 0x3c8ea00a , 0x384fbdbd , 0x4c11db70 , 0x48d0c6c7 ,
79
+ 0x4593e01e , 0x4152fda9 , 0x5f15adac , 0x5bd4b01b , 0x569796c2 , 0x52568b75 ,
80
+ 0x6a1936c8 , 0x6ed82b7f , 0x639b0da6 , 0x675a1011 , 0x791d4014 , 0x7ddc5da3 ,
81
+ 0x709f7b7a , 0x745e66cd , 0x9823b6e0 , 0x9ce2ab57 , 0x91a18d8e , 0x95609039 ,
82
+ 0x8b27c03c , 0x8fe6dd8b , 0x82a5fb52 , 0x8664e6e5 , 0xbe2b5b58 , 0xbaea46ef ,
83
+ 0xb7a96036 , 0xb3687d81 , 0xad2f2d84 , 0xa9ee3033 , 0xa4ad16ea , 0xa06c0b5d ,
84
+ 0xd4326d90 , 0xd0f37027 , 0xddb056fe , 0xd9714b49 , 0xc7361b4c , 0xc3f706fb ,
85
+ 0xceb42022 , 0xca753d95 , 0xf23a8028 , 0xf6fb9d9f , 0xfbb8bb46 , 0xff79a6f1 ,
86
+ 0xe13ef6f4 , 0xe5ffeb43 , 0xe8bccd9a , 0xec7dd02d , 0x34867077 , 0x30476dc0 ,
87
+ 0x3d044b19 , 0x39c556ae , 0x278206ab , 0x23431b1c , 0x2e003dc5 , 0x2ac12072 ,
88
+ 0x128e9dcf , 0x164f8078 , 0x1b0ca6a1 , 0x1fcdbb16 , 0x018aeb13 , 0x054bf6a4 ,
89
+ 0x0808d07d , 0x0cc9cdca , 0x7897ab07 , 0x7c56b6b0 , 0x71159069 , 0x75d48dde ,
90
+ 0x6b93dddb , 0x6f52c06c , 0x6211e6b5 , 0x66d0fb02 , 0x5e9f46bf , 0x5a5e5b08 ,
91
+ 0x571d7dd1 , 0x53dc6066 , 0x4d9b3063 , 0x495a2dd4 , 0x44190b0d , 0x40d816ba ,
92
+ 0xaca5c697 , 0xa864db20 , 0xa527fdf9 , 0xa1e6e04e , 0xbfa1b04b , 0xbb60adfc ,
93
+ 0xb6238b25 , 0xb2e29692 , 0x8aad2b2f , 0x8e6c3698 , 0x832f1041 , 0x87ee0df6 ,
94
+ 0x99a95df3 , 0x9d684044 , 0x902b669d , 0x94ea7b2a , 0xe0b41de7 , 0xe4750050 ,
95
+ 0xe9362689 , 0xedf73b3e , 0xf3b06b3b , 0xf771768c , 0xfa325055 , 0xfef34de2 ,
96
+ 0xc6bcf05f , 0xc27dede8 , 0xcf3ecb31 , 0xcbffd686 , 0xd5b88683 , 0xd1799b34 ,
97
+ 0xdc3abded , 0xd8fba05a , 0x690ce0ee , 0x6dcdfd59 , 0x608edb80 , 0x644fc637 ,
98
+ 0x7a089632 , 0x7ec98b85 , 0x738aad5c , 0x774bb0eb , 0x4f040d56 , 0x4bc510e1 ,
99
+ 0x46863638 , 0x42472b8f , 0x5c007b8a , 0x58c1663d , 0x558240e4 , 0x51435d53 ,
100
+ 0x251d3b9e , 0x21dc2629 , 0x2c9f00f0 , 0x285e1d47 , 0x36194d42 , 0x32d850f5 ,
101
+ 0x3f9b762c , 0x3b5a6b9b , 0x0315d626 , 0x07d4cb91 , 0x0a97ed48 , 0x0e56f0ff ,
102
+ 0x1011a0fa , 0x14d0bd4d , 0x19939b94 , 0x1d528623 , 0xf12f560e , 0xf5ee4bb9 ,
103
+ 0xf8ad6d60 , 0xfc6c70d7 , 0xe22b20d2 , 0xe6ea3d65 , 0xeba91bbc , 0xef68060b ,
104
+ 0xd727bbb6 , 0xd3e6a601 , 0xdea580d8 , 0xda649d6f , 0xc423cd6a , 0xc0e2d0dd ,
105
+ 0xcda1f604 , 0xc960ebb3 , 0xbd3e8d7e , 0xb9ff90c9 , 0xb4bcb610 , 0xb07daba7 ,
106
+ 0xae3afba2 , 0xaafbe615 , 0xa7b8c0cc , 0xa379dd7b , 0x9b3660c6 , 0x9ff77d71 ,
107
+ 0x92b45ba8 , 0x9675461f , 0x8832161a , 0x8cf30bad , 0x81b02d74 , 0x857130c3 ,
108
+ 0x5d8a9099 , 0x594b8d2e , 0x5408abf7 , 0x50c9b640 , 0x4e8ee645 , 0x4a4ffbf2 ,
109
+ 0x470cdd2b , 0x43cdc09c , 0x7b827d21 , 0x7f436096 , 0x7200464f , 0x76c15bf8 ,
110
+ 0x68860bfd , 0x6c47164a , 0x61043093 , 0x65c52d24 , 0x119b4be9 , 0x155a565e ,
111
+ 0x18197087 , 0x1cd86d30 , 0x029f3d35 , 0x065e2082 , 0x0b1d065b , 0x0fdc1bec ,
112
+ 0x3793a651 , 0x3352bbe6 , 0x3e119d3f , 0x3ad08088 , 0x2497d08d , 0x2056cd3a ,
113
+ 0x2d15ebe3 , 0x29d4f654 , 0xc5a92679 , 0xc1683bce , 0xcc2b1d17 , 0xc8ea00a0 ,
114
+ 0xd6ad50a5 , 0xd26c4d12 , 0xdf2f6bcb , 0xdbee767c , 0xe3a1cbc1 , 0xe760d676 ,
115
+ 0xea23f0af , 0xeee2ed18 , 0xf0a5bd1d , 0xf464a0aa , 0xf9278673 , 0xfde69bc4 ,
116
+ 0x89b8fd09 , 0x8d79e0be , 0x803ac667 , 0x84fbdbd0 , 0x9abc8bd5 , 0x9e7d9662 ,
117
+ 0x933eb0bb , 0x97ffad0c , 0xafb010b1 , 0xab710d06 , 0xa6322bdf , 0xa2f33668 ,
118
+ 0xbcb4666d , 0xb8757bda , 0xb5365d03 , 0xb1f740b4
119
+ };
120
+
121
+
122
+ uint32_t
123
+ ngx_rtmp_mpegts_crc32 (u_char * crc_buf , const u_char * data , int len )
124
+ {
125
+ int i ;
126
+ uint32_t crc = 0xFFFFFFFF ;
127
+
128
+ for (i = 0 ; i < len ; i ++ ) {
129
+ crc = (crc << 8 ) ^ crc32table [((crc >> 24 ) ^ * data ++ ) & 0xFF ];
130
+ }
131
+
132
+ crc_buf [0 ] = (crc & 0xff000000 ) >> 24 ;
133
+ crc_buf [1 ] = (crc & 0x00ff0000 ) >> 16 ;
134
+ crc_buf [2 ] = (crc & 0x0000ff00 ) >> 8 ;
135
+ crc_buf [3 ] = crc & 0x000000ff ;
136
+
137
+ return crc ;
138
+ }
139
+
140
+
141
+ ngx_int_t
142
+ ngx_rtmp_mpegts_gen_pmt (ngx_int_t vcodec , ngx_int_t acodec , u_char * pmt )
143
+ {
144
+ u_char * p , crc_buf [4 ], * pmt_pos ;
145
+ ngx_int_t vpid = -1 , apid = -1 ;
146
+
147
+ if (vcodec == acodec && vcodec == 0 ) {
148
+ return NGX_ERROR ;
149
+ }
150
+
151
+ p = pmt ;
152
+ p = ngx_cpymem (p , ngx_mpegts_ts_header , sizeof (ngx_mpegts_ts_header ));
153
+ pmt_pos = p ;
154
+
155
+ p = ngx_cpymem (p , ngx_mpegts_pmt_header , sizeof (ngx_mpegts_pmt_header ));
156
+ if (vcodec == NGX_RTMP_VIDEO_H264 ) {
157
+ vpid = NGX_RTMP_MPEGTS_PID_H264 ;
158
+ } else if (vcodec == NGX_RTMP_VIDEO_H265 ) {
159
+ vpid = NGX_RTMP_MPEGTS_PID_H265 ;
160
+ }
161
+
162
+ if (acodec == NGX_RTMP_AUDIO_AAC ) {
163
+ apid = NGX_RTMP_MPEGTS_PID_AAC ;
164
+ } else if (acodec == NGX_RTMP_AUDIO_MP3 ) {
165
+ apid = NGX_RTMP_MPEGTS_PID_MP3 ;
166
+ }
167
+
168
+ if (vpid != -1 ) {
169
+ p = ngx_cpymem (p , ngx_mpegts_pid [vpid ], 5 );
170
+ }
171
+
172
+ if (apid != -1 ) {
173
+ p = ngx_cpymem (p , ngx_mpegts_pid [apid ], 5 );
174
+ }
175
+
176
+ ngx_rtmp_mpegts_crc32 (crc_buf , pmt_pos , p - pmt_pos );
177
+ p = ngx_cpymem (p , crc_buf , 4 );
178
+
179
+ ngx_memset (p , 0xff , 188 - (p - pmt ));
180
+
181
+ return NGX_OK ;
182
+ }
183
+
77
184
78
185
static ngx_int_t
79
186
ngx_rtmp_mpegts_write_file (ngx_rtmp_mpegts_file_t * file , u_char * in ,
@@ -157,8 +264,20 @@ ngx_rtmp_mpegts_write_file(ngx_rtmp_mpegts_file_t *file, u_char *in,
157
264
static ngx_int_t
158
265
ngx_rtmp_mpegts_write_header (ngx_rtmp_mpegts_file_t * file )
159
266
{
160
- return ngx_rtmp_mpegts_write_file (file , ngx_rtmp_mpegts_header ,
161
- sizeof (ngx_rtmp_mpegts_header ));
267
+ ngx_int_t ret ;
268
+ u_char pmt [188 ];
269
+
270
+ ret = ngx_rtmp_mpegts_write_file (file , ngx_rtmp_mpegts_pat ,
271
+ sizeof (ngx_rtmp_mpegts_pat ));
272
+ if (ret != NGX_OK ) {
273
+ return ret ;
274
+ }
275
+
276
+ if (ngx_rtmp_mpegts_gen_pmt (file -> vcodec , file -> acodec , pmt ) != NGX_OK ) {
277
+ return NGX_ERROR ;
278
+ }
279
+
280
+ return ngx_rtmp_mpegts_write_file (file , pmt , sizeof (pmt ));
162
281
}
163
282
164
283
0 commit comments