正在显示
6 个修改的文件
包含
59 行增加
和
46 行删除
| @@ -814,7 +814,9 @@ About the HLS overhead of SRS, we compare the overhead to FLV by remux the HLS t | @@ -814,7 +814,9 @@ About the HLS overhead of SRS, we compare the overhead to FLV by remux the HLS t | ||
| 814 | | 5147kbps | 370s | 195040 | 200280 | 2.68% | | 814 | | 5147kbps | 370s | 195040 | 200280 | 2.68% | |
| 815 | | 5158kbps | 1327s | 835664 | 858092 | 2.68% | | 815 | | 5158kbps | 1327s | 835664 | 858092 | 2.68% | |
| 816 | 816 | ||
| 817 | -The HLS overhead is calc by: (HLS - FLV) / FLV * 100% | 817 | +The HLS overhead is calc by: (HLS - FLV) / FLV * 100%. |
| 818 | + | ||
| 819 | +The overhead is larger than this benchmark(48kbps audio is best overhead), for we fix the [#512][bug#512]. | ||
| 818 | 820 | ||
| 819 | ## Architecture | 821 | ## Architecture |
| 820 | 822 | ||
| @@ -1265,6 +1267,7 @@ Winlin | @@ -1265,6 +1267,7 @@ Winlin | ||
| 1265 | [bug #59]: https://github.com/simple-rtmp-server/srs/issues/59 | 1267 | [bug #59]: https://github.com/simple-rtmp-server/srs/issues/59 |
| 1266 | [bug #50]: https://github.com/simple-rtmp-server/srs/issues/50 | 1268 | [bug #50]: https://github.com/simple-rtmp-server/srs/issues/50 |
| 1267 | [bug #34]: https://github.com/simple-rtmp-server/srs/issues/34 | 1269 | [bug #34]: https://github.com/simple-rtmp-server/srs/issues/34 |
| 1270 | +<<<<<<< HEAD | ||
| 1268 | [bug #367]: https://github.com/simple-rtmp-server/srs/issues/367 | 1271 | [bug #367]: https://github.com/simple-rtmp-server/srs/issues/367 |
| 1269 | [bug #319]: https://github.com/simple-rtmp-server/srs/issues/319 | 1272 | [bug #319]: https://github.com/simple-rtmp-server/srs/issues/319 |
| 1270 | [bug #367]: https://github.com/simple-rtmp-server/srs/issues/367 | 1273 | [bug #367]: https://github.com/simple-rtmp-server/srs/issues/367 |
| @@ -1282,6 +1285,10 @@ Winlin | @@ -1282,6 +1285,10 @@ Winlin | ||
| 1282 | [bug #502]: https://github.com/simple-rtmp-server/srs/issues/502 | 1285 | [bug #502]: https://github.com/simple-rtmp-server/srs/issues/502 |
| 1283 | [bug #467]: https://github.com/simple-rtmp-server/srs/issues/467 | 1286 | [bug #467]: https://github.com/simple-rtmp-server/srs/issues/467 |
| 1284 | [bug #xxxxxxx]: https://github.com/simple-rtmp-server/srs/issues/xxxxxxx | 1287 | [bug #xxxxxxx]: https://github.com/simple-rtmp-server/srs/issues/xxxxxxx |
| 1288 | +======= | ||
| 1289 | +[bug #512]: https://github.com/simple-rtmp-server/srs/issues/512 | ||
| 1290 | +[bug #xxxxxxxxxx]: https://github.com/simple-rtmp-server/srs/issues/xxxxxxxxxx | ||
| 1291 | +>>>>>>> 2.0release | ||
| 1285 | 1292 | ||
| 1286 | [r2.0a2]: https://github.com/simple-rtmp-server/srs/releases/tag/v2.0-a2 | 1293 | [r2.0a2]: https://github.com/simple-rtmp-server/srs/releases/tag/v2.0-a2 |
| 1287 | [r2.0a1]: https://github.com/simple-rtmp-server/srs/releases/tag/2.0a1 | 1294 | [r2.0a1]: https://github.com/simple-rtmp-server/srs/releases/tag/2.0a1 |
| @@ -578,6 +578,7 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) | @@ -578,6 +578,7 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) | ||
| 578 | current->full_path.c_str(), tmp_file.c_str()); | 578 | current->full_path.c_str(), tmp_file.c_str()); |
| 579 | 579 | ||
| 580 | // set the segment muxer audio codec. | 580 | // set the segment muxer audio codec. |
| 581 | + // TODO: FIXME: refine code, use event instead. | ||
| 581 | if (acodec != SrsCodecAudioReserved1) { | 582 | if (acodec != SrsCodecAudioReserved1) { |
| 582 | current->muxer->update_acodec(acodec); | 583 | current->muxer->update_acodec(acodec); |
| 583 | } | 584 | } |
| @@ -646,6 +647,11 @@ int SrsHlsMuxer::update_acodec(SrsCodecAudio ac) | @@ -646,6 +647,11 @@ int SrsHlsMuxer::update_acodec(SrsCodecAudio ac) | ||
| 646 | return current->muxer->update_acodec(ac); | 647 | return current->muxer->update_acodec(ac); |
| 647 | } | 648 | } |
| 648 | 649 | ||
| 650 | +bool SrsHlsMuxer::pure_audio() | ||
| 651 | +{ | ||
| 652 | + return current && current->muxer && current->muxer->video_codec() == SrsCodecVideoDisabled; | ||
| 653 | +} | ||
| 654 | + | ||
| 649 | int SrsHlsMuxer::flush_audio(SrsTsCache* cache) | 655 | int SrsHlsMuxer::flush_audio(SrsTsCache* cache) |
| 650 | { | 656 | { |
| 651 | int ret = ERROR_SUCCESS; | 657 | int ret = ERROR_SUCCESS; |
| @@ -1049,25 +1055,6 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1049,25 +1055,6 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
| 1049 | return ret; | 1055 | return ret; |
| 1050 | } | 1056 | } |
| 1051 | 1057 | ||
| 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. | 1058 | // reap when current source is pure audio. |
| 1072 | // it maybe changed when stream info changed, | 1059 | // it maybe changed when stream info changed, |
| 1073 | // for example, pure audio when start, audio/video when publishing, | 1060 | // for example, pure audio when start, audio/video when publishing, |
| @@ -1083,6 +1070,21 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1083,6 +1070,21 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
| 1083 | } | 1070 | } |
| 1084 | } | 1071 | } |
| 1085 | 1072 | ||
| 1073 | + // for pure audio, aggregate some frame to one. | ||
| 1074 | + if (muxer->pure_audio() && cache->audio) { | ||
| 1075 | + if (pts - cache->audio->start_pts < SRS_CONSTS_HLS_PURE_AUDIO_AGGREGATE) { | ||
| 1076 | + return ret; | ||
| 1077 | + } | ||
| 1078 | + } | ||
| 1079 | + | ||
| 1080 | + // directly write the audio frame by frame to ts, | ||
| 1081 | + // it's ok for the hls overload, or maybe cause the audio corrupt, | ||
| 1082 | + // which introduced by aggregate the audios to a big one. | ||
| 1083 | + // @see https://github.com/simple-rtmp-server/srs/issues/512 | ||
| 1084 | + if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) { | ||
| 1085 | + return ret; | ||
| 1086 | + } | ||
| 1087 | + | ||
| 1086 | return ret; | 1088 | return ret; |
| 1087 | } | 1089 | } |
| 1088 | 1090 | ||
| @@ -1100,7 +1102,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1100,7 +1102,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
| 1100 | // do reap ts if any of: | 1102 | // do reap ts if any of: |
| 1101 | // a. wait keyframe and got keyframe. | 1103 | // a. wait keyframe and got keyframe. |
| 1102 | // b. always reap when not wait keyframe. | 1104 | // b. always reap when not wait keyframe. |
| 1103 | - if (!muxer->wait_keyframe()|| sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { | 1105 | + if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { |
| 1104 | // when wait keyframe, there must exists idr frame in sample. | 1106 | // when wait keyframe, there must exists idr frame in sample. |
| 1105 | if (!sample->has_idr && muxer->wait_keyframe()) { | 1107 | 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); | 1108 | srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr); |
| @@ -1110,9 +1112,6 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1110,9 +1112,6 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
| 1110 | if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) { | 1112 | if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) { |
| 1111 | return ret; | 1113 | return ret; |
| 1112 | } | 1114 | } |
| 1113 | - | ||
| 1114 | - // the video must be flushed, just return. | ||
| 1115 | - return ret; | ||
| 1116 | } | 1115 | } |
| 1117 | } | 1116 | } |
| 1118 | 1117 |
| @@ -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 |
| @@ -469,8 +469,11 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p | @@ -469,8 +469,11 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p | ||
| 469 | while (p < end) { | 469 | while (p < end) { |
| 470 | SrsTsPacket* pkt = NULL; | 470 | SrsTsPacket* pkt = NULL; |
| 471 | if (p == start) { | 471 | if (p == start) { |
| 472 | - // for pure audio stream, always write pcr. | 472 | + // write pcr according to message. |
| 473 | bool write_pcr = msg->write_pcr; | 473 | bool write_pcr = msg->write_pcr; |
| 474 | + | ||
| 475 | + // for pure audio, always write pcr. | ||
| 476 | + // TODO: FIXME: maybe only need to write at begin and end of ts. | ||
| 474 | if (pure_audio && msg->is_audio()) { | 477 | if (pure_audio && msg->is_audio()) { |
| 475 | write_pcr = true; | 478 | write_pcr = true; |
| 476 | } | 479 | } |
| @@ -2772,6 +2775,11 @@ void SrsTSMuxer::close() | @@ -2772,6 +2775,11 @@ void SrsTSMuxer::close() | ||
| 2772 | writer->close(); | 2775 | writer->close(); |
| 2773 | } | 2776 | } |
| 2774 | 2777 | ||
| 2778 | +SrsCodecVideo SrsTSMuxer::video_codec() | ||
| 2779 | +{ | ||
| 2780 | + return vcodec; | ||
| 2781 | +} | ||
| 2782 | + | ||
| 2775 | SrsTsCache::SrsTsCache() | 2783 | SrsTsCache::SrsTsCache() |
| 2776 | { | 2784 | { |
| 2777 | audio = NULL; | 2785 | audio = NULL; |
| @@ -2792,11 +2800,12 @@ int SrsTsCache::cache_audio(SrsAvcAacCodec* codec, int64_t dts, SrsCodecSample* | @@ -2792,11 +2800,12 @@ int SrsTsCache::cache_audio(SrsAvcAacCodec* codec, int64_t dts, SrsCodecSample* | ||
| 2792 | if (!audio) { | 2800 | if (!audio) { |
| 2793 | audio = new SrsTsMessage(); | 2801 | audio = new SrsTsMessage(); |
| 2794 | audio->write_pcr = false; | 2802 | audio->write_pcr = false; |
| 2795 | - audio->start_pts = dts; | 2803 | + audio->dts = audio->pts = audio->start_pts = dts; |
| 2796 | } | 2804 | } |
| 2797 | 2805 | ||
| 2798 | - audio->dts = dts; | ||
| 2799 | - audio->pts = audio->dts; | 2806 | + // TODO: FIXME: refine code. |
| 2807 | + //audio->dts = dts; | ||
| 2808 | + //audio->pts = audio->dts; | ||
| 2800 | audio->sid = SrsTsPESStreamIdAudioCommon; | 2809 | audio->sid = SrsTsPESStreamIdAudioCommon; |
| 2801 | 2810 | ||
| 2802 | // must be aac or mp3 | 2811 | // must be aac or mp3 |
| @@ -3146,20 +3155,11 @@ int SrsTsEncoder::write_audio(int64_t timestamp, char* data, int size) | @@ -3146,20 +3155,11 @@ int SrsTsEncoder::write_audio(int64_t timestamp, char* data, int size) | ||
| 3146 | return ret; | 3155 | return ret; |
| 3147 | } | 3156 | } |
| 3148 | 3157 | ||
| 3149 | - // flush if buffer exceed max size. | ||
| 3150 | - if (cache->audio->payload->length() > SRS_AUTO_HLS_AUDIO_CACHE_SIZE) { | ||
| 3151 | - return flush_video(); | ||
| 3152 | - } | 3158 | + // TODO: FIXME: for pure audio, aggregate some frame to one. |
| 3153 | 3159 | ||
| 3154 | - // TODO: config it. | ||
| 3155 | - // in ms, audio delay to flush the audios. | ||
| 3156 | - int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY; | ||
| 3157 | - // flush if audio delay exceed | ||
| 3158 | - if (dts - cache->audio->start_pts > audio_delay * 90) { | 3160 | + // always flush audio frame by frame. |
| 3161 | + // @see https://github.com/simple-rtmp-server/srs/issues/512 | ||
| 3159 | return flush_audio(); | 3162 | return flush_audio(); |
| 3160 | - } | ||
| 3161 | - | ||
| 3162 | - return ret; | ||
| 3163 | } | 3163 | } |
| 3164 | 3164 | ||
| 3165 | int SrsTsEncoder::write_video(int64_t timestamp, char* data, int size) | 3165 | int SrsTsEncoder::write_video(int64_t timestamp, char* data, int size) |
| @@ -54,6 +54,9 @@ class SrsTsContext; | @@ -54,6 +54,9 @@ class SrsTsContext; | ||
| 54 | // Transport Stream packets are 188 bytes in length. | 54 | // Transport Stream packets are 188 bytes in length. |
| 55 | #define SRS_TS_PACKET_SIZE 188 | 55 | #define SRS_TS_PACKET_SIZE 188 |
| 56 | 56 | ||
| 57 | +// the aggregate pure audio for hls, in ts tbn(ms * 90). | ||
| 58 | +#define SRS_CONSTS_HLS_PURE_AUDIO_AGGREGATE 720 * 90 | ||
| 59 | + | ||
| 57 | /** | 60 | /** |
| 58 | * the pid of ts packet, | 61 | * the pid of ts packet, |
| 59 | * Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37 | 62 | * Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37 |
| @@ -360,6 +363,7 @@ public: | @@ -360,6 +363,7 @@ public: | ||
| 360 | /** | 363 | /** |
| 361 | * whether the hls stream is pure audio stream. | 364 | * whether the hls stream is pure audio stream. |
| 362 | */ | 365 | */ |
| 366 | + // TODO: FIXME: merge with muxer codec detect. | ||
| 363 | virtual bool is_pure_audio(); | 367 | virtual bool is_pure_audio(); |
| 364 | /** | 368 | /** |
| 365 | * when PMT table parsed, we know some info about stream. | 369 | * when PMT table parsed, we know some info about stream. |
| @@ -1594,6 +1598,11 @@ public: | @@ -1594,6 +1598,11 @@ public: | ||
| 1594 | * close the writer. | 1598 | * close the writer. |
| 1595 | */ | 1599 | */ |
| 1596 | virtual void close(); | 1600 | virtual void close(); |
| 1601 | +public: | ||
| 1602 | + /** | ||
| 1603 | + * get the video codec of ts muxer. | ||
| 1604 | + */ | ||
| 1605 | + virtual SrsCodecVideo video_codec(); | ||
| 1597 | }; | 1606 | }; |
| 1598 | 1607 | ||
| 1599 | /** | 1608 | /** |
-
请 注册 或 登录 后发表评论