2012-03-08 16:21:22 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2012 Roman Arutyunyan
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _NGX_RTMP_H_INCLUDED_
|
|
|
|
#define _NGX_RTMP_H_INCLUDED_
|
|
|
|
|
|
|
|
|
|
|
|
#include <ngx_config.h>
|
|
|
|
#include <ngx_core.h>
|
|
|
|
#include <ngx_event.h>
|
|
|
|
#include <ngx_event_connect.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define NGX_RTMP_HANDSHAKE_SIZE 1536
|
|
|
|
|
|
|
|
#define NGX_RTMP_DEFAULT_CHUNK_SIZE 128
|
|
|
|
|
2012-03-08 18:45:10 +01:00
|
|
|
#define NGX_LOG_DEBUG_RTMP NGX_LOG_DEBUG_CORE
|
|
|
|
|
2012-03-08 16:21:22 +01:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
void **main_conf;
|
|
|
|
void **srv_conf;
|
|
|
|
} ngx_rtmp_conf_ctx_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
u_char sockaddr[NGX_SOCKADDRLEN];
|
|
|
|
socklen_t socklen;
|
|
|
|
|
|
|
|
/* server ctx */
|
|
|
|
ngx_rtmp_conf_ctx_t *ctx;
|
|
|
|
|
|
|
|
unsigned bind:1;
|
|
|
|
unsigned wildcard:1;
|
|
|
|
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
|
|
|
|
unsigned ipv6only:2;
|
|
|
|
#endif
|
|
|
|
unsigned so_keepalive:2;
|
|
|
|
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
|
|
|
|
int tcp_keepidle;
|
|
|
|
int tcp_keepintvl;
|
|
|
|
int tcp_keepcnt;
|
|
|
|
#endif
|
|
|
|
} ngx_rtmp_listen_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
ngx_rtmp_conf_ctx_t *ctx;
|
|
|
|
ngx_str_t addr_text;
|
|
|
|
} ngx_rtmp_addr_conf_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
in_addr_t addr;
|
|
|
|
ngx_rtmp_addr_conf_t conf;
|
|
|
|
} ngx_rtmp_in_addr_t;
|
|
|
|
|
|
|
|
|
|
|
|
#if (NGX_HAVE_INET6)
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
struct in6_addr addr6;
|
|
|
|
ngx_rtmp_addr_conf_t conf;
|
|
|
|
} ngx_rtmp_in6_addr_t;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
void *addrs;
|
|
|
|
ngx_uint_t naddrs;
|
|
|
|
} ngx_rtmp_port_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int family;
|
|
|
|
in_port_t port;
|
|
|
|
ngx_array_t addrs; /* array of ngx_rtmp_conf_addr_t */
|
|
|
|
} ngx_rtmp_conf_port_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
struct sockaddr *sockaddr;
|
|
|
|
socklen_t socklen;
|
|
|
|
|
|
|
|
ngx_rtmp_conf_ctx_t *ctx;
|
|
|
|
|
|
|
|
unsigned bind:1;
|
|
|
|
unsigned wildcard:1;
|
|
|
|
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
|
|
|
|
unsigned ipv6only:2;
|
|
|
|
#endif
|
|
|
|
unsigned so_keepalive:2;
|
|
|
|
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
|
|
|
|
int tcp_keepidle;
|
|
|
|
int tcp_keepintvl;
|
|
|
|
int tcp_keepcnt;
|
|
|
|
#endif
|
|
|
|
} ngx_rtmp_conf_addr_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
2012-03-09 22:49:09 +01:00
|
|
|
ngx_array_t servers; /* ngx_rtmp_core_srv_conf_t */
|
|
|
|
ngx_array_t listen; /* ngx_rtmp_listen_t */
|
2012-03-08 16:21:22 +01:00
|
|
|
} ngx_rtmp_core_main_conf_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
2012-03-09 22:49:09 +01:00
|
|
|
uint32_t csid; /* chunk stream id */
|
|
|
|
uint32_t timestamp;
|
|
|
|
uint32_t mlen; /* message length */
|
|
|
|
uint8_t type; /* message type id */
|
|
|
|
uint32_t msid; /* message stream id */
|
2012-03-08 16:21:22 +01:00
|
|
|
} ngx_rtmp_packet_hdr_t;
|
|
|
|
|
|
|
|
|
|
|
|
#define NGX_RTMP_PUBLISHER 0x01
|
|
|
|
#define NGX_RTMP_SUBSCRIBER 0x02
|
|
|
|
|
|
|
|
|
2012-03-11 17:17:17 +01:00
|
|
|
typedef struct ngx_rtmp_stream_t {
|
|
|
|
ngx_rtmp_packet_hdr_t hdr;
|
|
|
|
ngx_chain_t *in;
|
|
|
|
} ngx_rtmp_stream_t;
|
|
|
|
|
|
|
|
|
2012-03-08 18:45:10 +01:00
|
|
|
struct ngx_rtmp_session_s {
|
2012-03-08 16:21:22 +01:00
|
|
|
uint32_t signature; /* "RTMP" */
|
|
|
|
|
|
|
|
ngx_connection_t *connection;
|
|
|
|
|
|
|
|
void **ctx;
|
|
|
|
void **main_conf;
|
|
|
|
void **srv_conf;
|
|
|
|
|
2012-03-08 18:45:10 +01:00
|
|
|
ngx_str_t *addr_text;
|
|
|
|
|
2012-03-08 16:21:22 +01:00
|
|
|
ngx_chain_t *free;
|
|
|
|
|
|
|
|
/* handshake */
|
|
|
|
ngx_buf_t buf;
|
|
|
|
ngx_uint_t hs_stage;
|
|
|
|
|
2012-03-11 17:17:17 +01:00
|
|
|
/* input
|
|
|
|
* stream 0 (reserved by RTMP spec)
|
|
|
|
* used for free chain link (0) */
|
|
|
|
ngx_rtmp_stream_t *streams;
|
|
|
|
uint32_t in_csid;
|
|
|
|
ngx_uint_t in_chunk_size;
|
|
|
|
ngx_pool_t *in_pool;
|
2012-03-08 16:21:22 +01:00
|
|
|
|
|
|
|
/* output */
|
|
|
|
ngx_chain_t *out;
|
|
|
|
ngx_rtmp_packet_hdr_t out_hdr;
|
|
|
|
|
|
|
|
/* broadcast */
|
2012-03-08 18:45:10 +01:00
|
|
|
ngx_str_t name;
|
|
|
|
struct ngx_rtmp_session_s
|
|
|
|
*next;
|
2012-03-08 16:21:22 +01:00
|
|
|
ngx_uint_t flags;
|
2012-03-09 22:49:09 +01:00
|
|
|
uint32_t csid;
|
2012-03-08 18:45:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct ngx_rtmp_session_s ngx_rtmp_session_t;
|
2012-03-08 16:21:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
#define NGX_RTMP_SESSION_HASH_SIZE 16384
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
ngx_msec_t timeout;
|
|
|
|
ngx_flag_t so_keepalive;
|
2012-03-11 17:17:17 +01:00
|
|
|
/*ngx_int_t buffers;*/
|
|
|
|
ngx_int_t max_streams;
|
2012-03-08 16:21:22 +01:00
|
|
|
ngx_msec_t resolver_timeout;
|
|
|
|
ngx_resolver_t *resolver;
|
|
|
|
ngx_rtmp_conf_ctx_t *ctx;
|
|
|
|
ngx_rtmp_session_t **sessions; /* session hash map: name->session */
|
|
|
|
} ngx_rtmp_core_srv_conf_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
ngx_str_t *client;
|
|
|
|
ngx_rtmp_session_t *session;
|
|
|
|
} ngx_rtmp_log_ctx_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
void *(*create_main_conf)(ngx_conf_t *cf);
|
|
|
|
char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
|
|
|
|
|
|
|
|
void *(*create_srv_conf)(ngx_conf_t *cf);
|
|
|
|
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
|
|
|
|
void *conf);
|
|
|
|
} ngx_rtmp_module_t;
|
|
|
|
|
|
|
|
|
2012-03-09 22:49:09 +01:00
|
|
|
/* Chunk header:
|
|
|
|
* max 3 basic header
|
|
|
|
* + max 11 message header
|
|
|
|
* + max 4 extended header (timestamp) */
|
|
|
|
#define NGX_RTMP_MAX_CHUNK_HEADER 18
|
|
|
|
|
|
|
|
|
2012-03-08 16:21:22 +01:00
|
|
|
/* RTMP packet types*/
|
2012-03-09 22:49:09 +01:00
|
|
|
#define NGX_RTMP_PACKET_CHUNK_SIZE 1
|
|
|
|
#define NGX_RTMP_PACKET_ABORT 2
|
|
|
|
#define NGX_RTMP_PACKET_ACK 3
|
|
|
|
#define NGX_RTMP_PACKET_CTL 4
|
|
|
|
#define NGX_RTMP_PACKET_ACK_SIZE 5
|
|
|
|
#define NGX_RTMP_PACKET_BANDWIDTH 6
|
|
|
|
#define NGX_RTMP_PACKET_EDGE 7
|
|
|
|
#define NGX_RTMP_PACKET_AUDIO 8
|
|
|
|
#define NGX_RTMP_PACKET_VIDEO 9
|
|
|
|
#define NGX_RTMP_PACKET_AMF3_META 15
|
|
|
|
#define NGX_RTMP_PACKET_AMF3_SHARED 16
|
|
|
|
#define NGX_RTMP_PACKET_AMF3_CMD 17
|
|
|
|
#define NGX_RTMP_PACKET_AMF0_META 18
|
|
|
|
#define NGX_RTMP_PACKET_AMF0_SHARED 19
|
|
|
|
#define NGX_RTMP_PACKET_AMF0_CMD 20
|
|
|
|
#define NGX_RTMP_PACKET_AGGREGATE 22
|
|
|
|
|
|
|
|
|
|
|
|
/* RMTP control message types */
|
|
|
|
#define NGX_RTMP_CTL_STREAM_BEGIN 0
|
|
|
|
#define NGX_RTMP_CTL_STREAM_EOF 1
|
|
|
|
#define NGX_RTMP_CTL_STREAM_DRY 2
|
|
|
|
#define NGX_RTMP_CTL_SET_BUFLEN 3
|
|
|
|
#define NGX_RTMP_CTL_RECORDED 4
|
|
|
|
#define NGX_RTMP_CTL_PING_REQUEST 6
|
|
|
|
#define NGX_RTMP_CTL_PING_RESPONSE 7
|
2012-03-08 16:21:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
#define NGX_RTMP_MODULE 0x504D5452 /* "RTMP" */
|
|
|
|
|
|
|
|
#define NGX_RTMP_MAIN_CONF 0x02000000
|
|
|
|
#define NGX_RTMP_SRV_CONF 0x04000000
|
|
|
|
|
|
|
|
|
|
|
|
#define NGX_RTMP_MAIN_CONF_OFFSET offsetof(ngx_rtmp_conf_ctx_t, main_conf)
|
|
|
|
#define NGX_RTMP_SRV_CONF_OFFSET offsetof(ngx_rtmp_conf_ctx_t, srv_conf)
|
|
|
|
|
|
|
|
|
|
|
|
#define ngx_rtmp_get_module_ctx(s, module) (s)->ctx[module.ctx_index]
|
|
|
|
#define ngx_rtmp_set_ctx(s, c, module) s->ctx[module.ctx_index] = c;
|
|
|
|
#define ngx_rtmp_delete_ctx(s, module) s->ctx[module.ctx_index] = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
#define ngx_rtmp_get_module_main_conf(s, module) \
|
|
|
|
(s)->main_conf[module.ctx_index]
|
|
|
|
#define ngx_rtmp_get_module_srv_conf(s, module) (s)->srv_conf[module.ctx_index]
|
|
|
|
|
|
|
|
#define ngx_rtmp_conf_get_module_main_conf(cf, module) \
|
|
|
|
((ngx_rtmp_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
|
|
|
|
#define ngx_rtmp_conf_get_module_srv_conf(cf, module) \
|
|
|
|
((ngx_rtmp_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
|
|
|
|
|
|
|
|
void ngx_rtmp_init_connection(ngx_connection_t *c);
|
|
|
|
void ngx_rtmp_close_session(ngx_rtmp_session_t *s);
|
|
|
|
u_char * ngx_rtmp_log_error(ngx_log_t *log, u_char *buf, size_t len);
|
|
|
|
|
|
|
|
void ngx_rtmp_set_chunk_size(ngx_rtmp_session_t *s, uint32_t chunk_size);
|
|
|
|
void ngx_rtmp_set_bytes_read(ngx_rtmp_session_t *s, uint32_t bytes_read);
|
|
|
|
void ngx_rtmp_set_client_buffer_time(ngx_rtmp_session_t *s, int16_t msec);
|
2012-03-08 18:45:10 +01:00
|
|
|
void ngx_rtmp_clear_buffer(ngx_rtmp_session_t *s);
|
2012-03-08 16:21:22 +01:00
|
|
|
void ngx_rtmp_set_ping_time(ngx_rtmp_session_t *s, int16_t msec);
|
|
|
|
void ngx_rtmp_set_server_bw(ngx_rtmp_session_t *s, uint32_t bw,
|
|
|
|
uint8_t limit_type);
|
|
|
|
void ngx_rtmp_set_client_bw(ngx_rtmp_session_t *s, uint32_t bw,
|
|
|
|
uint8_t limit_type);
|
|
|
|
|
|
|
|
void ngx_rtmp_join(ngx_rtmp_session_t *s, ngx_str_t *name, ngx_uint_t flags);
|
|
|
|
void ngx_rtmp_leave(ngx_rtmp_session_t *s);
|
|
|
|
|
|
|
|
ngx_int_t ngx_rtmp_receive_packet(ngx_rtmp_session_t *s,
|
|
|
|
ngx_rtmp_packet_hdr_t *h, ngx_chain_t *b);
|
|
|
|
|
|
|
|
void ngx_rtmp_send_packet(ngx_rtmp_session_t *s,
|
|
|
|
ngx_rtmp_packet_hdr_t *h, ngx_chain_t *b);
|
|
|
|
|
|
|
|
|
|
|
|
/* NetConnection methods */
|
2012-03-11 17:17:17 +01:00
|
|
|
ngx_int_t ngx_rtmp_connect(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_call(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_close(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_createstream(ngx_rtmp_session_t *s
|
|
|
|
double trans_id, , ngx_chain_t *l);
|
2012-03-08 16:21:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* NetStream methods */
|
2012-03-11 17:17:17 +01:00
|
|
|
ngx_int_t ngx_rtmp_play(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_play2(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_deletestream(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_closestream(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_receiveaudio(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_receivevideo(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_publish(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_seek(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
|
|
|
ngx_int_t ngx_rtmp_pause(ngx_rtmp_session_t *s,
|
|
|
|
double trans_id, ngx_chain_t *l);
|
2012-03-08 16:21:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
extern ngx_uint_t ngx_rtmp_max_module;
|
|
|
|
extern ngx_module_t ngx_rtmp_core_module;
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* _NGX_RTMP_H_INCLUDED_ */
|