From 2262649c1fb059add84656e913160c233e382344 Mon Sep 17 00:00:00 2001 From: Bryan Berg Date: Sun, 7 Sep 2014 12:35:10 -0700 Subject: [PATCH] Don't truncate framerate for MPEG-DASH When pushing 29.97fps RTMP streams, the manifest shows an incorrect frame rate of "29", not "30000/1001" as it should be. --- dash/ngx_rtmp_dash_module.c | 35 ++++++++++++++++++++++++++++++----- ngx_rtmp_codec_module.c | 4 ++-- ngx_rtmp_codec_module.h | 2 +- ngx_rtmp_stat_module.c | 2 +- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/dash/ngx_rtmp_dash_module.c b/dash/ngx_rtmp_dash_module.c index 88f55ef..b78f682 100644 --- a/dash/ngx_rtmp_dash_module.c +++ b/dash/ngx_rtmp_dash_module.c @@ -221,7 +221,7 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) ngx_fd_t fd; struct tm tm; ngx_str_t noname, *name; - ngx_uint_t i; + ngx_uint_t i, frame_rate_num, frame_rate_denom; ngx_rtmp_dash_ctx_t *ctx; ngx_rtmp_codec_ctx_t *codec_ctx; ngx_rtmp_dash_frag_t *f; @@ -230,6 +230,7 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) static u_char buffer[NGX_RTMP_DASH_BUFSIZE]; static u_char start_time[sizeof("1970-09-28T12:00:00+06:00")]; static u_char end_time[sizeof("1970-09-28T12:00:00+06:00")]; + static u_char frame_rate[(NGX_INT_T_LEN * 2) + 2]; dacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_dash_module); ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_dash_module); @@ -277,14 +278,14 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) " segmentAlignment=\"true\"\n" \ " maxWidth=\"%ui\"\n" \ " maxHeight=\"%ui\"\n" \ - " maxFrameRate=\"%ui\">\n" \ + " maxFrameRate=\"%s\">\n" \ " \n" \ @@ -382,17 +383,41 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) sep = (dacf->nested ? "" : "-"); if (ctx->has_video) { + frame_rate_num = (ngx_uint_t) (codec_ctx->frame_rate * 1000.); + + if (frame_rate_num % 1000 == 0) { + *ngx_sprintf(frame_rate, "%ui", frame_rate_num / 1000) = 0; + } else { + frame_rate_denom = 1000; + switch (frame_rate_num) { + case 23976: + frame_rate_num = 24000; + frame_rate_denom = 1001; + break; + case 29970: + frame_rate_num = 30000; + frame_rate_denom = 1001; + break; + case 59940: + frame_rate_num = 60000; + frame_rate_denom = 1001; + break; + } + + *ngx_sprintf(frame_rate, "%ui/%ui", frame_rate_num, frame_rate_denom) = 0; + } + p = ngx_slprintf(buffer, last, NGX_RTMP_DASH_MANIFEST_VIDEO, codec_ctx->width, codec_ctx->height, - codec_ctx->frame_rate, + frame_rate, &ctx->name, codec_ctx->avc_profile, codec_ctx->avc_compat, codec_ctx->avc_level, codec_ctx->width, codec_ctx->height, - codec_ctx->frame_rate, + frame_rate, (ngx_uint_t) (codec_ctx->video_data_rate * 1000), name, sep, name, sep); diff --git a/ngx_rtmp_codec_module.c b/ngx_rtmp_codec_module.c index ddc9273..bb11044 100644 --- a/ngx_rtmp_codec_module.c +++ b/ngx_rtmp_codec_module.c @@ -857,7 +857,7 @@ ngx_rtmp_codec_meta_data(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ctx->width = (ngx_uint_t) v.width; ctx->height = (ngx_uint_t) v.height; ctx->duration = (ngx_uint_t) v.duration; - ctx->frame_rate = (ngx_uint_t) v.frame_rate; + ctx->frame_rate = v.frame_rate; ctx->video_data_rate = (ngx_uint_t) v.video_data_rate; ctx->video_codec_id = (ngx_uint_t) v.video_codec_id_n; ctx->audio_data_rate = (ngx_uint_t) v.audio_data_rate; @@ -869,7 +869,7 @@ ngx_rtmp_codec_meta_data(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ngx_log_debug8(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "codec: data frame: " - "width=%ui height=%ui duration=%ui frame_rate=%ui " + "width=%ui height=%ui duration=%ui frame_rate=%.3f " "video=%s (%ui) audio=%s (%ui)", ctx->width, ctx->height, ctx->duration, ctx->frame_rate, ngx_rtmp_get_video_codec_name(ctx->video_codec_id), diff --git a/ngx_rtmp_codec_module.h b/ngx_rtmp_codec_module.h index ee48c1c..831f02b 100644 --- a/ngx_rtmp_codec_module.h +++ b/ngx_rtmp_codec_module.h @@ -53,7 +53,7 @@ typedef struct { ngx_uint_t width; ngx_uint_t height; ngx_uint_t duration; - ngx_uint_t frame_rate; + double frame_rate; ngx_uint_t video_data_rate; ngx_uint_t video_codec_id; ngx_uint_t audio_data_rate; diff --git a/ngx_rtmp_stat_module.c b/ngx_rtmp_stat_module.c index 326a811..e6d62ce 100644 --- a/ngx_rtmp_stat_module.c +++ b/ngx_rtmp_stat_module.c @@ -509,7 +509,7 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll, "%ui", codec->height) - buf); NGX_RTMP_STAT_L(""); NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf), - "%ui", codec->frame_rate) - buf); + "%.3f", codec->frame_rate) - buf); NGX_RTMP_STAT_L(""); cname = ngx_rtmp_get_video_codec_name(codec->video_codec_id);