Permalink
Browse files

added support for multiple aac/avc codecs per stream

  • Loading branch information...
1 parent c377e3b commit 266e206afcda93cf2880e660fb796eb99fb6df6c @arut arut committed Jun 13, 2012
Showing with 53 additions and 22 deletions.
  1. +13 −0 ngx_rtmp_codec_module.c
  2. +3 −0 ngx_rtmp_codec_module.h
  3. +35 −22 ngx_rtmp_live_module.c
  4. +2 −0 ngx_rtmp_live_module.h
@@ -11,6 +11,11 @@
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 = {
NULL, /* preconfiguration */
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;
uint8_t fmt;
ngx_rtmp_header_t ch, lh;
+ ngx_uint_t *version;
/* save AVC/AAC header */
if ((h->type != NGX_RTMP_MSG_AUDIO
@@ -166,13 +172,15 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
if (((fmt & 0xf0) >> 4) == NGX_RTMP_AUDIO_AAC) {
header = &ctx->aac_header;
pheader = &ctx->aac_pheader;
+ version = &ctx->aac_version;
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"codec: AAC header arrived");
}
} else {
if ((fmt & 0x0f) == NGX_RTMP_VIDEO_H264) {
header = &ctx->avc_header;
pheader = &ctx->avc_pheader;
+ version = &ctx->avc_version;
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"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);
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;
}
@@ -47,6 +47,9 @@ u_char * ngx_rtmp_get_video_codec_name(ngx_uint_t id);
typedef struct {
+ ngx_uint_t avc_version;
+ ngx_uint_t aac_version;
+
ngx_chain_t *avc_header;
ngx_chain_t *aac_header;
@@ -283,14 +283,16 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
{
ngx_rtmp_live_ctx_t *ctx, *pctx;
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_live_app_conf_t *lacf;
ngx_rtmp_session_t *ss;
ngx_rtmp_header_t ch, lh;
ngx_uint_t prio, peer_prio;
ngx_uint_t peers, dropped_peers;
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);
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 */
for (pctx = ctx->stream->ctx; pctx; pctx = pctx->next) {
if (pctx == ctx) {
@@ -378,29 +401,19 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
pctx->msg_mask |= (1 << h->type);
ngx_rtmp_send_message(ss, peer_out, prio);
ngx_rtmp_free_shared_chain(cscf, peer_out);
+ continue;
+ }
- /* 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);
- }
+ /* 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;
}
- continue;
}
/* push buffered data */
@@ -49,6 +49,8 @@ struct ngx_rtmp_live_ctx_s {
uint32_t next_push;
uint32_t last_audio;
uint32_t last_video;
+ ngx_uint_t aac_version;
+ ngx_uint_t avc_version;
};

0 comments on commit 266e206

Please sign in to comment.