Skip to content

Commit

Permalink
[fix] optimize sequence header cache from context level to gop level
Browse files Browse the repository at this point in the history
  • Loading branch information
vacing committed Jan 29, 2024
1 parent 1f6aa87 commit 35afca3
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 43 deletions.
13 changes: 13 additions & 0 deletions ngx_rtmp_codec_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ 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;
ngx_uint_t *version;
uint8_t fmt;
static ngx_uint_t sample_rates[] =
{ 5512, 11025, 22050, 44100 };
Expand Down Expand Up @@ -250,13 +251,15 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
if (h->type == NGX_RTMP_MSG_AUDIO) {
if (ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC) {
header = &ctx->aac_header;
version = &ctx->ash_version;
if (ngx_rtmp_codec_parse_aac_header(s, in) == NGX_ERROR) {
return NGX_ERROR;
}
}
} else {
if (ctx->video_codec_id == NGX_RTMP_VIDEO_H264) {
header = &ctx->avc_header;
version = &ctx->vsh_version;
if (ngx_rtmp_codec_parse_avc_header(s, in) == NGX_ERROR) {
return NGX_ERROR;
}
Expand All @@ -272,6 +275,14 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
}

*header = ngx_rtmp_append_shared_bufs(cscf, NULL, in);
*version = ngx_rtmp_codec_get_next_version();
if (h->type == NGX_RTMP_MSG_AUDIO) {
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"codec: audio header version=%ui", *version);
} else {
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"codec: video header version=%ui", *version);
}

return NGX_OK;
}
Expand Down Expand Up @@ -766,6 +777,8 @@ ngx_rtmp_codec_prepare_meta(ngx_rtmp_session_t *s, uint32_t timestamp)
ngx_rtmp_prepare_message(s, &h, NULL, ctx->meta);

ctx->meta_version = ngx_rtmp_codec_get_next_version();
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"codec: meta header version=%ui", ctx->meta_version);

return NGX_OK;
}
Expand Down
2 changes: 2 additions & 0 deletions ngx_rtmp_codec_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ typedef struct {

ngx_chain_t *avc_header;
ngx_chain_t *aac_header;
ngx_uint_t vsh_version;
ngx_uint_t ash_version;

ngx_chain_t *meta;
ngx_uint_t meta_version;
Expand Down
96 changes: 65 additions & 31 deletions ngx_rtmp_gop_cache_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,11 @@ ngx_rtmp_gop_cache_cleanup(ngx_rtmp_session_t *s)

for (cache = ctx->cache_head; cache; cache = cache->next) {
ngx_rtmp_gop_cache_free_cache(s, cache);
cache->video_seq_header = NULL;
cache->audio_seq_header = NULL;
cache->meta = NULL;
}

ctx->video_seq_header = NULL;
ctx->audio_seq_header = NULL;
ctx->meta = NULL;

if (ctx->cache_head) {
ctx->cache_head->next = ctx->free_cache;
ctx->free_cache = ctx->cache_head;
Expand Down Expand Up @@ -460,28 +459,35 @@ ngx_rtmp_gop_cache_frame(ngx_rtmp_session_t *s, ngx_uint_t prio,
}
}

if (ctx->cache_tail == NULL) {
return;
}

// save video seq header.
if (codec_ctx->avc_header && ctx->video_seq_header == NULL) {
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache: video seq header is comming");
ctx->video_seq_header = codec_ctx->avc_header;
if (codec_ctx->avc_header && ctx->cache_tail->video_seq_header == NULL) {
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache: video seq header is comming, version=%ui",
codec_ctx->vsh_version);
ctx->cache_tail->video_seq_header = codec_ctx->avc_header;
ctx->cache_tail->vsh_version = codec_ctx->vsh_version;
}

// save audio seq header.
if (codec_ctx->aac_header && ctx->audio_seq_header == NULL) {
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache: audio seq header is comming");
ctx->audio_seq_header = codec_ctx->aac_header;
if (codec_ctx->aac_header && ctx->cache_tail->audio_seq_header == NULL) {
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache: audio seq header is comming, version=%ui",
codec_ctx->ash_version);
ctx->cache_tail->audio_seq_header = codec_ctx->aac_header;
ctx->cache_tail->ash_version = codec_ctx->ash_version;
}

// save metadata.
if (codec_ctx->meta &&
(ctx->meta == NULL || codec_ctx->meta_version != ctx->meta_version))
if (codec_ctx->meta && ctx->cache_tail->meta == NULL)
{
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache: meta is comming");
ctx->meta_version = codec_ctx->meta_version;
ctx->meta = codec_ctx->meta;
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache: meta is comming, version=%ui", codec_ctx->meta_version);
ctx->cache_tail->meta_version = codec_ctx->meta_version;
ctx->cache_tail->meta = codec_ctx->meta;
}

gf = ngx_rtmp_gop_cache_alloc_frame(s);
Expand Down Expand Up @@ -538,7 +544,8 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s)
ngx_rtmp_gop_cache_t *cache;
ngx_rtmp_gop_frame_t *gf;
ngx_rtmp_header_t ch, lh, clh;
ngx_uint_t meta_version;
ngx_uint_t version, coversion, meta_version;
ngx_uint_t version_send, coversion_send;
uint32_t delta;
ngx_int_t csidx;
ngx_rtmp_live_chunk_stream_t *cs;
Expand All @@ -565,7 +572,11 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s)
header = NULL;
coheader = NULL;
meta = NULL;
version = 0;
coversion = 0;
meta_version = 0;
version_send = 0;
coversion_send = 0;

pub_ctx = ctx->stream->pub_ctx;
rs = pub_ctx->session;
Expand Down Expand Up @@ -604,22 +615,22 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s)
}
}

if (meta == NULL && meta_version != gctx->meta_version) {
meta = handler->meta_message_pt(s, gctx->meta);
if (meta == NULL && meta_version != cache->meta_version) {
meta = handler->meta_message_pt(s, cache->meta);
if (meta == NULL) {
ngx_rtmp_finalize_session(s);
return;
}
}

if (meta) {
meta_version = gctx->meta_version;
meta_version = cache->meta_version;
}

/* send metadata */
if (meta && meta_version != ctx->meta_version) {
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache send: meta");
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache send: meta, version=%ui", meta_version);

if (handler->send_message_pt(s, meta, 0) == NGX_ERROR) {
ngx_rtmp_finalize_session(s);
Expand Down Expand Up @@ -673,20 +684,31 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s)
}

switch (gf->h.type) {
case NGX_RTMP_MSG_VIDEO:
header = gctx->video_seq_header;
case NGX_RTMP_MSG_AUDIO:
header = cache->audio_seq_header;
version = cache->ash_version;
version_send = ctx->ash_version;
if (lacf->interleave) {
coheader = gctx->audio_seq_header;
coheader = cache->video_seq_header;
coversion = cache->vsh_version;
coversion_send = ctx->vsh_version;
}
break;
default:
header = gctx->audio_seq_header;
header = cache->video_seq_header;
version = cache->vsh_version;
version_send = ctx->vsh_version;
if (lacf->interleave) {
coheader = gctx->video_seq_header;
coheader = cache->audio_seq_header;
coversion = cache->ash_version;
coversion_send = cache->ash_version;
}
}

if (header) {
if (header && version != version_send) {
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache send: %s sequence header, version=%ui",
(gf->h.type == NGX_RTMP_MSG_AUDIO ? "audio" : "video"), version);
apkt = handler->append_message_pt(s, &lh, NULL, header);
if (apkt == NULL) {
error = 1;
Expand All @@ -698,7 +720,10 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s)
goto next;
}

if (coheader) {
if (coheader && coversion != coversion_send) {
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"gop cache send: %s sequence coheader, version=%ui",
(gf->h.type == NGX_RTMP_MSG_AUDIO ? "video" : "audio"), coversion);
acopkt = handler->append_message_pt(s, &clh, NULL,
coheader);
if (acopkt == NULL) {
Expand All @@ -711,6 +736,15 @@ ngx_rtmp_gop_cache_send(ngx_rtmp_session_t *s)
goto next;
}

if (gf->h.type == NGX_RTMP_MSG_AUDIO) {
ctx->ash_version = version;
if (coheader && coversion)
ctx->vsh_version = coversion;
} else {
ctx->vsh_version = version;
if (coheader && coversion)
ctx->ash_version = coversion;
}
cs->timestamp = lh.timestamp;
cs->active = 1;
s->current_time = cs->timestamp;
Expand Down
13 changes: 8 additions & 5 deletions ngx_rtmp_gop_cache_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ struct ngx_rtmp_gop_cache_s {
ngx_rtmp_gop_cache_t *next;
ngx_int_t video_frame_in_this;
ngx_int_t audio_frame_in_this;

ngx_chain_t *video_seq_header;
ngx_chain_t *audio_seq_header;
ngx_chain_t *meta;

ngx_uint_t vsh_version;
ngx_uint_t ash_version;
ngx_uint_t meta_version;
};


Expand All @@ -48,12 +56,7 @@ typedef struct ngx_rtmp_gop_cache_ctx_s {
ngx_rtmp_gop_cache_t *free_cache;
ngx_rtmp_gop_frame_t *free_frame;

ngx_chain_t *video_seq_header;
ngx_chain_t *audio_seq_header;
ngx_chain_t *meta;
ngx_chain_t *free;

ngx_uint_t meta_version;

size_t gop_cache_count;
size_t video_frame_in_all;
Expand Down
49 changes: 42 additions & 7 deletions ngx_rtmp_live_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,16 +837,18 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
ngx_int_t rc, mandatory, i;
ngx_uint_t prio;
ngx_uint_t peers;
ngx_uint_t meta_version;
ngx_uint_t version, coversion, meta_version;
ngx_uint_t version_send, coversion_send;
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_sco;

type_s = (h->type == NGX_RTMP_MSG_VIDEO ? "video" : "audio");
type_sco = (h->type == NGX_RTMP_MSG_VIDEO ? "audio" : "video");
#endif

lacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_live_module);
Expand Down Expand Up @@ -886,7 +888,11 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
peers = 0;
header = NULL;
coheader = NULL;
version = 0;
coversion = 0;
meta_version = 0;
version_send = 0;
coversion_send = 0;
mandatory = 0;

for (i = 0; i <= NGX_RTMP_PROTOCOL_HTTP; i++) {
Expand Down Expand Up @@ -944,9 +950,11 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,

if (h->type == NGX_RTMP_MSG_AUDIO) {
header = codec_ctx->aac_header;
version = codec_ctx->ash_version;

if (lacf->interleave) {
coheader = codec_ctx->avc_header;
coversion = codec_ctx->vsh_version;
}

if (codec_ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC &&
Expand All @@ -958,9 +966,11 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,

} else {
header = codec_ctx->avc_header;
version = codec_ctx->vsh_version;

if (lacf->interleave) {
coheader = codec_ctx->aac_header;
coversion = codec_ctx->ash_version;
}

if (codec_ctx->video_codec_id == NGX_RTMP_VIDEO_H264 &&
Expand All @@ -985,6 +995,16 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,

ss = pctx->session;
cs = &pctx->cs[csidx];

if (h->type == NGX_RTMP_MSG_AUDIO) {
version_send = pctx->ash_version;
if (lacf->interleave)
coversion_send = pctx->vsh_version;
} else {
version_send = pctx->vsh_version;
if (lacf->interleave)
coversion_send = pctx->ash_version;
}

handler = ngx_rtmp_live_proc_handlers[pctx->protocol];

Expand Down Expand Up @@ -1072,11 +1092,14 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,

/* send absolute codec header */

ngx_log_debug2(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0,
"live: abs %s header timestamp=%uD",
type_s, lh.timestamp);
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0,
"live: abs %s header timestamp=%uD, version=%ui",
type_s, lh.timestamp, version);

if (header) {
if (header && version != version_send) {
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0,
"live: %s coheader send, version=%ui",
type_s, version);
if (handler->apkt == NULL) {
handler->apkt = handler->append_message_pt(ss, &lh,
NULL, header);
Expand All @@ -1091,7 +1114,10 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
}
}

if (coheader) {
if (coheader && coversion != coversion_send) {
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, ss->connection->log, 0,
"live: %s coheader send, coversion=%ui",
type_sco, coversion);
if (handler->acopkt == NULL) {
handler->acopkt = handler->append_message_pt(ss, &clh,
NULL, coheader);
Expand All @@ -1107,6 +1133,15 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,

}

if (h->type == NGX_RTMP_MSG_AUDIO) {
pctx->ash_version = version;
if (coheader && coversion)
pctx->vsh_version = coversion;
} else {
pctx->vsh_version = version;
if (coheader && coversion)
pctx->ash_version = coversion;
}
cs->timestamp = lh.timestamp;
cs->active = 1;
ss->current_time = cs->timestamp;
Expand Down
2 changes: 2 additions & 0 deletions ngx_rtmp_live_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ struct ngx_rtmp_live_ctx_s {
ngx_rtmp_live_ctx_t *next;
ngx_uint_t ndropped;
ngx_rtmp_live_chunk_stream_t cs[2];
ngx_uint_t vsh_version;
ngx_uint_t ash_version;
ngx_uint_t meta_version;
ngx_event_t idle_evt;
unsigned active:1;
Expand Down

0 comments on commit 35afca3

Please sign in to comment.