1
2 /*
3 * Copyright (C) Roman Arutyunyan
4 */
5
6
7 #ifndef _NGX_RTMP_H_INCLUDED_
8 #define _NGX_RTMP_H_INCLUDED_
9
10
11 #include <ngx_config.h>
12 #include <ngx_core.h>
13 #include <ngx_event.h>
14 #include <ngx_event_connect.h>
15 #include <nginx.h>
16
17 #include "ngx_rtmp_amf.h"
18 #include "ngx_rtmp_bandwidth.h"
19
20
21 #if (NGX_WIN32)
22 typedef __int8 int8_t;
23 typedef unsigned __int8 uint8_t;
24 #endif
25
26
27 typedef struct {
28 void **main_conf;
29 void **srv_conf;
30 void **app_conf;
31 } ngx_rtmp_conf_ctx_t;
32
33
34 typedef struct {
35 u_char sockaddr[NGX_SOCKADDRLEN];
36 socklen_t socklen;
37
38 /* server ctx */
39 ngx_rtmp_conf_ctx_t *ctx;
40
41 unsigned bind:1;
42 unsigned wildcard:1;
43 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
44 unsigned ipv6only:2;
45 #endif
46 unsigned so_keepalive:2;
47 unsigned proxy_protocol:1;
48 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
49 int tcp_keepidle;
50 int tcp_keepintvl;
51 int tcp_keepcnt;
52 #endif
53 } ngx_rtmp_listen_t;
54
55
56 typedef struct {
57 ngx_rtmp_conf_ctx_t *ctx;
58 ngx_str_t addr_text;
59 unsigned proxy_protocol:1;
60 } ngx_rtmp_addr_conf_t;
61
62 typedef struct {
63 ngx_rtmp_addr_conf_t conf;
64 in_addr_t addr;
65 } ngx_rtmp_in_addr_t;
66
67
68 #if (NGX_HAVE_INET6)
69
70 typedef struct {
71 ngx_rtmp_addr_conf_t conf;
72 struct in6_addr addr6;
73 } ngx_rtmp_in6_addr_t;
74
75 #endif
76
77
78 typedef struct {
79 void *addrs;
80 ngx_uint_t naddrs;
81 } ngx_rtmp_port_t;
82
83
84 typedef struct {
85 int family;
86 in_port_t port;
87 ngx_array_t addrs; /* array of ngx_rtmp_conf_addr_t */
88 } ngx_rtmp_conf_port_t;
89
90
91 typedef struct {
92 struct sockaddr *sockaddr;
93 socklen_t socklen;
94
95 ngx_rtmp_conf_ctx_t *ctx;
96
97 unsigned bind:1;
98 unsigned wildcard:1;
99 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
100 unsigned ipv6only:2;
101 #endif
102 unsigned so_keepalive:2;
103 unsigned proxy_protocol:1;
104 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
105 int tcp_keepidle;
106 int tcp_keepintvl;
107 int tcp_keepcnt;
108 #endif
109 } ngx_rtmp_conf_addr_t;
110
111
112 #define NGX_RTMP_VERSION 3
113
114 #define NGX_LOG_DEBUG_RTMP NGX_LOG_DEBUG_CORE
115
116 #define NGX_RTMP_DEFAULT_CHUNK_SIZE 128
117
118
119 /* RTMP message types */
120 #define NGX_RTMP_MSG_CHUNK_SIZE 1
121 #define NGX_RTMP_MSG_ABORT 2
122 #define NGX_RTMP_MSG_ACK 3
123 #define NGX_RTMP_MSG_USER 4
124 #define NGX_RTMP_MSG_ACK_SIZE 5
125 #define NGX_RTMP_MSG_BANDWIDTH 6
126 #define NGX_RTMP_MSG_EDGE 7
127 #define NGX_RTMP_MSG_AUDIO 8
128 #define NGX_RTMP_MSG_VIDEO 9
129 #define NGX_RTMP_MSG_AMF3_META 15
130 #define NGX_RTMP_MSG_AMF3_SHARED 16
131 #define NGX_RTMP_MSG_AMF3_CMD 17
132 #define NGX_RTMP_MSG_AMF_META 18
133 #define NGX_RTMP_MSG_AMF_SHARED 19
134 #define NGX_RTMP_MSG_AMF_CMD 20
135 #define NGX_RTMP_MSG_AGGREGATE 22
136 #define NGX_RTMP_MSG_MAX 22
137
138 #define NGX_RTMP_CONNECT NGX_RTMP_MSG_MAX + 1
139 #define NGX_RTMP_DISCONNECT NGX_RTMP_MSG_MAX + 2
140 #define NGX_RTMP_HANDSHAKE_DONE NGX_RTMP_MSG_MAX + 3
141 #define NGX_RTMP_MAX_EVENT NGX_RTMP_MSG_MAX + 4
142
143
144 /* RMTP control message types */
145 #define NGX_RTMP_USER_STREAM_BEGIN 0
146 #define NGX_RTMP_USER_STREAM_EOF 1
147 #define NGX_RTMP_USER_STREAM_DRY 2
148 #define NGX_RTMP_USER_SET_BUFLEN 3
149 #define NGX_RTMP_USER_RECORDED 4
150 #define NGX_RTMP_USER_PING_REQUEST 6
151 #define NGX_RTMP_USER_PING_RESPONSE 7
152 #define NGX_RTMP_USER_UNKNOWN 8
153 #define NGX_RTMP_USER_BUFFER_END 31
154
155
156 /* Chunk header:
157 * max 3 basic header
158 * + max 11 message header
159 * + max 4 extended header (timestamp) */
160 #define NGX_RTMP_MAX_CHUNK_HEADER 18
161
162
163 typedef struct {
164 uint32_t csid; /* chunk stream id */
165 uint32_t timestamp; /* timestamp (delta) */
166 uint32_t mlen; /* message length */
167 uint8_t type; /* message type id */
168 uint32_t msid; /* message stream id */
169 } ngx_rtmp_header_t;
170
171
172 typedef struct {
173 ngx_rtmp_header_t hdr;
174 uint32_t dtime;
175 uint32_t len; /* current fragment length */
176 uint8_t ext;
177 ngx_chain_t *in;
178 } ngx_rtmp_stream_t;
179
180
181 /* disable zero-sized array warning by msvc */
182
183 #if (NGX_WIN32)
184 #pragma warning(push)
185 #pragma warning(disable:4200)
186 #endif
187
188
189 typedef struct {
190 uint32_t signature; /* "RTMP" */ /* <-- FIXME wtf */
191
192 ngx_event_t close;
193
194 void **ctx;
195 void **main_conf;
196 void **srv_conf;
197 void **app_conf;
198
199 ngx_str_t *addr_text;
200 int connected;
201
202 #if (nginx_version >= 1007005)
203 ngx_queue_t posted_dry_events;
204 #else
205 ngx_event_t *posted_dry_events;
206 #endif
207
208 /* client buffer time in msec */
209 uint32_t buflen;
210 uint32_t ack_size;
211
212 /* connection parameters */
213 ngx_str_t app;
214 ngx_str_t args;
215 ngx_str_t flashver;
216 ngx_str_t swf_url;
217 ngx_str_t tc_url;
218 uint32_t acodecs;
219 uint32_t vcodecs;
220 ngx_str_t page_url;
221
222 /* handshake data */
223 ngx_buf_t *hs_buf;
224 u_char *hs_digest;
225 unsigned hs_old:1;
226 ngx_uint_t hs_stage;
227
228 /* connection timestamps */
229 ngx_msec_t epoch;
230 ngx_msec_t peer_epoch;
231 ngx_msec_t base_time;
232 uint32_t current_time;
233
234 /* ready for publishing? */
235 unsigned ready_for_publish:1;
236
237 /* ping */
238 ngx_event_t ping_evt;
239 unsigned ping_active:1;
240 unsigned ping_reset:1;
241
242 /* auto-pushed? */
243 unsigned auto_pushed:1;
244 unsigned relay:1;
245 unsigned static_relay:1;
246
247 /* input stream 0 (reserved by RTMP spec)
248 * is used as free chain link */
249
250 ngx_rtmp_stream_t *in_streams;
251 uint32_t in_csid;
252 ngx_uint_t in_chunk_size;
253 ngx_pool_t *in_pool;
254 uint32_t in_bytes;
255 uint32_t in_last_ack;
256
257 ngx_pool_t *in_old_pool;
258 ngx_int_t in_chunk_size_changing;
259
260 ngx_connection_t *connection;
261
262 /* circular buffer of RTMP message pointers */
263 ngx_msec_t timeout;
264 uint32_t out_bytes;
265 size_t out_pos, out_last;
266 ngx_chain_t *out_chain;
267 u_char *out_bpos;
268 unsigned out_buffer:1;
269 size_t out_queue;
270 size_t out_cork;
271 ngx_chain_t *out[0];
272 } ngx_rtmp_session_t;
273
274
275 #if (NGX_WIN32)
276 #pragma warning(pop)
277 #endif
278
279
280 /* handler result code:
281 * NGX_ERROR - error
282 * NGX_OK - success, may continue
283 * NGX_DONE - success, input parsed, reply sent; need no
284 * more calls on this event */
285 typedef ngx_int_t (*ngx_rtmp_handler_pt)(ngx_rtmp_session_t *s,
286 ngx_rtmp_header_t *h, ngx_chain_t *in);
287
288
289 typedef struct {
290 ngx_str_t name;
291 ngx_rtmp_handler_pt handler;
292 } ngx_rtmp_amf_handler_t;
293
294
295 typedef struct {
296 ngx_array_t servers; /* ngx_rtmp_core_srv_conf_t */
297 ngx_array_t listen; /* ngx_rtmp_listen_t */
298
299 ngx_array_t events[NGX_RTMP_MAX_EVENT];
300
301 ngx_hash_t amf_hash;
302 ngx_array_t amf_arrays;
303 ngx_array_t amf;
304 } ngx_rtmp_core_main_conf_t;
305
306
307 /* global main conf for stats */
308 extern ngx_rtmp_core_main_conf_t *ngx_rtmp_core_main_conf;
309
310
311 typedef struct ngx_rtmp_core_srv_conf_s {
312 ngx_array_t applications; /* ngx_rtmp_core_app_conf_t */
313
314 ngx_msec_t timeout;
315 ngx_msec_t ping;
316 ngx_msec_t ping_timeout;
317 ngx_flag_t so_keepalive;
318 ngx_int_t max_streams;
319
320 ngx_uint_t ack_window;
321
322 ngx_int_t chunk_size;
323 ngx_pool_t *pool;
324 ngx_chain_t *free;
325 ngx_chain_t *free_hs;
326 size_t max_message;
327 ngx_flag_t play_time_fix;
328 ngx_flag_t publish_time_fix;
329 ngx_flag_t busy;
330 size_t out_queue;
331 size_t out_cork;
332 ngx_msec_t buflen;
333
334 ngx_rtmp_conf_ctx_t *ctx;
335 } ngx_rtmp_core_srv_conf_t;
336
337
338 typedef struct {
339 ngx_array_t applications; /* ngx_rtmp_core_app_conf_t */
340 ngx_str_t name;
341 void **app_conf;
342 } ngx_rtmp_core_app_conf_t;
343
344
345 typedef struct {
346 ngx_str_t *client;
347 ngx_rtmp_session_t *session;
348 } ngx_rtmp_error_log_ctx_t;
349
350
351 typedef struct {
352 ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
353 ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
354
355 void *(*create_main_conf)(ngx_conf_t *cf);
356 char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
357
358 void *(*create_srv_conf)(ngx_conf_t *cf);
359 char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
360 void *conf);
361
362 void *(*create_app_conf)(ngx_conf_t *cf);
363 char *(*merge_app_conf)(ngx_conf_t *cf, void *prev,
364 void *conf);
365 } ngx_rtmp_module_t;
366
367 #define NGX_RTMP_MODULE 0x504D5452 /* "RTMP" */
368
369 #define NGX_RTMP_MAIN_CONF 0x02000000
370 #define NGX_RTMP_SRV_CONF 0x04000000
371 #define NGX_RTMP_APP_CONF 0x08000000
372 #define NGX_RTMP_REC_CONF 0x10000000
373
374
375 #define NGX_RTMP_MAIN_CONF_OFFSET offsetof(ngx_rtmp_conf_ctx_t, main_conf)
376 #define NGX_RTMP_SRV_CONF_OFFSET offsetof(ngx_rtmp_conf_ctx_t, srv_conf)
377 #define NGX_RTMP_APP_CONF_OFFSET offsetof(ngx_rtmp_conf_ctx_t, app_conf)
378
379
380 #define ngx_rtmp_get_module_ctx(s, module) (s)->ctx[module.ctx_index]
381 #define ngx_rtmp_set_ctx(s, c, module) s->ctx[module.ctx_index] = c;
382 #define ngx_rtmp_delete_ctx(s, module) s->ctx[module.ctx_index] = NULL;
383
384
385 #define ngx_rtmp_get_module_main_conf(s, module) \
386 (s)->main_conf[module.ctx_index]
387 #define ngx_rtmp_get_module_srv_conf(s, module) (s)->srv_conf[module.ctx_index]
388 #define ngx_rtmp_get_module_app_conf(s, module) ((s)->app_conf ? \
389 (s)->app_conf[module.ctx_index] : NULL)
390
391 #define ngx_rtmp_conf_get_module_main_conf(cf, module) \
392 ((ngx_rtmp_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
393 #define ngx_rtmp_conf_get_module_srv_conf(cf, module) \
394 ((ngx_rtmp_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
395 #define ngx_rtmp_conf_get_module_app_conf(cf, module) \
396 ((ngx_rtmp_conf_ctx_t *) cf->ctx)->app_conf[module.ctx_index]
397
398
399 #ifdef NGX_DEBUG
400 char* ngx_rtmp_message_type(uint8_t type);
401 char* ngx_rtmp_user_message_type(uint16_t evt);
402 #endif
403
404 void ngx_rtmp_init_connection(ngx_connection_t *c);
405 ngx_rtmp_session_t * ngx_rtmp_init_session(ngx_connection_t *c,
406 ngx_rtmp_addr_conf_t *addr_conf);
407 void ngx_rtmp_finalize_session(ngx_rtmp_session_t *s);
408 void ngx_rtmp_handshake(ngx_rtmp_session_t *s);
409 void ngx_rtmp_client_handshake(ngx_rtmp_session_t *s, unsigned async);
410 void ngx_rtmp_free_handshake_buffers(ngx_rtmp_session_t *s);
411 void ngx_rtmp_cycle(ngx_rtmp_session_t *s);
412 void ngx_rtmp_reset_ping(ngx_rtmp_session_t *s);
413 ngx_int_t ngx_rtmp_fire_event(ngx_rtmp_session_t *s, ngx_uint_t evt,
414 ngx_rtmp_header_t *h, ngx_chain_t *in);
415
416
417 ngx_int_t ngx_rtmp_set_chunk_size(ngx_rtmp_session_t *s, ngx_uint_t size);
418
419
420 /* Bit reverse: we need big-endians in many places */
421 void * ngx_rtmp_rmemcpy(void *dst, const void* src, size_t n);
422
423 #define ngx_rtmp_rcpymem(dst, src, n) \
424 (((u_char*)ngx_rtmp_rmemcpy(dst, src, n)) + (n))
425
426
427 static ngx_inline uint16_t
ngx_rtmp_r16(uint16_t n)428 ngx_rtmp_r16(uint16_t n)
429 {
430 return (n << 8) | (n >> 8);
431 }
432
433
434 static ngx_inline uint32_t
ngx_rtmp_r32(uint32_t n)435 ngx_rtmp_r32(uint32_t n)
436 {
437 return (n << 24) | ((n << 8) & 0xff0000) | ((n >> 8) & 0xff00) | (n >> 24);
438 }
439
440
441 static ngx_inline uint64_t
ngx_rtmp_r64(uint64_t n)442 ngx_rtmp_r64(uint64_t n)
443 {
444 return (uint64_t) ngx_rtmp_r32((uint32_t) n) << 32 |
445 ngx_rtmp_r32((uint32_t) (n >> 32));
446 }
447
448
449 /* Receiving messages */
450 ngx_int_t ngx_rtmp_receive_message(ngx_rtmp_session_t *s,
451 ngx_rtmp_header_t *h, ngx_chain_t *in);
452 ngx_int_t ngx_rtmp_protocol_message_handler(ngx_rtmp_session_t *s,
453 ngx_rtmp_header_t *h, ngx_chain_t *in);
454 ngx_int_t ngx_rtmp_user_message_handler(ngx_rtmp_session_t *s,
455 ngx_rtmp_header_t *h, ngx_chain_t *in);
456 ngx_int_t ngx_rtmp_aggregate_message_handler(ngx_rtmp_session_t *s,
457 ngx_rtmp_header_t *h, ngx_chain_t *in);
458 ngx_int_t ngx_rtmp_amf_message_handler(ngx_rtmp_session_t *s,
459 ngx_rtmp_header_t *h, ngx_chain_t *in);
460 ngx_int_t ngx_rtmp_amf_shared_object_handler(ngx_rtmp_session_t *s,
461 ngx_rtmp_header_t *h, ngx_chain_t *in);
462
463
464 /* Shared output buffers */
465
466 /* Store refcount in negative bytes of shared buffer */
467
468 #define NGX_RTMP_REFCOUNT_TYPE uint32_t
469 #define NGX_RTMP_REFCOUNT_BYTES sizeof(NGX_RTMP_REFCOUNT_TYPE)
470
471 #define ngx_rtmp_ref(b) \
472 *((NGX_RTMP_REFCOUNT_TYPE*)(b) - 1)
473
474 #define ngx_rtmp_ref_set(b, v) \
475 ngx_rtmp_ref(b) = v
476
477 #define ngx_rtmp_ref_get(b) \
478 ++ngx_rtmp_ref(b)
479
480 #define ngx_rtmp_ref_put(b) \
481 --ngx_rtmp_ref(b)
482
483 ngx_chain_t * ngx_rtmp_alloc_shared_buf(ngx_rtmp_core_srv_conf_t *cscf);
484 void ngx_rtmp_free_shared_chain(ngx_rtmp_core_srv_conf_t *cscf,
485 ngx_chain_t *in);
486 ngx_chain_t * ngx_rtmp_append_shared_bufs(ngx_rtmp_core_srv_conf_t *cscf,
487 ngx_chain_t *head, ngx_chain_t *in);
488
489 #define ngx_rtmp_acquire_shared_chain(in) \
490 ngx_rtmp_ref_get(in); \
491
492
493 /* Sending messages */
494 void ngx_rtmp_prepare_message(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
495 ngx_rtmp_header_t *lh, ngx_chain_t *out);
496 ngx_int_t ngx_rtmp_send_message(ngx_rtmp_session_t *s, ngx_chain_t *out,
497 ngx_uint_t priority);
498
499 /* Note on priorities:
500 * the bigger value the lower the priority.
501 * priority=0 is the highest */
502
503
504 #define NGX_RTMP_LIMIT_SOFT 0
505 #define NGX_RTMP_LIMIT_HARD 1
506 #define NGX_RTMP_LIMIT_DYNAMIC 2
507
508 /* Protocol control messages */
509 ngx_chain_t * ngx_rtmp_create_chunk_size(ngx_rtmp_session_t *s,
510 uint32_t chunk_size);
511 ngx_chain_t * ngx_rtmp_create_abort(ngx_rtmp_session_t *s,
512 uint32_t csid);
513 ngx_chain_t * ngx_rtmp_create_ack(ngx_rtmp_session_t *s,
514 uint32_t seq);
515 ngx_chain_t * ngx_rtmp_create_ack_size(ngx_rtmp_session_t *s,
516 uint32_t ack_size);
517 ngx_chain_t * ngx_rtmp_create_bandwidth(ngx_rtmp_session_t *s,
518 uint32_t ack_size, uint8_t limit_type);
519
520 ngx_int_t ngx_rtmp_send_chunk_size(ngx_rtmp_session_t *s,
521 uint32_t chunk_size);
522 ngx_int_t ngx_rtmp_send_abort(ngx_rtmp_session_t *s,
523 uint32_t csid);
524 ngx_int_t ngx_rtmp_send_ack(ngx_rtmp_session_t *s,
525 uint32_t seq);
526 ngx_int_t ngx_rtmp_send_ack_size(ngx_rtmp_session_t *s,
527 uint32_t ack_size);
528 ngx_int_t ngx_rtmp_send_bandwidth(ngx_rtmp_session_t *s,
529 uint32_t ack_size, uint8_t limit_type);
530
531 /* User control messages */
532 ngx_chain_t * ngx_rtmp_create_stream_begin(ngx_rtmp_session_t *s,
533 uint32_t msid);
534 ngx_chain_t * ngx_rtmp_create_stream_eof(ngx_rtmp_session_t *s,
535 uint32_t msid);
536 ngx_chain_t * ngx_rtmp_create_stream_dry(ngx_rtmp_session_t *s,
537 uint32_t msid);
538 ngx_chain_t * ngx_rtmp_create_set_buflen(ngx_rtmp_session_t *s,
539 uint32_t msid, uint32_t buflen_msec);
540 ngx_chain_t * ngx_rtmp_create_recorded(ngx_rtmp_session_t *s,
541 uint32_t msid);
542 ngx_chain_t * ngx_rtmp_create_ping_request(ngx_rtmp_session_t *s,
543 uint32_t timestamp);
544 ngx_chain_t * ngx_rtmp_create_ping_response(ngx_rtmp_session_t *s,
545 uint32_t timestamp);
546
547 ngx_int_t ngx_rtmp_send_stream_begin(ngx_rtmp_session_t *s,
548 uint32_t msid);
549 ngx_int_t ngx_rtmp_send_stream_eof(ngx_rtmp_session_t *s,
550 uint32_t msid);
551 ngx_int_t ngx_rtmp_send_stream_dry(ngx_rtmp_session_t *s,
552 uint32_t msid);
553 ngx_int_t ngx_rtmp_send_set_buflen(ngx_rtmp_session_t *s,
554 uint32_t msid, uint32_t buflen_msec);
555 ngx_int_t ngx_rtmp_send_recorded(ngx_rtmp_session_t *s,
556 uint32_t msid);
557 ngx_int_t ngx_rtmp_send_ping_request(ngx_rtmp_session_t *s,
558 uint32_t timestamp);
559 ngx_int_t ngx_rtmp_send_ping_response(ngx_rtmp_session_t *s,
560 uint32_t timestamp);
561
562 /* AMF sender/receiver */
563 ngx_int_t ngx_rtmp_append_amf(ngx_rtmp_session_t *s,
564 ngx_chain_t **first, ngx_chain_t **last,
565 ngx_rtmp_amf_elt_t *elts, size_t nelts);
566 ngx_int_t ngx_rtmp_receive_amf(ngx_rtmp_session_t *s, ngx_chain_t *in,
567 ngx_rtmp_amf_elt_t *elts, size_t nelts);
568
569 ngx_chain_t * ngx_rtmp_create_amf(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
570 ngx_rtmp_amf_elt_t *elts, size_t nelts);
571 ngx_int_t ngx_rtmp_send_amf(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
572 ngx_rtmp_amf_elt_t *elts, size_t nelts);
573
574 /* AMF status sender */
575 ngx_chain_t * ngx_rtmp_create_status(ngx_rtmp_session_t *s, char *code,
576 char* level, char *desc);
577 ngx_chain_t * ngx_rtmp_create_play_status(ngx_rtmp_session_t *s, char *code,
578 char* level, ngx_uint_t duration, ngx_uint_t bytes);
579 ngx_chain_t * ngx_rtmp_create_sample_access(ngx_rtmp_session_t *s);
580
581 ngx_int_t ngx_rtmp_send_status(ngx_rtmp_session_t *s, char *code,
582 char* level, char *desc);
583 ngx_int_t ngx_rtmp_send_play_status(ngx_rtmp_session_t *s, char *code,
584 char* level, ngx_uint_t duration, ngx_uint_t bytes);
585 ngx_int_t ngx_rtmp_send_sample_access(ngx_rtmp_session_t *s);
586 ngx_int_t ngx_rtmp_send_redirect_status(ngx_rtmp_session_t *s,
587 char *callMethod, char *desc, ngx_str_t to_url);
588 ngx_int_t ngx_rtmp_send_close_method(ngx_rtmp_session_t *s, char *methodName);
589 ngx_int_t ngx_rtmp_send_fcpublish(ngx_rtmp_session_t *s, u_char *desc);
590 ngx_int_t ngx_rtmp_send_fcunpublish(ngx_rtmp_session_t *s, u_char *desc);
591 ngx_int_t ngx_rtmp_send_fi(ngx_rtmp_session_t *s);
592
593
594 /* Frame types */
595 #define NGX_RTMP_VIDEO_KEY_FRAME 1
596 #define NGX_RTMP_VIDEO_INTER_FRAME 2
597 #define NGX_RTMP_VIDEO_DISPOSABLE_FRAME 3
598
599
600 static ngx_inline ngx_int_t
ngx_rtmp_get_video_frame_type(ngx_chain_t * in)601 ngx_rtmp_get_video_frame_type(ngx_chain_t *in)
602 {
603 return (in->buf->pos[0] & 0xf0) >> 4;
604 }
605
606
607 static ngx_inline ngx_int_t
ngx_rtmp_is_codec_header(ngx_chain_t * in)608 ngx_rtmp_is_codec_header(ngx_chain_t *in)
609 {
610 return in->buf->pos + 1 < in->buf->last && in->buf->pos[1] == 0;
611 }
612
613
614 extern ngx_rtmp_bandwidth_t ngx_rtmp_bw_out;
615 extern ngx_rtmp_bandwidth_t ngx_rtmp_bw_in;
616
617
618 extern ngx_uint_t ngx_rtmp_naccepted;
619 #if (nginx_version >= 1007011)
620 extern ngx_queue_t ngx_rtmp_init_queue;
621 #elif (nginx_version >= 1007005)
622 extern ngx_thread_volatile ngx_queue_t ngx_rtmp_init_queue;
623 #else
624 extern ngx_thread_volatile ngx_event_t *ngx_rtmp_init_queue;
625 #endif
626
627 extern ngx_uint_t ngx_rtmp_max_module;
628 extern ngx_module_t ngx_rtmp_core_module;
629
630
631 #endif /* _NGX_RTMP_H_INCLUDED_ */
632