正在显示
6 个修改的文件
包含
35 行增加
和
43 行删除
@@ -765,7 +765,9 @@ About the HLS overhead of SRS, we compare the overhead to FLV by remux the HLS t | @@ -765,7 +765,9 @@ About the HLS overhead of SRS, we compare the overhead to FLV by remux the HLS t | ||
765 | | 5147kbps | 370s | 195040 | 200280 | 2.68% | | 765 | | 5147kbps | 370s | 195040 | 200280 | 2.68% | |
766 | | 5158kbps | 1327s | 835664 | 858092 | 2.68% | | 766 | | 5158kbps | 1327s | 835664 | 858092 | 2.68% | |
767 | 767 | ||
768 | -The HLS overhead is calc by: (HLS - FLV) / FLV * 100% | 768 | +The HLS overhead is calc by: (HLS - FLV) / FLV * 100%. |
769 | + | ||
770 | +The overhead is larger than this benchmark(48kbps audio is best overhead), for we fix the [#512][bug#512]. | ||
769 | 771 | ||
770 | ## Architecture | 772 | ## Architecture |
771 | 773 | ||
@@ -1193,6 +1195,8 @@ Winlin | @@ -1193,6 +1195,8 @@ Winlin | ||
1193 | [bug #59]: https://github.com/simple-rtmp-server/srs/issues/59 | 1195 | [bug #59]: https://github.com/simple-rtmp-server/srs/issues/59 |
1194 | [bug #50]: https://github.com/simple-rtmp-server/srs/issues/50 | 1196 | [bug #50]: https://github.com/simple-rtmp-server/srs/issues/50 |
1195 | [bug #34]: https://github.com/simple-rtmp-server/srs/issues/34 | 1197 | [bug #34]: https://github.com/simple-rtmp-server/srs/issues/34 |
1198 | +[bug #512]: https://github.com/simple-rtmp-server/srs/issues/512 | ||
1199 | +[bug #xxxxxxxxxx]: https://github.com/simple-rtmp-server/srs/issues/xxxxxxxxxx | ||
1196 | 1200 | ||
1197 | [r2.0a2]: https://github.com/simple-rtmp-server/srs/releases/tag/v2.0-a2 | 1201 | [r2.0a2]: https://github.com/simple-rtmp-server/srs/releases/tag/v2.0-a2 |
1198 | [r2.0a1]: https://github.com/simple-rtmp-server/srs/releases/tag/2.0a1 | 1202 | [r2.0a1]: https://github.com/simple-rtmp-server/srs/releases/tag/2.0a1 |
@@ -646,6 +646,11 @@ int SrsHlsMuxer::update_acodec(SrsCodecAudio ac) | @@ -646,6 +646,11 @@ int SrsHlsMuxer::update_acodec(SrsCodecAudio ac) | ||
646 | return current->muxer->update_acodec(ac); | 646 | return current->muxer->update_acodec(ac); |
647 | } | 647 | } |
648 | 648 | ||
649 | +bool SrsHlsMuxer::pure_audio() | ||
650 | +{ | ||
651 | + return current && current->muxer && current->muxer->video_codec() == SrsCodecVideoDisabled; | ||
652 | +} | ||
653 | + | ||
649 | int SrsHlsMuxer::flush_audio(SrsTsCache* cache) | 654 | int SrsHlsMuxer::flush_audio(SrsTsCache* cache) |
650 | { | 655 | { |
651 | int ret = ERROR_SUCCESS; | 656 | int ret = ERROR_SUCCESS; |
@@ -1049,25 +1054,6 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1049,25 +1054,6 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
1049 | return ret; | 1054 | return ret; |
1050 | } | 1055 | } |
1051 | 1056 | ||
1052 | - // flush if buffer exceed max size. | ||
1053 | - if (cache->audio->payload->length() > SRS_AUTO_HLS_AUDIO_CACHE_SIZE) { | ||
1054 | - if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) { | ||
1055 | - return ret; | ||
1056 | - } | ||
1057 | - } | ||
1058 | - | ||
1059 | - // TODO: config it. | ||
1060 | - // in ms, audio delay to flush the audios. | ||
1061 | - int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY; | ||
1062 | - // flush if audio delay exceed | ||
1063 | - // cache->audio will be free in flush_audio | ||
1064 | - // so we must check whether it's null ptr. | ||
1065 | - if (cache->audio && pts - cache->audio->start_pts > audio_delay * 90) { | ||
1066 | - if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) { | ||
1067 | - return ret; | ||
1068 | - } | ||
1069 | - } | ||
1070 | - | ||
1071 | // reap when current source is pure audio. | 1057 | // reap when current source is pure audio. |
1072 | // it maybe changed when stream info changed, | 1058 | // it maybe changed when stream info changed, |
1073 | // for example, pure audio when start, audio/video when publishing, | 1059 | // for example, pure audio when start, audio/video when publishing, |
@@ -1083,6 +1069,14 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1083,6 +1069,14 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
1083 | } | 1069 | } |
1084 | } | 1070 | } |
1085 | 1071 | ||
1072 | + // directly write the audio frame by frame to ts, | ||
1073 | + // it's ok for the hls overload, or maybe cause the audio corrupt, | ||
1074 | + // which introduced by aggregate the audios to a big one. | ||
1075 | + // @see https://github.com/simple-rtmp-server/srs/issues/512 | ||
1076 | + if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) { | ||
1077 | + return ret; | ||
1078 | + } | ||
1079 | + | ||
1086 | return ret; | 1080 | return ret; |
1087 | } | 1081 | } |
1088 | 1082 | ||
@@ -1100,7 +1094,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1100,7 +1094,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
1100 | // do reap ts if any of: | 1094 | // do reap ts if any of: |
1101 | // a. wait keyframe and got keyframe. | 1095 | // a. wait keyframe and got keyframe. |
1102 | // b. always reap when not wait keyframe. | 1096 | // b. always reap when not wait keyframe. |
1103 | - if (!muxer->wait_keyframe()|| sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { | 1097 | + if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { |
1104 | // when wait keyframe, there must exists idr frame in sample. | 1098 | // when wait keyframe, there must exists idr frame in sample. |
1105 | if (!sample->has_idr && muxer->wait_keyframe()) { | 1099 | if (!sample->has_idr && muxer->wait_keyframe()) { |
1106 | srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr); | 1100 | srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr); |
@@ -1110,9 +1104,6 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1110,9 +1104,6 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
1110 | if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) { | 1104 | if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) { |
1111 | return ret; | 1105 | return ret; |
1112 | } | 1106 | } |
1113 | - | ||
1114 | - // the video must be flushed, just return. | ||
1115 | - return ret; | ||
1116 | } | 1107 | } |
1117 | } | 1108 | } |
1118 | 1109 |
@@ -309,6 +309,10 @@ public: | @@ -309,6 +309,10 @@ public: | ||
309 | virtual bool is_segment_absolutely_overflow(); | 309 | virtual bool is_segment_absolutely_overflow(); |
310 | public: | 310 | public: |
311 | virtual int update_acodec(SrsCodecAudio ac); | 311 | virtual int update_acodec(SrsCodecAudio ac); |
312 | + /** | ||
313 | + * whether current hls muxer is pure audio mode. | ||
314 | + */ | ||
315 | + virtual bool pure_audio(); | ||
312 | virtual int flush_audio(SrsTsCache* cache); | 316 | virtual int flush_audio(SrsTsCache* cache); |
313 | virtual int flush_video(SrsTsCache* cache); | 317 | virtual int flush_video(SrsTsCache* cache); |
314 | /** | 318 | /** |
@@ -246,12 +246,6 @@ extern int aac_sample_rates[]; | @@ -246,12 +246,6 @@ extern int aac_sample_rates[]; | ||
246 | #define SRS_SRS_MAX_CODEC_SAMPLE 128 | 246 | #define SRS_SRS_MAX_CODEC_SAMPLE 128 |
247 | #define SRS_AAC_SAMPLE_RATE_UNSET 15 | 247 | #define SRS_AAC_SAMPLE_RATE_UNSET 15 |
248 | 248 | ||
249 | -// in ms, for HLS aac flush the audio | ||
250 | -#define SRS_CONF_DEFAULT_AAC_DELAY 60 | ||
251 | - | ||
252 | -// max PES packets size to flush the video. | ||
253 | -#define SRS_AUTO_HLS_AUDIO_CACHE_SIZE 128 * 1024 | ||
254 | - | ||
255 | /** | 249 | /** |
256 | * the FLV/RTMP supported audio sample size. | 250 | * the FLV/RTMP supported audio sample size. |
257 | * Size of each audio sample. This parameter only pertains to | 251 | * Size of each audio sample. This parameter only pertains to |
@@ -2760,6 +2760,11 @@ void SrsTSMuxer::close() | @@ -2760,6 +2760,11 @@ void SrsTSMuxer::close() | ||
2760 | writer->close(); | 2760 | writer->close(); |
2761 | } | 2761 | } |
2762 | 2762 | ||
2763 | +SrsCodecVideo SrsTSMuxer::video_codec() | ||
2764 | +{ | ||
2765 | + return vcodec; | ||
2766 | +} | ||
2767 | + | ||
2763 | SrsTsCache::SrsTsCache() | 2768 | SrsTsCache::SrsTsCache() |
2764 | { | 2769 | { |
2765 | audio = NULL; | 2770 | audio = NULL; |
@@ -3134,20 +3139,9 @@ int SrsTsEncoder::write_audio(int64_t timestamp, char* data, int size) | @@ -3134,20 +3139,9 @@ int SrsTsEncoder::write_audio(int64_t timestamp, char* data, int size) | ||
3134 | return ret; | 3139 | return ret; |
3135 | } | 3140 | } |
3136 | 3141 | ||
3137 | - // flush if buffer exceed max size. | ||
3138 | - if (cache->audio->payload->length() > SRS_AUTO_HLS_AUDIO_CACHE_SIZE) { | ||
3139 | - return flush_video(); | ||
3140 | - } | ||
3141 | - | ||
3142 | - // TODO: config it. | ||
3143 | - // in ms, audio delay to flush the audios. | ||
3144 | - int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY; | ||
3145 | - // flush if audio delay exceed | ||
3146 | - if (dts - cache->audio->start_pts > audio_delay * 90) { | 3142 | + // always flush audio frame by frame. |
3143 | + // @see https://github.com/simple-rtmp-server/srs/issues/512 | ||
3147 | return flush_audio(); | 3144 | return flush_audio(); |
3148 | - } | ||
3149 | - | ||
3150 | - return ret; | ||
3151 | } | 3145 | } |
3152 | 3146 | ||
3153 | int SrsTsEncoder::write_video(int64_t timestamp, char* data, int size) | 3147 | int SrsTsEncoder::write_video(int64_t timestamp, char* data, int size) |
@@ -1586,6 +1586,11 @@ public: | @@ -1586,6 +1586,11 @@ public: | ||
1586 | * close the writer. | 1586 | * close the writer. |
1587 | */ | 1587 | */ |
1588 | virtual void close(); | 1588 | virtual void close(); |
1589 | +public: | ||
1590 | + /** | ||
1591 | + * get the video codec of ts muxer. | ||
1592 | + */ | ||
1593 | + virtual SrsCodecVideo video_codec(); | ||
1589 | }; | 1594 | }; |
1590 | 1595 | ||
1591 | /** | 1596 | /** |
-
请 注册 或 登录 后发表评论