From 9177be55dd46cd3c2831e612c60ee3ffdc0065be Mon Sep 17 00:00:00 2001 From: Stephen Basile Date: Wed, 9 Oct 2013 16:12:47 -0400 Subject: [PATCH] MPD tweaks and stubbed out MP3 support --- hls/ngx_rtmp_dash_module.c | 42 ++++++++++++++++++++++++++------------ hls/ngx_rtmp_mp4.c | 20 ++++++++++-------- hls/ngx_rtmp_mp4.h | 1 + 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/hls/ngx_rtmp_dash_module.c b/hls/ngx_rtmp_dash_module.c index 210f456..386ec42 100644 --- a/hls/ngx_rtmp_dash_module.c +++ b/hls/ngx_rtmp_dash_module.c @@ -223,10 +223,10 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) #define NGX_RTMP_DASH_MANIFEST_HEADER \ "\n" \ "\n" \ - " \n" + "availabilityStartTime=\"%V\" minBufferTime=\"PT3S\" " \ + "timeShiftBufferDepth=\"PT0H0M0.00S\" " \ + "profiles=\"urn:mpeg:dash:profile:isoff-live:2011\">\n " \ + " \n" #define NGX_RTMP_DASH_MANIFEST_VIDEO \ " \n" \ @@ -244,7 +244,7 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) "schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" " \ "value=\"1\"/>\n" \ " \n" \ " sample_rate*(hacf->fraglen/1000)); p = ngx_snprintf(buffer, sizeof(buffer), NGX_RTMP_DASH_MANIFEST_HEADER, - &ctx->start_time); + &ctx->start_time); n = ngx_write_fd(fd, buffer, p - buffer); if (ctx->video) { @@ -273,9 +273,9 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) codec_ctx->width, codec_ctx->height, codec_ctx->frame_rate, - (uint32_t)(live_ctx->stream->bw_in.bandwidth*8), + (ngx_uint_t)(live_ctx->stream->bw_in.bandwidth*8), f->video_earliest_pres_time, - f->id > 0 ? (uint32_t)(f->video_latest_pres_time / + f->id > 0 ? (ngx_uint_t)(f->video_latest_pres_time / f->id) : hacf->fraglen, &ctx->name, &ctx->name); @@ -284,8 +284,10 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) if (ctx->audio) { p = ngx_snprintf(buffer, sizeof(buffer), NGX_RTMP_DASH_MANIFEST_AUDIO, + codec_ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC ? + "40.2" : "6b", codec_ctx->sample_rate, - (uint32_t)(f->audio_earliest_pres_time * + (ngx_uint_t)(f->audio_earliest_pres_time * ((float)codec_ctx->sample_rate/1000.0)), codec_ctx->sample_rate, audio_dur, @@ -368,6 +370,7 @@ ngx_rtmp_dash_write_init_segments(ngx_rtmp_session_t *s) metadata.video = 1; metadata.sample_rate = codec_ctx->sample_rate; metadata.frame_rate = codec_ctx->frame_rate; + metadata.audio_codec = codec_ctx->audio_codec_id; ngx_rtmp_mp4_write_ftyp(b, NGX_RTMP_MP4_FILETYPE_INIT, metadata); ngx_rtmp_mp4_write_moov(s, b, metadata); @@ -901,7 +904,15 @@ ngx_rtmp_dash_audio(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, return NGX_OK; } - if (codec_ctx->audio_codec_id != NGX_RTMP_AUDIO_AAC || + /* Disable MP3 for now + if ((codec_ctx->audio_codec_id != NGX_RTMP_AUDIO_AAC) && + (codec_ctx->audio_codec_id != NGX_RTMP_AUDIO_MP3)) */ + if (codec_ctx->audio_codec_id != NGX_RTMP_AUDIO_AAC) + { + return NGX_OK; + } + + if (codec_ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC && codec_ctx->aac_header == NULL) { return NGX_OK; @@ -918,6 +929,10 @@ ngx_rtmp_dash_audio(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ctx->audio = 1; + if (codec_ctx->audio_codec_id == NGX_RTMP_AUDIO_MP3) { + in->buf->pos += 1; + } + for (; in && out.last < out.end; in = in->next) { bsize = in->buf->last - in->buf->pos; if (bsize < 4) { @@ -926,19 +941,20 @@ ngx_rtmp_dash_audio(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, if (out.last + bsize > out.end) { bsize = out.end - out.last; } - if (*in->buf->pos == 0xAF) { /* rtmp frame header */ + if (codec_ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC && *in->buf->pos == 0xAF) { /* rtmp frame header */ /* rtmp audio frame number--skip 0 */ if (*(in->buf->pos+1) == 0x00) { break; } else { - if (bsize > 2) { + if (bsize > 3) { /* skip two bytes of audio frame header */ in->buf->pos += 2; + /* skip the extra mp3 byte */ } } } - if (!in->next) { + if (!in->next && codec_ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC) { bsize -= 2; /* chop 2 bytes off the end of the frame */ } out.last = ngx_cpymem(out.last, in->buf->pos, bsize); diff --git a/hls/ngx_rtmp_mp4.c b/hls/ngx_rtmp_mp4.c index e2a8c25..9c8ac8a 100644 --- a/hls/ngx_rtmp_mp4.c +++ b/hls/ngx_rtmp_mp4.c @@ -507,7 +507,8 @@ ngx_rtmp_mp4_write_video(ngx_rtmp_session_t *s, ngx_buf_t *b, ngx_int_t -ngx_rtmp_mp4_write_esds(ngx_rtmp_session_t *s, ngx_buf_t *b) +ngx_rtmp_mp4_write_esds(ngx_rtmp_session_t *s, ngx_buf_t *b, + ngx_rtmp_mp4_metadata_t metadata) { u_char *pos; @@ -528,7 +529,7 @@ ngx_rtmp_mp4_write_esds(ngx_rtmp_session_t *s, ngx_buf_t *b) aac_header_offset = 0; } else { - decoder_info = (aac->buf->last-aac->buf->pos)-2; + decoder_info = (aac->buf->last-aac->buf->pos); aac_header_offset = 2; } pos = b->last; @@ -540,17 +541,18 @@ ngx_rtmp_mp4_write_esds(ngx_rtmp_session_t *s, ngx_buf_t *b) ngx_rtmp_mp4_field_32(b, 0); /* version */ /* length of the rest of the box */ - ngx_rtmp_mp4_put_descr(b, 0x03, 23+decoder_info); + ngx_rtmp_mp4_put_descr(b, 0x03, 21+decoder_info); ngx_rtmp_mp4_field_16(b, 1); /* track id */ ngx_rtmp_mp4_field_8(b, 0x00); /* flags */ /* length of the rest of the box */ - ngx_rtmp_mp4_put_descr(b, 0x04, 15+decoder_info); - ngx_rtmp_mp4_field_8(b, 0x40); /* codec id */ + ngx_rtmp_mp4_put_descr(b, 0x04, 13+decoder_info); + ngx_rtmp_mp4_field_8(b, metadata.audio_codec == NGX_RTMP_AUDIO_AAC ? 0x40 : + 0x6B); /* codec id */ ngx_rtmp_mp4_field_8(b, 0x15); /* audio stream */ ngx_rtmp_mp4_field_24(b, 0); /* buffersize? */ - /* bitrate TODO: should probably set it dynamically*/ + /* Next two fields are bitrate. */ ngx_rtmp_mp4_field_32(b, 0x0001F151); - ngx_rtmp_mp4_field_32(b, 0x0001F14D); /* I really dont know */ + ngx_rtmp_mp4_field_32(b, 0x0001F14D); if (aac) { ngx_rtmp_mp4_put_descr(b, 0x05, decoder_info); @@ -592,7 +594,7 @@ ngx_rtmp_mp4_write_audio(ngx_rtmp_session_t *s, ngx_buf_t *b, ngx_rtmp_mp4_field_16(b, metadata.sample_rate); /* sample rate */ ngx_rtmp_mp4_field_16(b, 0); /* reserved */ - ngx_rtmp_mp4_write_esds(s, b); + ngx_rtmp_mp4_write_esds(s, b, metadata); ngx_rtmp_mp4_field_32(b, 8); /* size */ ngx_rtmp_mp4_field_32(b, 0); /* null tag */ @@ -825,7 +827,7 @@ ngx_rtmp_mp4_write_mvex(ngx_buf_t *b, ngx_rtmp_mp4_metadata_t metadata) metadata.frame_rate : NGX_RTMP_MP4_TIMESCALE; } else { - sample_dur = 1024; + sample_dur = metadata.audio_codec == NGX_RTMP_AUDIO_AAC ? 1024 : 1152; } pos = b->last; diff --git a/hls/ngx_rtmp_mp4.h b/hls/ngx_rtmp_mp4.h index bfef725..3226232 100644 --- a/hls/ngx_rtmp_mp4.h +++ b/hls/ngx_rtmp_mp4.h @@ -16,6 +16,7 @@ typedef struct { ngx_uint_t video; ngx_uint_t sample_rate; ngx_uint_t frame_rate; + ngx_uint_t audio_codec; } ngx_rtmp_mp4_metadata_t;