2013-11-03 20:11:37 +01:00
|
|
|
|
2012-03-12 18:58:00 +01:00
|
|
|
/*
|
2013-11-03 20:11:37 +01:00
|
|
|
* Copyright (C) Roman Arutyunyan
|
2012-03-12 18:58:00 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2013-06-11 19:00:39 +02:00
|
|
|
#include <ngx_config.h>
|
|
|
|
#include <ngx_core.h>
|
2012-03-13 06:41:51 +01:00
|
|
|
#include "ngx_rtmp.h"
|
2012-03-29 14:10:11 +02:00
|
|
|
#include "ngx_rtmp_amf.h"
|
2012-08-24 18:46:40 +02:00
|
|
|
#include "ngx_rtmp_streams.h"
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2012-03-12 18:58:00 +01:00
|
|
|
|
2012-04-07 20:59:25 +02:00
|
|
|
#define NGX_RTMP_USER_START(s, tp) \
|
|
|
|
ngx_rtmp_header_t __h; \
|
|
|
|
ngx_chain_t *__l; \
|
|
|
|
ngx_buf_t *__b; \
|
|
|
|
ngx_rtmp_core_srv_conf_t *__cscf; \
|
|
|
|
\
|
|
|
|
__cscf = ngx_rtmp_get_module_srv_conf( \
|
|
|
|
s, ngx_rtmp_core_module); \
|
|
|
|
memset(&__h, 0, sizeof(__h)); \
|
|
|
|
__h.type = tp; \
|
|
|
|
__h.csid = 2; \
|
|
|
|
__l = ngx_rtmp_alloc_shared_buf(__cscf); \
|
|
|
|
if (__l == NULL) { \
|
2012-11-12 21:22:57 +01:00
|
|
|
return NULL; \
|
2012-04-07 20:59:25 +02:00
|
|
|
} \
|
2013-11-30 08:21:53 +01:00
|
|
|
__b = __l->buf;
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2012-04-07 20:59:25 +02:00
|
|
|
#define NGX_RTMP_UCTL_START(s, type, utype) \
|
|
|
|
NGX_RTMP_USER_START(s, type); \
|
|
|
|
*(__b->last++) = (u_char)((utype) >> 8); \
|
2012-03-13 06:41:51 +01:00
|
|
|
*(__b->last++) = (u_char)(utype);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2012-04-07 20:59:25 +02:00
|
|
|
#define NGX_RTMP_USER_OUT1(v) \
|
2012-03-13 06:41:51 +01:00
|
|
|
*(__b->last++) = ((u_char*)&v)[0];
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2012-04-07 20:59:25 +02:00
|
|
|
#define NGX_RTMP_USER_OUT4(v) \
|
|
|
|
*(__b->last++) = ((u_char*)&v)[3]; \
|
|
|
|
*(__b->last++) = ((u_char*)&v)[2]; \
|
|
|
|
*(__b->last++) = ((u_char*)&v)[1]; \
|
2012-03-13 06:41:51 +01:00
|
|
|
*(__b->last++) = ((u_char*)&v)[0];
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2012-04-07 20:59:25 +02:00
|
|
|
#define NGX_RTMP_USER_END(s) \
|
|
|
|
ngx_rtmp_prepare_message(s, &__h, NULL, __l); \
|
2012-11-12 21:22:57 +01:00
|
|
|
return __l;
|
|
|
|
|
|
|
|
|
|
|
|
static ngx_int_t
|
|
|
|
ngx_rtmp_send_shared_packet(ngx_rtmp_session_t *s, ngx_chain_t *cl)
|
|
|
|
{
|
|
|
|
ngx_rtmp_core_srv_conf_t *cscf;
|
|
|
|
ngx_int_t rc;
|
|
|
|
|
|
|
|
if (cl == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
|
|
|
|
|
|
|
rc = ngx_rtmp_send_message(s, cl, 0);
|
|
|
|
|
|
|
|
ngx_rtmp_free_shared_chain(cscf, cl);
|
|
|
|
|
2012-04-07 20:59:25 +02:00
|
|
|
return rc;
|
2012-11-12 21:22:57 +01:00
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* Protocol control messages */
|
2012-11-12 21:22:57 +01:00
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_chunk_size(ngx_rtmp_session_t *s, uint32_t chunk_size)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-05-21 17:34:07 +02:00
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
2012-11-12 21:22:57 +01:00
|
|
|
"chunk_size=%uD", chunk_size);
|
2012-05-21 17:34:07 +02:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_USER_START(s, NGX_RTMP_MSG_CHUNK_SIZE);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(chunk_size);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_chunk_size(ngx_rtmp_session_t *s, uint32_t chunk_size)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_chunk_size(s, chunk_size));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_abort(ngx_rtmp_session_t *s, uint32_t csid)
|
|
|
|
{
|
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: abort csid=%uD", csid);
|
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_USER_START(s, NGX_RTMP_MSG_CHUNK_SIZE);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(csid);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_abort(ngx_rtmp_session_t *s, uint32_t csid)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_abort(s, csid));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_ack(ngx_rtmp_session_t *s, uint32_t seq)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-05-21 17:34:07 +02:00
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
2012-11-12 21:22:57 +01:00
|
|
|
"create: ack seq=%uD", seq);
|
2012-05-21 17:34:07 +02:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_USER_START(s, NGX_RTMP_MSG_ACK);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(seq);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_ack(ngx_rtmp_session_t *s, uint32_t seq)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_ack(s, seq));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_ack_size(ngx_rtmp_session_t *s, uint32_t ack_size)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-05-21 17:34:07 +02:00
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
2012-11-12 21:22:57 +01:00
|
|
|
"create: ack_size=%uD", ack_size);
|
2012-05-21 17:34:07 +02:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_USER_START(s, NGX_RTMP_MSG_ACK_SIZE);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(ack_size);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_ack_size(ngx_rtmp_session_t *s, uint32_t ack_size)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_ack_size(s, ack_size));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_bandwidth(ngx_rtmp_session_t *s, uint32_t ack_size,
|
|
|
|
uint8_t limit_type)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-05-21 17:34:07 +02:00
|
|
|
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
2013-11-30 08:21:53 +01:00
|
|
|
"create: bandwidth ack_size=%uD limit=%d",
|
2012-11-12 21:22:57 +01:00
|
|
|
ack_size, (int)limit_type);
|
2012-05-21 17:34:07 +02:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_USER_START(s, NGX_RTMP_MSG_BANDWIDTH);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(ack_size);
|
|
|
|
NGX_RTMP_USER_OUT1(limit_type);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_bandwidth(ngx_rtmp_session_t *s, uint32_t ack_size,
|
|
|
|
uint8_t limit_type)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_bandwidth(s, ack_size, limit_type));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* User control messages */
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_stream_begin(ngx_rtmp_session_t *s, uint32_t msid)
|
|
|
|
{
|
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: stream_begin msid=%uD", msid);
|
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_UCTL_START(s, NGX_RTMP_MSG_USER, NGX_RTMP_USER_STREAM_BEGIN);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(msid);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_stream_begin(ngx_rtmp_session_t *s, uint32_t msid)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_stream_begin(s, msid));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_stream_eof(ngx_rtmp_session_t *s, uint32_t msid)
|
|
|
|
{
|
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: stream_end msid=%uD", msid);
|
2013-11-30 08:21:53 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_UCTL_START(s, NGX_RTMP_MSG_USER, NGX_RTMP_USER_STREAM_EOF);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(msid);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_stream_eof(ngx_rtmp_session_t *s, uint32_t msid)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_stream_eof(s, msid));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_stream_dry(ngx_rtmp_session_t *s, uint32_t msid)
|
|
|
|
{
|
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: stream_dry msid=%uD", msid);
|
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_UCTL_START(s, NGX_RTMP_MSG_USER, NGX_RTMP_USER_STREAM_DRY);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(msid);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_stream_dry(ngx_rtmp_session_t *s, uint32_t msid)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_stream_dry(s, msid));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_rtmp_create_set_buflen(ngx_rtmp_session_t *s, uint32_t msid,
|
2012-11-12 21:22:57 +01:00
|
|
|
uint32_t buflen_msec)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: set_buflen msid=%uD buflen=%uD",
|
|
|
|
msid, buflen_msec);
|
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_UCTL_START(s, NGX_RTMP_MSG_USER, NGX_RTMP_USER_SET_BUFLEN);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(msid);
|
|
|
|
NGX_RTMP_USER_OUT4(buflen_msec);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_rtmp_send_set_buflen(ngx_rtmp_session_t *s, uint32_t msid,
|
2012-11-12 21:22:57 +01:00
|
|
|
uint32_t buflen_msec)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_set_buflen(s, msid, buflen_msec));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_rtmp_create_recorded(ngx_rtmp_session_t *s, uint32_t msid)
|
2012-11-12 21:22:57 +01:00
|
|
|
{
|
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: recorded msid=%uD", msid);
|
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_UCTL_START(s, NGX_RTMP_MSG_USER, NGX_RTMP_USER_RECORDED);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(msid);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_rtmp_send_recorded(ngx_rtmp_session_t *s, uint32_t msid)
|
2012-11-12 21:22:57 +01:00
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_recorded(s, msid));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_rtmp_create_ping_request(ngx_rtmp_session_t *s, uint32_t timestamp)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: ping_request timestamp=%uD", timestamp);
|
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_UCTL_START(s, NGX_RTMP_MSG_USER, NGX_RTMP_USER_PING_REQUEST);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(timestamp);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_rtmp_send_ping_request(ngx_rtmp_session_t *s, uint32_t timestamp)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_ping_request(s, timestamp));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_rtmp_create_ping_response(ngx_rtmp_session_t *s, uint32_t timestamp)
|
2012-11-12 21:22:57 +01:00
|
|
|
{
|
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: ping_response timestamp=%uD", timestamp);
|
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
{
|
|
|
|
NGX_RTMP_UCTL_START(s, NGX_RTMP_MSG_USER, NGX_RTMP_USER_PING_RESPONSE);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_OUT4(timestamp);
|
2012-03-12 00:44:58 +01:00
|
|
|
|
2013-06-11 20:19:05 +02:00
|
|
|
NGX_RTMP_USER_END(s);
|
|
|
|
}
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
2012-03-13 06:41:51 +01:00
|
|
|
|
2012-03-17 23:16:59 +01:00
|
|
|
ngx_int_t
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_rtmp_send_ping_response(ngx_rtmp_session_t *s, uint32_t timestamp)
|
2012-03-17 23:16:59 +01:00
|
|
|
{
|
2012-11-12 21:22:57 +01:00
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_ping_response(s, timestamp));
|
2012-03-17 23:16:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
static ngx_chain_t *
|
2012-03-30 17:07:14 +02:00
|
|
|
ngx_rtmp_alloc_amf_buf(void *arg)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_alloc_shared_buf((ngx_rtmp_core_srv_conf_t *)arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-29 14:10:11 +02:00
|
|
|
/* AMF sender */
|
2012-04-06 15:49:30 +02:00
|
|
|
|
|
|
|
/* NOTE: this function does not free shared bufs on error */
|
|
|
|
ngx_int_t
|
2012-05-24 10:21:07 +02:00
|
|
|
ngx_rtmp_append_amf(ngx_rtmp_session_t *s,
|
2013-11-30 08:21:53 +01:00
|
|
|
ngx_chain_t **first, ngx_chain_t **last,
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_amf_elt_t *elts, size_t nelts)
|
2012-03-12 00:44:58 +01:00
|
|
|
{
|
2012-03-29 14:10:11 +02:00
|
|
|
ngx_rtmp_amf_ctx_t act;
|
2012-03-17 07:12:19 +01:00
|
|
|
ngx_rtmp_core_srv_conf_t *cscf;
|
2012-04-06 15:49:30 +02:00
|
|
|
ngx_int_t rc;
|
2012-03-17 07:12:19 +01:00
|
|
|
|
|
|
|
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
2012-03-13 06:41:51 +01:00
|
|
|
|
|
|
|
memset(&act, 0, sizeof(act));
|
2012-03-30 17:07:14 +02:00
|
|
|
act.arg = cscf;
|
|
|
|
act.alloc = ngx_rtmp_alloc_amf_buf;
|
2012-03-13 06:41:51 +01:00
|
|
|
act.log = s->connection->log;
|
|
|
|
|
2012-04-06 15:49:30 +02:00
|
|
|
if (first) {
|
|
|
|
act.first = *first;
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
2012-04-06 15:49:30 +02:00
|
|
|
if (last) {
|
|
|
|
act.link = *last;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = ngx_rtmp_amf_write(&act, elts, nelts);
|
|
|
|
|
|
|
|
if (first) {
|
|
|
|
*first = act.first;
|
2012-03-13 06:41:51 +01:00
|
|
|
}
|
|
|
|
|
2012-04-06 14:13:48 +02:00
|
|
|
if (last) {
|
|
|
|
*last = act.link;
|
|
|
|
}
|
|
|
|
|
2012-04-06 15:49:30 +02:00
|
|
|
return rc;
|
2012-04-05 12:58:10 +02:00
|
|
|
}
|
|
|
|
|
2012-08-24 18:46:40 +02:00
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_amf(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|
|
|
ngx_rtmp_amf_elt_t *elts, size_t nelts)
|
2012-04-05 12:58:10 +02:00
|
|
|
{
|
2012-04-06 15:49:30 +02:00
|
|
|
ngx_chain_t *first;
|
2012-04-05 12:58:10 +02:00
|
|
|
ngx_int_t rc;
|
|
|
|
ngx_rtmp_core_srv_conf_t *cscf;
|
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: amf nelts=%ui", nelts);
|
|
|
|
|
2012-04-05 12:58:10 +02:00
|
|
|
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
|
|
|
|
2012-04-06 15:49:30 +02:00
|
|
|
first = NULL;
|
2012-11-12 21:22:57 +01:00
|
|
|
|
2012-05-24 10:21:07 +02:00
|
|
|
rc = ngx_rtmp_append_amf(s, &first, NULL, elts, nelts);
|
2012-11-12 21:22:57 +01:00
|
|
|
|
|
|
|
if (rc != NGX_OK && first) {
|
|
|
|
ngx_rtmp_free_shared_chain(cscf, first);
|
|
|
|
first = NULL;
|
2012-04-05 12:58:10 +02:00
|
|
|
}
|
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
if (first) {
|
|
|
|
ngx_rtmp_prepare_message(s, h, NULL, first);
|
|
|
|
}
|
2012-04-06 15:49:30 +02:00
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
return first;
|
|
|
|
}
|
2012-04-05 12:58:10 +02:00
|
|
|
|
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_int_t
|
|
|
|
ngx_rtmp_send_amf(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|
|
|
ngx_rtmp_amf_elt_t *elts, size_t nelts)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_amf(s, h, elts, nelts));
|
2012-03-12 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
2012-08-24 18:46:40 +02:00
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_status(ngx_rtmp_session_t *s, char *code, char* level,
|
|
|
|
char *desc)
|
2012-08-24 18:46:40 +02:00
|
|
|
{
|
|
|
|
ngx_rtmp_header_t h;
|
|
|
|
static double trans;
|
|
|
|
|
|
|
|
static ngx_rtmp_amf_elt_t out_inf[] = {
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2012-12-26 11:28:31 +01:00
|
|
|
ngx_string("level"),
|
2012-08-24 18:46:40 +02:00
|
|
|
NULL, 0 },
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2012-12-26 11:28:31 +01:00
|
|
|
ngx_string("code"),
|
2012-08-24 18:46:40 +02:00
|
|
|
NULL, 0 },
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2012-08-24 18:46:40 +02:00
|
|
|
ngx_string("description"),
|
|
|
|
NULL, 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
static ngx_rtmp_amf_elt_t out_elts[] = {
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2012-08-24 18:46:40 +02:00
|
|
|
ngx_null_string,
|
|
|
|
"onStatus", 0 },
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_NUMBER,
|
2012-08-24 18:46:40 +02:00
|
|
|
ngx_null_string,
|
|
|
|
&trans, 0 },
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_NULL,
|
|
|
|
ngx_null_string,
|
|
|
|
NULL, 0 },
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_OBJECT,
|
2015-08-01 18:30:01 +02:00
|
|
|
ngx_null_string,
|
2012-08-24 18:46:40 +02:00
|
|
|
out_inf,
|
|
|
|
sizeof(out_inf) },
|
|
|
|
};
|
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: status code='%s' level='%s' desc='%s'",
|
|
|
|
code, level, desc);
|
2012-08-24 18:46:40 +02:00
|
|
|
|
2012-12-26 12:06:55 +01:00
|
|
|
out_inf[0].data = level;
|
|
|
|
out_inf[1].data = code;
|
2012-08-24 18:46:40 +02:00
|
|
|
out_inf[2].data = desc;
|
2015-08-01 18:30:01 +02:00
|
|
|
trans = 0;
|
2012-08-24 18:46:40 +02:00
|
|
|
|
|
|
|
memset(&h, 0, sizeof(h));
|
|
|
|
|
|
|
|
h.type = NGX_RTMP_MSG_AMF_CMD;
|
|
|
|
h.csid = NGX_RTMP_CSID_AMF;
|
|
|
|
h.msid = NGX_RTMP_MSID;
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
return ngx_rtmp_create_amf(s, &h, out_elts,
|
2012-11-12 21:22:57 +01:00
|
|
|
sizeof(out_elts) / sizeof(out_elts[0]));
|
2012-08-24 18:46:40 +02:00
|
|
|
}
|
2012-10-05 08:11:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_rtmp_send_status(ngx_rtmp_session_t *s, char *code, char* level, char *desc)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_status(s, code, level, desc));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_play_status(ngx_rtmp_session_t *s, char *code, char* level,
|
|
|
|
ngx_uint_t duration, ngx_uint_t bytes)
|
2012-10-05 08:11:30 +02:00
|
|
|
{
|
|
|
|
ngx_rtmp_header_t h;
|
|
|
|
static double dduration;
|
|
|
|
static double dbytes;
|
|
|
|
|
|
|
|
static ngx_rtmp_amf_elt_t out_inf[] = {
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2012-10-05 08:11:30 +02:00
|
|
|
ngx_string("code"),
|
|
|
|
NULL, 0 },
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2012-10-05 08:11:30 +02:00
|
|
|
ngx_string("level"),
|
|
|
|
NULL, 0 },
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_NUMBER,
|
2012-10-05 08:11:30 +02:00
|
|
|
ngx_string("duration"),
|
|
|
|
&dduration, 0 },
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_NUMBER,
|
2012-10-05 08:11:30 +02:00
|
|
|
ngx_string("bytes"),
|
|
|
|
&dbytes, 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
static ngx_rtmp_amf_elt_t out_elts[] = {
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2012-10-05 08:11:30 +02:00
|
|
|
ngx_null_string,
|
|
|
|
"onPlayStatus", 0 },
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_OBJECT,
|
|
|
|
ngx_null_string,
|
|
|
|
out_inf,
|
|
|
|
sizeof(out_inf) },
|
|
|
|
};
|
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
|
|
"create: play_status code='%s' level='%s' "
|
|
|
|
"duration=%ui bytes=%ui",
|
|
|
|
code, level, duration, bytes);
|
2012-10-05 08:11:30 +02:00
|
|
|
|
|
|
|
out_inf[0].data = code;
|
|
|
|
out_inf[1].data = level;
|
|
|
|
|
|
|
|
dduration = duration;
|
|
|
|
dbytes = bytes;
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(h));
|
|
|
|
|
|
|
|
h.type = NGX_RTMP_MSG_AMF_META;
|
|
|
|
h.csid = NGX_RTMP_CSID_AMF;
|
|
|
|
h.msid = NGX_RTMP_MSID;
|
2012-10-05 13:36:05 +02:00
|
|
|
h.timestamp = duration;
|
2012-10-05 08:11:30 +02:00
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
return ngx_rtmp_create_amf(s, &h, out_elts,
|
2012-11-12 21:22:57 +01:00
|
|
|
sizeof(out_elts) / sizeof(out_elts[0]));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
|
|
|
ngx_rtmp_send_play_status(ngx_rtmp_session_t *s, char *code, char* level,
|
|
|
|
ngx_uint_t duration, ngx_uint_t bytes)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_play_status(s, code, level, duration, bytes));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-07-07 15:04:31 +02:00
|
|
|
// ----------- Based on Adobe FMS 3 application.redirectConnection description --------- //
|
|
|
|
|
|
|
|
ngx_chain_t *
|
2015-08-01 18:30:01 +02:00
|
|
|
ngx_rtmp_create_redirect_status(ngx_rtmp_session_t *s, char *callMethod, char *desc, ngx_str_t to_url)
|
2015-07-07 15:04:31 +02:00
|
|
|
{
|
|
|
|
ngx_rtmp_header_t h;
|
2015-08-01 18:30:01 +02:00
|
|
|
static double dtrans;
|
2015-08-01 03:50:38 +02:00
|
|
|
static double dcode;
|
2015-07-07 15:04:31 +02:00
|
|
|
|
2015-08-01 03:50:38 +02:00
|
|
|
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
|
|
|
|
"create redirect status: got data");
|
|
|
|
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
|
2015-08-01 18:30:01 +02:00
|
|
|
"create redirect status: method='%s', status code='%s' level='%s' "
|
|
|
|
"ex.code=%ui ex.redirect='%s'", callMethod,
|
|
|
|
"NetConnection.Connect.Rejected", "error", 302, to_url.data);
|
2015-07-07 15:04:31 +02:00
|
|
|
|
2015-08-01 03:50:38 +02:00
|
|
|
static ngx_rtmp_amf_elt_t out_inf_ex_data[] = {
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_NUMBER,
|
2015-07-07 15:04:31 +02:00
|
|
|
ngx_string("code"),
|
2015-08-01 03:50:38 +02:00
|
|
|
&dcode, 0 },
|
2015-07-07 15:04:31 +02:00
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_STRING,
|
|
|
|
ngx_string("redirect"),
|
|
|
|
NULL, 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
static ngx_rtmp_amf_elt_t out_inf[] = {
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2015-08-01 18:30:01 +02:00
|
|
|
ngx_string("level"),
|
|
|
|
"error", 0 },
|
2015-07-07 15:04:31 +02:00
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2015-08-01 18:30:01 +02:00
|
|
|
ngx_string("code"),
|
|
|
|
"NetConnection.Connect.Rejected", 0 },
|
2015-07-07 15:04:31 +02:00
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_STRING,
|
|
|
|
ngx_string("description"),
|
|
|
|
NULL, 0 },
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_OBJECT,
|
|
|
|
ngx_string("ex"),
|
2015-08-01 03:50:38 +02:00
|
|
|
out_inf_ex_data,
|
|
|
|
sizeof(out_inf_ex_data) },
|
2015-07-07 15:04:31 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static ngx_rtmp_amf_elt_t out_elts[] = {
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_STRING,
|
|
|
|
ngx_null_string,
|
2015-08-01 18:30:01 +02:00
|
|
|
NULL, 0 },
|
2015-07-07 15:04:31 +02:00
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_NUMBER,
|
|
|
|
ngx_null_string,
|
2015-08-01 18:30:01 +02:00
|
|
|
&dtrans, 0 },
|
2015-07-07 15:04:31 +02:00
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_NULL,
|
|
|
|
ngx_null_string,
|
|
|
|
NULL, 0 },
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_OBJECT,
|
2015-08-01 18:30:01 +02:00
|
|
|
ngx_null_string,
|
2015-07-07 15:04:31 +02:00
|
|
|
out_inf,
|
|
|
|
sizeof(out_inf) },
|
|
|
|
};
|
|
|
|
|
2015-08-01 03:50:38 +02:00
|
|
|
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
|
|
|
|
"create redirect status: set structure data");
|
2015-07-07 15:04:31 +02:00
|
|
|
|
2015-08-01 18:30:01 +02:00
|
|
|
out_elts[0].data = callMethod;
|
2015-07-07 15:04:31 +02:00
|
|
|
out_inf[2].data = desc;
|
2015-08-01 03:50:38 +02:00
|
|
|
dcode = 302;
|
2015-08-01 18:30:01 +02:00
|
|
|
dtrans = 0;
|
2015-08-01 03:50:38 +02:00
|
|
|
out_inf_ex_data[1].data = to_url.data;
|
2015-07-07 15:04:31 +02:00
|
|
|
|
2015-08-01 18:30:01 +02:00
|
|
|
ngx_memzero(&h, sizeof(h));
|
2015-07-07 15:04:31 +02:00
|
|
|
|
2015-08-01 18:30:01 +02:00
|
|
|
h.type = NGX_RTMP_MSG_AMF_CMD;
|
2015-07-07 15:04:31 +02:00
|
|
|
h.csid = NGX_RTMP_CSID_AMF;
|
|
|
|
h.msid = NGX_RTMP_MSID;
|
|
|
|
|
|
|
|
return ngx_rtmp_create_amf(s, &h, out_elts,
|
|
|
|
sizeof(out_elts) / sizeof(out_elts[0]));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
|
|
|
ngx_rtmp_send_redirect_status(ngx_rtmp_session_t *s,
|
2015-08-01 18:30:01 +02:00
|
|
|
char *callMethod, char *desc, ngx_str_t to_url)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_redirect_status(s, callMethod, desc, to_url));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_close_method(ngx_rtmp_session_t *s, char *methodName)
|
|
|
|
{
|
|
|
|
ngx_rtmp_header_t h;
|
|
|
|
static double dtrans;
|
|
|
|
|
|
|
|
static ngx_rtmp_amf_elt_t out_elts[] = {
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_STRING,
|
|
|
|
ngx_null_string,
|
|
|
|
NULL, 0 },
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_NUMBER,
|
|
|
|
ngx_null_string,
|
|
|
|
&dtrans, 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
|
|
|
|
"create close method: set structure data");
|
|
|
|
|
|
|
|
out_elts[0].data = methodName;
|
|
|
|
dtrans = 0;
|
|
|
|
|
|
|
|
ngx_memzero(&h, sizeof(h));
|
|
|
|
|
|
|
|
h.type = NGX_RTMP_MSG_AMF_CMD;
|
|
|
|
h.csid = NGX_RTMP_CSID_AMF;
|
|
|
|
h.msid = NGX_RTMP_MSID;
|
|
|
|
|
|
|
|
return ngx_rtmp_create_amf(s, &h, out_elts,
|
|
|
|
sizeof(out_elts) / sizeof(out_elts[0]));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
|
|
|
ngx_rtmp_send_close_method(ngx_rtmp_session_t *s, char *methodName)
|
2015-07-07 15:04:31 +02:00
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
2015-08-01 18:30:01 +02:00
|
|
|
ngx_rtmp_create_close_method(s, methodName));
|
2015-07-07 15:04:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_chain_t *
|
|
|
|
ngx_rtmp_create_sample_access(ngx_rtmp_session_t *s)
|
|
|
|
{
|
|
|
|
ngx_rtmp_header_t h;
|
|
|
|
|
|
|
|
static int access = 1;
|
|
|
|
|
|
|
|
static ngx_rtmp_amf_elt_t access_elts[] = {
|
|
|
|
|
2013-11-30 08:21:53 +01:00
|
|
|
{ NGX_RTMP_AMF_STRING,
|
2012-11-12 21:22:57 +01:00
|
|
|
ngx_null_string,
|
|
|
|
"|RtmpSampleAccess", 0 },
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_BOOLEAN,
|
|
|
|
ngx_null_string,
|
|
|
|
&access, 0 },
|
|
|
|
|
|
|
|
{ NGX_RTMP_AMF_BOOLEAN,
|
|
|
|
ngx_null_string,
|
|
|
|
&access, 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(h));
|
|
|
|
|
|
|
|
h.type = NGX_RTMP_MSG_AMF_META;
|
|
|
|
h.csid = NGX_RTMP_CSID_AMF;
|
|
|
|
h.msid = NGX_RTMP_MSID;
|
|
|
|
|
|
|
|
return ngx_rtmp_create_amf(s, &h, access_elts,
|
|
|
|
sizeof(access_elts) / sizeof(access_elts[0]));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
|
|
|
ngx_rtmp_send_sample_access(ngx_rtmp_session_t *s)
|
|
|
|
{
|
|
|
|
return ngx_rtmp_send_shared_packet(s,
|
|
|
|
ngx_rtmp_create_sample_access(s));
|
2012-10-05 08:11:30 +02:00
|
|
|
}
|