diff --git a/ngx_rtmp_codec_module.c b/ngx_rtmp_codec_module.c index a8d23b9..f0b01ac 100644 --- a/ngx_rtmp_codec_module.c +++ b/ngx_rtmp_codec_module.c @@ -130,16 +130,6 @@ ngx_rtmp_codec_disconnect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ctx->aac_header = NULL; } - if (ctx->avc_pheader) { - ngx_rtmp_free_shared_chain(cscf, ctx->avc_pheader); - ctx->avc_pheader = NULL; - } - - if (ctx->aac_pheader) { - ngx_rtmp_free_shared_chain(cscf, ctx->aac_pheader); - ctx->aac_pheader = NULL; - } - if (ctx->meta) { ngx_rtmp_free_shared_chain(cscf, ctx->meta); ctx->meta = NULL; @@ -155,9 +145,8 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, { ngx_rtmp_core_srv_conf_t *cscf; ngx_rtmp_codec_ctx_t *ctx; - ngx_chain_t **header, **pheader; + ngx_chain_t **header; uint8_t fmt; - ngx_rtmp_header_t ch, lh; ngx_uint_t *version, idx; u_char *p; static ngx_uint_t sample_rates[] = @@ -209,12 +198,10 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module); header = NULL; - pheader = NULL; version = NULL; if (h->type == NGX_RTMP_MSG_AUDIO) { if (ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC) { header = &ctx->aac_header; - pheader = &ctx->aac_pheader; version = &ctx->aac_version; if (in->buf->last - in->buf->pos > 3) { @@ -269,7 +256,6 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, } else { if (ctx->video_codec_id == 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"); @@ -284,21 +270,7 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ngx_rtmp_free_shared_chain(cscf, *header); } - if (*pheader) { - ngx_rtmp_free_shared_chain(cscf, *pheader); - } - - /* equal headers; timeout diff is zero */ - ngx_memzero(&ch, sizeof(ch)); - ch.msid = NGX_RTMP_MSID; - ch.type = h->type; - ch.csid = (h->type == NGX_RTMP_MSG_VIDEO - ? NGX_RTMP_CSID_VIDEO - : NGX_RTMP_CSID_AUDIO); - lh = ch; *header = 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); /* don't want zero as version value */ *version = ngx_rtmp_codec_get_next_version(); diff --git a/ngx_rtmp_codec_module.h b/ngx_rtmp_codec_module.h index d02f100..c84047a 100644 --- a/ngx_rtmp_codec_module.h +++ b/ngx_rtmp_codec_module.h @@ -68,10 +68,6 @@ typedef struct { ngx_chain_t *avc_header; ngx_chain_t *aac_header; - /* prepared headers (for live streaming) */ - ngx_chain_t *avc_pheader; - ngx_chain_t *aac_pheader; - ngx_chain_t *meta; ngx_uint_t meta_version; } ngx_rtmp_codec_ctx_t; diff --git a/ngx_rtmp_live_module.c b/ngx_rtmp_live_module.c index 18de9d2..5ff6c1a 100644 --- a/ngx_rtmp_live_module.c +++ b/ngx_rtmp_live_module.c @@ -399,9 +399,9 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ch.csid = NGX_RTMP_CSID_VIDEO; } - if ((ctx->msg_mask & (1 << h->type)) == 0) { + if ((ctx->msg_mask & (1 << ch.csid)) == 0) { lh.timestamp = ch.timestamp; - ctx->msg_mask |= (1 << h->type); + ctx->msg_mask |= (1 << ch.csid); } lh.csid = ch.csid; @@ -422,16 +422,14 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, meta_version = 0; if (codec_ctx) { if (h->type == NGX_RTMP_MSG_AUDIO) { - if (codec_ctx->aac_pheader) { + if (codec_ctx->aac_header) { header_out = codec_ctx->aac_header; - pheader_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) { + if (codec_ctx->avc_header) { header_out = codec_ctx->avc_header; - pheader_out = codec_ctx->avc_pheader; header_offset = offsetof(ngx_rtmp_live_ctx_t, avc_version); header_version = codec_ctx->avc_version; } @@ -456,6 +454,8 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ch.timestamp -= (uint32_t)ss->epoch; } + lh.timestamp = ch.timestamp - diff_timestamp; + /* send absolute frame */ if ((pctx->msg_mask & (1 << ch.csid)) == 0) { @@ -491,12 +491,19 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, } /* send AVC/H264 header if newer header has arrived */ - if (pheader_out && *(ngx_uint_t *)((u_char *)pctx + header_offset) + 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, pheader_out, prio) == NGX_OK) { + + if (pheader_out == NULL) { + pheader_out = + ngx_rtmp_append_shared_bufs(cscf, NULL, header_out); + ngx_rtmp_prepare_message(s, &ch, &ch, pheader_out); + } + + if (ngx_rtmp_send_message(ss, pheader_out, 0) == NGX_OK) { *(ngx_uint_t *)((u_char *)pctx + header_offset) = header_version; } @@ -511,6 +518,23 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, } } + /* send absolute frame to sync stream */ + if (!lacf->interleave && lacf->sync && + *last + lacf->sync < lh.timestamp) + { + ngx_log_debug2(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0, + "live: av: sync %s: %i", + h->type == NGX_RTMP_MSG_VIDEO ? "video" : "audio", + (ngx_int_t) (lh.timestamp - *last)); + + peer_out = ngx_rtmp_alloc_shared_buf(cscf); + ngx_rtmp_prepare_message(s, &lh, NULL, peer_out); + if (ngx_rtmp_send_message(ss, peer_out, 0) == NGX_OK) { + *last = lh.timestamp; + } + ngx_rtmp_free_shared_chain(cscf, peer_out); + } + /* push buffered data */ peer_prio = prio; if (ngx_rtmp_send_message(ss, out, peer_prio) != NGX_OK) { @@ -521,25 +545,13 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, *last += diff_timestamp; - if (lacf->sync == 0 || *last + lacf->sync >= ch.timestamp) { - continue; - } - - /* send absolute frame to sync stream */ - ngx_log_debug2(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0, - "live: av: sync %s: %i", - h->type == NGX_RTMP_MSG_VIDEO ? "video" : "audio", - (ngx_int_t) (ch.timestamp - *last)); - - peer_out = ngx_rtmp_alloc_shared_buf(cscf); - ngx_rtmp_prepare_message(s, &ch, NULL, peer_out); - if (ngx_rtmp_send_message(ss, peer_out, 0) == NGX_OK) { - *last = ch.timestamp; - } - ngx_rtmp_free_shared_chain(cscf, peer_out); } ngx_rtmp_free_shared_chain(cscf, out); + if (pheader_out) { + ngx_rtmp_free_shared_chain(cscf, pheader_out); + } + ngx_rtmp_update_bandwidth(&ctx->stream->bw_in, h->mlen); ngx_rtmp_update_bandwidth(&ctx->stream->bw_out, h->mlen * (peers - dropped_peers)); diff --git a/ngx_rtmp_live_module.h b/ngx_rtmp_live_module.h index 8d1feea..f1255a5 100644 --- a/ngx_rtmp_live_module.h +++ b/ngx_rtmp_live_module.h @@ -29,12 +29,15 @@ struct ngx_rtmp_live_ctx_s { ngx_uint_t msg_mask; ngx_uint_t dropped; uint32_t csid; - uint32_t next_push; uint32_t last_audio; uint32_t last_video; ngx_uint_t aac_version; ngx_uint_t avc_version; ngx_uint_t meta_version; + + /* last stream timestamps */ + uint32_t last[2]; + uint32_t *plast[2]; };