mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-05-20 18:01:08 +02:00
added support for multiple aac/avc codecs per stream
This commit is contained in:
parent
c377e3b5c6
commit
266e206afc
|
@ -11,6 +11,11 @@
|
||||||
static ngx_int_t ngx_rtmp_codec_postconfiguration(ngx_conf_t *cf);
|
static ngx_int_t ngx_rtmp_codec_postconfiguration(ngx_conf_t *cf);
|
||||||
|
|
||||||
|
|
||||||
|
/* Global header version is used to identify
|
||||||
|
* incoming AAC/AVC header */
|
||||||
|
static ngx_uint_t header_version;
|
||||||
|
|
||||||
|
|
||||||
static ngx_rtmp_module_t ngx_rtmp_codec_module_ctx = {
|
static ngx_rtmp_module_t ngx_rtmp_codec_module_ctx = {
|
||||||
NULL, /* preconfiguration */
|
NULL, /* preconfiguration */
|
||||||
ngx_rtmp_codec_postconfiguration, /* postconfiguration */
|
ngx_rtmp_codec_postconfiguration, /* postconfiguration */
|
||||||
|
@ -139,6 +144,7 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_chain_t **header, **pheader;
|
ngx_chain_t **header, **pheader;
|
||||||
uint8_t fmt;
|
uint8_t fmt;
|
||||||
ngx_rtmp_header_t ch, lh;
|
ngx_rtmp_header_t ch, lh;
|
||||||
|
ngx_uint_t *version;
|
||||||
|
|
||||||
/* save AVC/AAC header */
|
/* save AVC/AAC header */
|
||||||
if ((h->type != NGX_RTMP_MSG_AUDIO
|
if ((h->type != NGX_RTMP_MSG_AUDIO
|
||||||
|
@ -166,6 +172,7 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
if (((fmt & 0xf0) >> 4) == NGX_RTMP_AUDIO_AAC) {
|
if (((fmt & 0xf0) >> 4) == NGX_RTMP_AUDIO_AAC) {
|
||||||
header = &ctx->aac_header;
|
header = &ctx->aac_header;
|
||||||
pheader = &ctx->aac_pheader;
|
pheader = &ctx->aac_pheader;
|
||||||
|
version = &ctx->aac_version;
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"codec: AAC header arrived");
|
"codec: AAC header arrived");
|
||||||
}
|
}
|
||||||
|
@ -173,6 +180,7 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
if ((fmt & 0x0f) == NGX_RTMP_VIDEO_H264) {
|
if ((fmt & 0x0f) == NGX_RTMP_VIDEO_H264) {
|
||||||
header = &ctx->avc_header;
|
header = &ctx->avc_header;
|
||||||
pheader = &ctx->avc_pheader;
|
pheader = &ctx->avc_pheader;
|
||||||
|
version = &ctx->avc_version;
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"codec: AVC/H264 header arrived");
|
"codec: AVC/H264 header arrived");
|
||||||
}
|
}
|
||||||
|
@ -204,6 +212,11 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
*pheader = ngx_rtmp_append_shared_bufs(cscf, NULL, in);
|
*pheader = ngx_rtmp_append_shared_bufs(cscf, NULL, in);
|
||||||
ngx_rtmp_prepare_message(s, &ch, &lh, *pheader);
|
ngx_rtmp_prepare_message(s, &ch, &lh, *pheader);
|
||||||
|
|
||||||
|
/* don't want zero as version value */
|
||||||
|
do {
|
||||||
|
*version = ++header_version;
|
||||||
|
} while (*version == 0);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@ u_char * ngx_rtmp_get_video_codec_name(ngx_uint_t id);
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
ngx_uint_t avc_version;
|
||||||
|
ngx_uint_t aac_version;
|
||||||
|
|
||||||
ngx_chain_t *avc_header;
|
ngx_chain_t *avc_header;
|
||||||
ngx_chain_t *aac_header;
|
ngx_chain_t *aac_header;
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,7 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
{
|
{
|
||||||
ngx_rtmp_live_ctx_t *ctx, *pctx;
|
ngx_rtmp_live_ctx_t *ctx, *pctx;
|
||||||
ngx_rtmp_codec_ctx_t *codec_ctx;
|
ngx_rtmp_codec_ctx_t *codec_ctx;
|
||||||
ngx_chain_t *out, *peer_out;
|
ngx_chain_t *out, *peer_out, *header_out;
|
||||||
ngx_rtmp_core_srv_conf_t *cscf;
|
ngx_rtmp_core_srv_conf_t *cscf;
|
||||||
ngx_rtmp_live_app_conf_t *lacf;
|
ngx_rtmp_live_app_conf_t *lacf;
|
||||||
ngx_rtmp_session_t *ss;
|
ngx_rtmp_session_t *ss;
|
||||||
|
@ -291,6 +291,8 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_uint_t prio, peer_prio;
|
ngx_uint_t prio, peer_prio;
|
||||||
ngx_uint_t peers, dropped_peers;
|
ngx_uint_t peers, dropped_peers;
|
||||||
uint8_t flv_fmt;
|
uint8_t flv_fmt;
|
||||||
|
size_t header_offset;
|
||||||
|
ngx_uint_t header_version;
|
||||||
|
|
||||||
lacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_live_module);
|
lacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_live_module);
|
||||||
if (lacf == NULL) {
|
if (lacf == NULL) {
|
||||||
|
@ -358,6 +360,27 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||||
|
header_out = NULL;
|
||||||
|
header_offset = 0;
|
||||||
|
header_version = 0;
|
||||||
|
if (codec_ctx) {
|
||||||
|
peer_out = NULL;
|
||||||
|
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
||||||
|
if (codec_ctx->aac_pheader) {
|
||||||
|
header_out = codec_ctx->aac_pheader;
|
||||||
|
header_offset = offsetof(ngx_rtmp_live_ctx_t, aac_version);
|
||||||
|
header_version = codec_ctx->aac_version;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (codec_ctx->avc_pheader) {
|
||||||
|
header_out = codec_ctx->avc_pheader;
|
||||||
|
header_offset = offsetof(ngx_rtmp_live_ctx_t, avc_version);
|
||||||
|
header_version = codec_ctx->avc_version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* broadcast to all subscribers */
|
/* broadcast to all subscribers */
|
||||||
for (pctx = ctx->stream->ctx; pctx; pctx = pctx->next) {
|
for (pctx = ctx->stream->ctx; pctx; pctx = pctx->next) {
|
||||||
if (pctx == ctx) {
|
if (pctx == ctx) {
|
||||||
|
@ -378,31 +401,21 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
pctx->msg_mask |= (1 << h->type);
|
pctx->msg_mask |= (1 << h->type);
|
||||||
ngx_rtmp_send_message(ss, peer_out, prio);
|
ngx_rtmp_send_message(ss, peer_out, prio);
|
||||||
ngx_rtmp_free_shared_chain(cscf, peer_out);
|
ngx_rtmp_free_shared_chain(cscf, peer_out);
|
||||||
|
|
||||||
/* send AVC/H264 header */
|
|
||||||
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
|
||||||
if (codec_ctx) {
|
|
||||||
peer_out = NULL;
|
|
||||||
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
|
||||||
if (codec_ctx->aac_pheader) {
|
|
||||||
peer_out = codec_ctx->aac_pheader;
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, ss->connection->log,
|
|
||||||
0, "live: sending AAC header");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (codec_ctx->avc_pheader) {
|
|
||||||
peer_out = codec_ctx->avc_pheader;
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, ss->connection->log,
|
|
||||||
0, "live: sending AVC/H264 header");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (peer_out) {
|
|
||||||
ngx_rtmp_send_message(ss, peer_out, prio);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send AVC/H264 header */
|
||||||
|
if (header_out && *(ngx_uint_t *)((u_char *)pctx + header_offset)
|
||||||
|
!= header_version)
|
||||||
|
{
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0,
|
||||||
|
"live: sending codec header");
|
||||||
|
if (ngx_rtmp_send_message(ss, header_out, prio) == NGX_OK) {
|
||||||
|
*(ngx_uint_t *)((u_char *)pctx + header_offset)
|
||||||
|
= header_version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* push buffered data */
|
/* push buffered data */
|
||||||
peer_prio = prio;
|
peer_prio = prio;
|
||||||
if (ngx_rtmp_send_message(ss, out, peer_prio) != NGX_OK) {
|
if (ngx_rtmp_send_message(ss, out, peer_prio) != NGX_OK) {
|
||||||
|
|
|
@ -49,6 +49,8 @@ struct ngx_rtmp_live_ctx_s {
|
||||||
uint32_t next_push;
|
uint32_t next_push;
|
||||||
uint32_t last_audio;
|
uint32_t last_audio;
|
||||||
uint32_t last_video;
|
uint32_t last_video;
|
||||||
|
ngx_uint_t aac_version;
|
||||||
|
ngx_uint_t avc_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue