From 83a611d243e012cb69b2fc109dd0aa7dc36901b6 Mon Sep 17 00:00:00 2001 From: winshining Date: Thu, 18 Jan 2018 02:05:57 +0800 Subject: [PATCH] [dev] optimize ngx_rtmp_gop_cache_send and ngx_rtmp_live_av functions. --- ngx_http_flv_live_module.c | 10 ++- ngx_http_flv_live_module.h | 7 +- ngx_rtmp_gop_cache_module.c | 70 ++++++++-------- ngx_rtmp_live_module.c | 157 +++++++++++++++++------------------- 4 files changed, 123 insertions(+), 121 deletions(-) diff --git a/ngx_http_flv_live_module.c b/ngx_http_flv_live_module.c index 2b4674e..f14f3ba 100644 --- a/ngx_http_flv_live_module.c +++ b/ngx_http_flv_live_module.c @@ -31,15 +31,19 @@ static void ngx_http_flv_live_free_message(ngx_rtmp_session_t *s, ngx_chain_t *in); static void ngx_http_flv_live_close_http_request(ngx_rtmp_session_t *s); -extern ngx_rtmp_process_handler_t ngx_rtmp_live_process_handler; -static ngx_rtmp_process_handler_t ngx_http_flv_live_process_handler = { +extern ngx_rtmp_live_process_handler_t ngx_rtmp_live_process_handler; +static ngx_rtmp_live_process_handler_t ngx_http_flv_live_process_handler = { + NULL, + NULL, + NULL, + NULL, ngx_http_flv_live_send_message, ngx_http_flv_live_meta_message, ngx_http_flv_live_append_message, ngx_http_flv_live_free_message }; -ngx_rtmp_process_handler_t *ngx_rtmp_process_handlers[] = { +ngx_rtmp_live_process_handler_t *ngx_rtmp_live_process_handlers[] = { &ngx_rtmp_live_process_handler, &ngx_http_flv_live_process_handler }; diff --git a/ngx_http_flv_live_module.h b/ngx_http_flv_live_module.h index f8e93c0..7859213 100644 --- a/ngx_http_flv_live_module.h +++ b/ngx_http_flv_live_module.h @@ -50,6 +50,11 @@ typedef struct ngx_http_flv_live_conf_s { typedef struct { + ngx_chain_t *meta; + ngx_chain_t *apkt; + ngx_chain_t *acopkt; + ngx_chain_t *rpkt; + ngx_int_t (*send_message_pt)(ngx_rtmp_session_t *s, ngx_chain_t *out, unsigned int priority); ngx_chain_t *(*meta_message_pt)(ngx_rtmp_session_t *s, @@ -59,7 +64,7 @@ typedef struct { ngx_chain_t *in); void (*free_message_pt)(ngx_rtmp_session_t *s, ngx_chain_t *in); -} ngx_rtmp_process_handler_t; +} ngx_rtmp_live_process_handler_t; ngx_int_t ngx_http_flv_live_send_header(ngx_rtmp_session_t *s); diff --git a/ngx_rtmp_gop_cache_module.c b/ngx_rtmp_gop_cache_module.c index 8914954..6db407b 100644 --- a/ngx_rtmp_gop_cache_module.c +++ b/ngx_rtmp_gop_cache_module.c @@ -43,8 +43,9 @@ static char *ngx_rtmp_gop_cache_merge_app_conf(ngx_conf_t *cf, void *parent, void *child); -extern ngx_rtmp_process_handler_t *ngx_rtmp_process_handlers[2]; -extern ngx_module_t ngx_http_flv_live_module; +extern ngx_rtmp_live_process_handler_t *ngx_rtmp_live_process_handlers + [NGX_RTMP_PROTOCOL_HTTP + 1]; +extern ngx_module_t ngx_http_flv_live_module; static ngx_command_t ngx_rtmp_gop_cache_commands[] = { @@ -579,21 +580,21 @@ ngx_rtmp_gop_cache_frame(ngx_rtmp_session_t *s, ngx_uint_t prio, void ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s) { - ngx_rtmp_session_t *rs; - ngx_chain_t *pkt, *apkt, *meta, *header; - ngx_rtmp_live_ctx_t *ctx, *pub_ctx; - ngx_http_flv_live_ctx_t *hflctx; - ngx_rtmp_gop_cache_ctx_t *gctx; - ngx_rtmp_live_app_conf_t *lacf; - ngx_rtmp_gop_cache_t *cache; - ngx_rtmp_gop_frame_t *gop_frame; - ngx_rtmp_header_t ch, lh; - ngx_uint_t meta_version; - uint32_t delta; - ngx_int_t csidx; - ngx_rtmp_live_chunk_stream_t *cs; - ngx_rtmp_process_handler_t *handler; - ngx_http_request_t *r; + ngx_rtmp_session_t *rs; + ngx_chain_t *pkt, *apkt, *meta, *header; + ngx_rtmp_live_ctx_t *ctx, *pub_ctx; + ngx_http_flv_live_ctx_t *hflctx; + ngx_rtmp_gop_cache_ctx_t *gctx; + ngx_rtmp_live_app_conf_t *lacf; + ngx_rtmp_gop_cache_t *cache; + ngx_rtmp_gop_frame_t *gop_frame; + ngx_rtmp_header_t ch, lh; + ngx_uint_t meta_version; + uint32_t delta; + ngx_int_t csidx; + ngx_rtmp_live_chunk_stream_t *cs; + ngx_rtmp_live_process_handler_t *handler; + ngx_http_request_t *r; lacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_live_module); if (lacf == NULL) { @@ -616,7 +617,7 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s) pub_ctx = ctx->stream->pub_ctx; rs = pub_ctx->session; s->publisher = rs; - handler = ngx_rtmp_process_handlers[ctx->protocol]; + handler = ngx_rtmp_live_process_handlers[ctx->protocol]; gctx = ngx_rtmp_get_module_ctx(rs, ngx_rtmp_gop_cache_module); if (gctx == NULL) { @@ -627,7 +628,7 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s) if (ctx->protocol == NGX_RTMP_PROTOCOL_HTTP) { r = s->data; if (r == NULL || (r->connection && r->connection->destroyed)) { - return; + goto clear; } hflctx = ngx_http_get_module_ctx(r, ngx_http_flv_live_module); @@ -653,9 +654,6 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s) if (handler->send_message_pt(s, meta, 0) == NGX_OK) { ctx->meta_version = meta_version; } - - handler->free_message_pt(s, meta); - meta = NULL; } for (gop_frame = cache->frame_head; @@ -693,11 +691,6 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s) cs->active = 1; s->current_time = cs->timestamp; } - - if (apkt) { - handler->free_message_pt(s, apkt); - apkt = NULL; - } } pkt = handler->append_message_pt(s, &ch, &lh, gop_frame->frame); @@ -706,12 +699,7 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s) cs->dropped += delta; - return; - } - - if (pkt) { - handler->free_message_pt(s, pkt); - pkt = NULL; + goto clear; } ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, @@ -726,6 +714,22 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s) s->current_time = cs->timestamp; } } + + return; + +clear: + + if (meta) { + handler->free_message_pt(s, meta); + } + + if (pkt) { + handler->free_message_pt(s, pkt); + } + + if (apkt) { + handler->free_message_pt(s, apkt); + } } diff --git a/ngx_rtmp_live_module.c b/ngx_rtmp_live_module.c index 1990706..1aba31d 100644 --- a/ngx_rtmp_live_module.c +++ b/ngx_rtmp_live_module.c @@ -40,7 +40,11 @@ static ngx_chain_t *ngx_rtmp_live_append_message(ngx_rtmp_session_t *s, static void ngx_rtmp_live_free_message(ngx_rtmp_session_t *s, ngx_chain_t *in); -ngx_rtmp_process_handler_t ngx_rtmp_live_process_handler = { +ngx_rtmp_live_process_handler_t ngx_rtmp_live_process_handler = { + NULL, + NULL, + NULL, + NULL, ngx_rtmp_live_send_message, ngx_rtmp_live_meta_message, ngx_rtmp_live_append_message, @@ -48,8 +52,9 @@ ngx_rtmp_process_handler_t ngx_rtmp_live_process_handler = { }; -extern ngx_rtmp_process_handler_t *ngx_rtmp_process_handlers[2]; -extern ngx_module_t ngx_http_flv_live_module; +extern ngx_rtmp_live_process_handler_t *ngx_rtmp_live_process_handlers + [NGX_RTMP_PROTOCOL_HTTP + 1]; +extern ngx_module_t ngx_http_flv_live_module; static ngx_command_t ngx_rtmp_live_commands[] = { @@ -792,28 +797,27 @@ static ngx_int_t ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ngx_chain_t *in) { - ngx_rtmp_process_handler_t *handler; - ngx_rtmp_live_ctx_t *ctx, *pctx; - ngx_rtmp_codec_ctx_t *codec_ctx; - ngx_chain_t *header, *coheader, *meta, - *apkt, *acopkt, *rpkt; - ngx_rtmp_live_app_conf_t *lacf; - ngx_rtmp_session_t *ss; - ngx_rtmp_header_t ch, lh, clh; - ngx_int_t rc, mandatory; - ngx_uint_t prio; - ngx_uint_t peers; - ngx_uint_t meta_version; - ngx_uint_t csidx; - uint32_t delta; - ngx_rtmp_live_chunk_stream_t *cs; + ngx_rtmp_live_process_handler_t *handler; + ngx_rtmp_live_ctx_t *ctx, *pctx; + ngx_rtmp_codec_ctx_t *codec_ctx; + ngx_chain_t *header, *coheader; + ngx_rtmp_live_app_conf_t *lacf; + ngx_rtmp_session_t *ss; + ngx_rtmp_header_t ch, lh, clh; + ngx_int_t rc, mandatory, i; + ngx_uint_t prio; + ngx_uint_t peers; + ngx_uint_t meta_version; + ngx_uint_t csidx; + uint32_t delta; + ngx_rtmp_live_chunk_stream_t *cs; + ngx_http_request_t *r; + ngx_http_flv_live_ctx_t *hctx; #ifdef NGX_DEBUG - const char *type_s; + const char *type_s; type_s = (h->type == NGX_RTMP_MSG_VIDEO ? "video" : "audio"); -#endif - ngx_http_request_t *r; - ngx_http_flv_live_ctx_t *hctx; +#endif lacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_live_module); if (lacf == NULL) { @@ -850,15 +854,20 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, s->current_time = h->timestamp; peers = 0; - rpkt = NULL; - apkt = NULL; - acopkt = NULL; header = NULL; coheader = NULL; - meta = NULL; meta_version = 0; mandatory = 0; + for (i = 0; i <= NGX_RTMP_PROTOCOL_HTTP; i++) { + handler = ngx_rtmp_live_process_handlers[i]; + + handler->meta = NULL; + handler->rpkt = NULL; + handler->apkt = NULL; + handler->acopkt = NULL; + } + prio = (h->type == NGX_RTMP_MSG_VIDEO ? ngx_rtmp_get_video_frame_type(in) : 0); @@ -898,6 +907,7 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ch.timestamp = lh.timestamp; } */ + codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module); if (codec_ctx) { @@ -946,7 +956,7 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ss = pctx->session; cs = &pctx->cs[csidx]; - handler = ngx_rtmp_process_handlers[pctx->protocol]; + handler = ngx_rtmp_live_process_handlers[pctx->protocol]; /* send metadata */ @@ -960,7 +970,6 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, } hctx = ngx_http_get_module_ctx(r, ngx_http_flv_live_module); - if (!hctx->header_sent) { if ((!codec_ctx->has_video || !codec_ctx->has_audio) && !codec_ctx->pure_audio) @@ -974,20 +983,17 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, } } - if (meta == NULL && meta_version != pctx->meta_version) { - meta = handler->meta_message_pt(ss, codec_ctx->meta); + if (handler->meta == NULL && meta_version != pctx->meta_version) { + handler->meta = handler->meta_message_pt(ss, codec_ctx->meta); } - if (meta && meta_version != pctx->meta_version) { + if (handler->meta && meta_version != pctx->meta_version) { ngx_log_debug0(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0, "live: meta"); - if (handler->send_message_pt(ss, meta, 0) == NGX_OK) { + if (handler->send_message_pt(ss, handler->meta, 0) == NGX_OK) { pctx->meta_version = meta_version; } - - handler->free_message_pt(ss, meta); - meta = NULL; } /* sync stream */ @@ -1040,33 +1046,25 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, type_s, lh.timestamp); if (header) { - if (apkt == NULL) { - apkt = handler->append_message_pt(ss, &lh, NULL, header); + if (handler->apkt == NULL) { + handler->apkt = handler->append_message_pt(ss, &lh, + NULL, header); } - rc = handler->send_message_pt(ss, apkt, 0); + rc = handler->send_message_pt(ss, handler->apkt, 0); if (rc != NGX_OK) { - if (apkt) { - handler->free_message_pt(ss, apkt); - apkt = NULL; - } - continue; } } if (coheader) { - if (acopkt == NULL) { - acopkt = handler->append_message_pt(ss, &clh, NULL, coheader); + if (handler->acopkt == NULL) { + handler->acopkt = handler->append_message_pt(ss, &clh, + NULL, coheader); } - rc = handler->send_message_pt(ss, acopkt, 0); + rc = handler->send_message_pt(ss, handler->acopkt, 0); if (rc != NGX_OK) { - if (acopkt) { - handler->free_message_pt(ss, acopkt); - acopkt = NULL; - } - continue; } @@ -1084,17 +1082,13 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, "live: abs %s packet timestamp=%uD", type_s, ch.timestamp); - if (apkt == NULL) { - apkt = handler->append_message_pt(ss, &ch, NULL, in); + if (handler->apkt == NULL) { + handler->apkt = handler->append_message_pt(ss, &ch, + NULL, in); } - rc = handler->send_message_pt(ss, apkt, prio); + rc = handler->send_message_pt(ss, handler->apkt, prio); if (rc != NGX_OK) { - if (apkt) { - handler->free_message_pt(ss, apkt); - apkt = NULL; - } - continue; } @@ -1108,11 +1102,7 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, } } - rpkt = handler->append_message_pt(ss, &ch, &lh, in); - if (rpkt == NULL) { - /* request from http closed */ - continue; - } + handler->rpkt = handler->append_message_pt(ss, &ch, &lh, in); /* send relative packet */ @@ -1120,21 +1110,11 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, "live: rel %s packet delta=%uD", type_s, delta); - if (handler->send_message_pt(ss, rpkt, prio) != NGX_OK) { + if (handler->send_message_pt(ss, handler->rpkt, prio) != NGX_OK) { ++pctx->ndropped; cs->dropped += delta; - if (apkt) { - handler->free_message_pt(ss, apkt); - apkt = NULL; - } - - if (acopkt) { - handler->free_message_pt(ss, acopkt); - acopkt = NULL; - } - if (mandatory) { ngx_log_debug0(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0, "live: mandatory packet failed"); @@ -1147,20 +1127,29 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, cs->timestamp += delta; ++peers; ss->current_time = cs->timestamp; + } + + for (i = 0; i <= NGX_RTMP_PROTOCOL_HTTP; i++) { + handler = ngx_rtmp_live_process_handlers[i]; + + if (handler->meta) { + handler->free_message_pt(s, handler->meta); + handler->meta = NULL; + } - if (rpkt) { - handler->free_message_pt(ss, rpkt); - rpkt = NULL; + if (handler->rpkt) { + handler->free_message_pt(s, handler->rpkt); + handler->rpkt = NULL; } - if (apkt) { - handler->free_message_pt(ss, apkt); - apkt = NULL; + if (handler->apkt) { + handler->free_message_pt(s, handler->apkt); + handler->apkt = NULL; } - if (acopkt) { - handler->free_message_pt(ss, acopkt); - acopkt = NULL; + if (handler->acopkt) { + handler->free_message_pt(s, handler->acopkt); + handler->acopkt = NULL; } }