added proper keyframe & codec header handling to recorder

This commit is contained in:
Roman Arutyunyan 2012-12-14 21:03:38 +04:00
parent 5c947253af
commit a0a4cc21b4
2 changed files with 63 additions and 35 deletions

View file

@ -421,12 +421,12 @@ ngx_rtmp_record_node_open(ngx_rtmp_session_t *s,
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"record: %V opening", &rracf->id);
ngx_memzero(rctx, sizeof(*rctx));
rctx->timestamp = ngx_cached_time->sec;
ngx_rtmp_record_make_path(s, rctx, &path);
rctx->nframes = 0;
ngx_memzero(&rctx->file, sizeof(rctx->file));
rctx->last = *ngx_cached_time;
@ -938,11 +938,6 @@ ngx_rtmp_record_node_av(ngx_rtmp_session_t *s, ngx_rtmp_record_rec_ctx_t *rctx,
ngx_rtmp_record_node_close(s, rctx);
return NGX_OK;
}
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
if (codec_ctx) {
ch = *h;
#if 0
/* metadata */
if (codec_ctx->meta) {
@ -957,41 +952,71 @@ ngx_rtmp_record_node_av(ngx_rtmp_session_t *s, ngx_rtmp_record_rec_ctx_t *rctx,
}
}
#endif
/* AAC header */
if (codec_ctx->aac_header && (rracf->flags & NGX_RTMP_RECORD_AUDIO))
{
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"record: %V writing AAC header", &rracf->id);
}
ch.type = NGX_RTMP_MSG_AUDIO;
ch.mlen = ngx_rtmp_record_get_chain_mlen(codec_ctx->aac_header);
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
if (codec_ctx) {
ch = *h;
if (ngx_rtmp_record_write_frame(s, rctx, &ch,
codec_ctx->aac_header, 0)
/* AAC header */
if (!rctx->aac_header_sent && codec_ctx->aac_header &&
(rracf->flags & NGX_RTMP_RECORD_AUDIO))
{
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"record: %V writing AAC header", &rracf->id);
ch.type = NGX_RTMP_MSG_AUDIO;
ch.mlen = ngx_rtmp_record_get_chain_mlen(codec_ctx->aac_header);
if (ngx_rtmp_record_write_frame(s, rctx, &ch,
codec_ctx->aac_header, 0)
!= NGX_OK)
{
return NGX_OK;
}
{
return NGX_OK;
}
/* AVC header */
if (codec_ctx->avc_header &&
(rracf->flags & (NGX_RTMP_RECORD_VIDEO|
NGX_RTMP_RECORD_KEYFRAMES)))
rctx->aac_header_sent = 1;
}
/* AVC header */
if (!rctx->avc_header_sent && codec_ctx->avc_header &&
(rracf->flags & (NGX_RTMP_RECORD_VIDEO|
NGX_RTMP_RECORD_KEYFRAMES)))
{
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"record: %V writing AVC header", &rracf->id);
ch.type = NGX_RTMP_MSG_VIDEO;
ch.mlen = ngx_rtmp_record_get_chain_mlen(codec_ctx->avc_header);
if (ngx_rtmp_record_write_frame(s, rctx, &ch,
codec_ctx->avc_header, 0)
!= NGX_OK)
{
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"record: %V writing AVC header", &rracf->id);
ch.type = NGX_RTMP_MSG_VIDEO;
ch.mlen = ngx_rtmp_record_get_chain_mlen(codec_ctx->avc_header);
if (ngx_rtmp_record_write_frame(s, rctx, &ch,
codec_ctx->avc_header, 0)
!= NGX_OK)
{
return NGX_OK;
}
return NGX_OK;
}
rctx->avc_header_sent = 1;
}
}
if (h->type == NGX_RTMP_MSG_VIDEO) {
if (codec_ctx && codec_ctx->video_codec_id == NGX_RTMP_VIDEO_H264 &&
!rctx->avc_header_sent)
{
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"record: %V skipping until H264 header", &rracf->id);
return NGX_OK;
}
if (ngx_rtmp_get_video_frame_type(in) == NGX_RTMP_VIDEO_KEY_FRAME) {
rctx->video_key_sent = 1;
}
if (!rctx->video_key_sent) {
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"record: %V skipping until keyframe", &rracf->id);
return NGX_OK;
}
}

View file

@ -42,6 +42,9 @@ typedef struct {
ngx_time_t last;
time_t timestamp;
unsigned failed:1;
unsigned aac_header_sent:1;
unsigned avc_header_sent:1;
unsigned video_key_sent:1;
} ngx_rtmp_record_rec_ctx_t;