From 3ad030fe83b456ab4568beee2193b9c50f52d8cd Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 29 May 2015 17:56:05 +0800 Subject: [PATCH 1/2] add HLS overload --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 14259dd73..13f75ac59 100755 --- a/README.md +++ b/README.md @@ -731,7 +731,7 @@ The latency between encoder and player with realtime config( [CN](https://github.com/simple-rtmp-server/srs/wiki/v2_CN_LowLatency), [EN](https://github.com/simple-rtmp-server/srs/wiki/v2_EN_LowLatency) ): - +| | Update | SRS | VP6 | H.264 | VP6+MP3 | H.264+MP3 | | ------------- | --------- | --------- | --------- | --------- | -------- | @@ -743,6 +743,32 @@ We use FMLE as encoder for benchmark. The latency of server is 0.1s+, and the bottleneck is the encoder. For more information, read [bug #257](https://github.com/simple-rtmp-server/srs/issues/257#issuecomment-66864413). +### HLS overhead + +About the HLS overhead of SRS, we compare the overhead to FLV by remux the HLS to FLV by ffmpeg. + +| Bitrate | Duration | FLV(KB) | HLS(KB) | Overhead | +| ------- | -------- | ------- | -------- | --------- | +| 275kbps | 600s | 11144 | 12756 | 14.46% | +| 260kbps | 1860s | 59344 | 68004 | 14.59% | +| 697kbps | 60s | 5116 | 5476 | 7.03% | +| 565kbps | 453s | 31316 | 33544 | 7.11% | +| 565kbps | 1813s | 125224 | 134140 | 7.12% | +| 861kbps | 497s | 52316 | 54924 | 4.98% | +| 857kbps | 1862s | 195008 | 204768 | 5.00% | +| 1301kbps | 505s | 80320 | 83676 | 4.17% | +| 1312kbps | 1915s | 306920 | 319680 | 4.15% | +| 2707kbps | 600s | 198356 | 204560 | 3.12% | +| 2814kbps | 1800s | 618456 | 637660 | 3.10% | +| 2828kbps | 60s | 20716 | 21356 | 3.08% | +| 2599kbps | 307s | 97580 | 100672 | 3.16% | +| 2640kbps | 1283s | 413880 | 426912 | 3.14% | +| 5254kbps | 71s | 45832 | 47056 | 2.67% | +| 5147kbps | 370s | 195040 | 200280 | 2.68% | +| 5158kbps | 1327s | 835664 | 858092 | 2.68% | + +The HLS overhead is calc by: (HLS - FLV) / FLV * 100% + ## Architecture SRS always use the most simple architecture to support complex transaction. From 5caafadd451b15088fc47d8fd7cc3668b1f399ca Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 29 May 2015 21:43:17 +0800 Subject: [PATCH 2/2] fix #409: support pure video hls. 2.0.172. --- README.md | 1 + trunk/conf/full.conf | 2 +- trunk/src/app/srs_app_hls.cpp | 3 +++ trunk/src/core/srs_core.hpp | 2 +- trunk/src/kernel/srs_kernel_codec.hpp | 3 +++ trunk/src/kernel/srs_kernel_error.hpp | 2 +- trunk/src/kernel/srs_kernel_ts.cpp | 31 +++++++++++++++++++++------ 7 files changed, 35 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 13f75ac59..554c1da8d 100755 --- a/README.md +++ b/README.md @@ -342,6 +342,7 @@ Remark: ## History ### SRS 2.0 history +* v2.0, 2015-05-29, fix [#409](https://github.com/simple-rtmp-server/srs/issues/409) support pure video hls. 2.0.172. * v2.0, 2015-05-28, support [srs-dolphin][srs-dolphin], the multiple-process SRS. * v2.0, 2015-05-24, fix [#404](https://github.com/simple-rtmp-server/srs/issues/404) register handler then start http thread. 2.0.167. * v2.0, 2015-05-23, refine the thread, protocol, kbps code. 2.0.166 diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index bab1433de..211a2d1d8 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -608,7 +608,7 @@ vhost with-hls.srs.com { # when codec changed, write the PAT/PMT table, but maybe ok util next ts. # so user can set the default codec for mp3. # the available audio codec: - # aac, mp3 + # aac, mp3, an # default: aac hls_acodec aac; # the default video codec of hls. diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index 46af33a29..a11711b1a 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -420,6 +420,9 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) } else if (default_acodec_str == "aac") { default_acodec = SrsCodecAudioAAC; srs_info("hls: use default aac acodec"); + } else if (default_acodec_str == "an") { + default_acodec = SrsCodecAudioDisabled; + srs_info("hls: use default an acodec for pure video"); } else { srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str()); } diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index aaf72ac9c..277308c91 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR 2 #define VERSION_MINOR 0 -#define VERSION_REVISION 171 +#define VERSION_REVISION 172 // server info. #define RTMP_SIG_SRS_KEY "SRS" diff --git a/trunk/src/kernel/srs_kernel_codec.hpp b/trunk/src/kernel/srs_kernel_codec.hpp index e45493c4d..702106101 100644 --- a/trunk/src/kernel/srs_kernel_codec.hpp +++ b/trunk/src/kernel/srs_kernel_codec.hpp @@ -136,6 +136,9 @@ enum SrsCodecAudio // set to the max value to reserved, for array map. SrsCodecAudioReserved1 = 16, + // for user to disable audio, for example, use pure video hls. + SrsCodecAudioDisabled = 17, + SrsCodecAudioLinearPCMPlatformEndian = 0, SrsCodecAudioADPCM = 1, SrsCodecAudioMP3 = 2, diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 11f3e35b6..dec0f3f72 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -215,13 +215,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_HTTP_DVR_CREATE_REQUEST 3053 #define ERROR_HTTP_DVR_NO_TAEGET 3054 #define ERROR_ADTS_ID_NOT_AAC 3055 -// HDS error code #define ERROR_HDS_OPEN_F4M_FAILED 3056 #define ERROR_HDS_WRITE_F4M_FAILED 3057 #define ERROR_HDS_OPEN_BOOTSTRAP_FAILED 3058 #define ERROR_HDS_WRITE_BOOTSTRAP_FAILED 3059 #define ERROR_HDS_OPEN_FRAGMENT_FAILED 3060 #define ERROR_HDS_WRITE_FRAGMENT_FAILED 3061 +#define ERROR_HLS_NO_STREAM 3062 /////////////////////////////////////////////////////// // HTTP/StreamCaster protocol error. diff --git a/trunk/src/kernel/srs_kernel_ts.cpp b/trunk/src/kernel/srs_kernel_ts.cpp index 243c2ec76..64a7a1140 100644 --- a/trunk/src/kernel/srs_kernel_ts.cpp +++ b/trunk/src/kernel/srs_kernel_ts.cpp @@ -302,10 +302,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo vs = SrsTsStreamVideoH264; video_pid = TS_VIDEO_AVC_PID; break; + case SrsCodecVideoDisabled: + vs = SrsTsStreamReserved; + break; case SrsCodecVideoReserved: case SrsCodecVideoReserved1: case SrsCodecVideoReserved2: - case SrsCodecVideoDisabled: case SrsCodecVideoSorensonH263: case SrsCodecVideoScreenVideo: case SrsCodecVideoOn2VP6: @@ -323,6 +325,9 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo as = SrsTsStreamAudioMp3; audio_pid = TS_AUDIO_MP3_PID; break; + case SrsCodecAudioDisabled: + as = SrsTsStreamReserved; + break; case SrsCodecAudioReserved1: case SrsCodecAudioLinearPCMPlatformEndian: case SrsCodecAudioADPCM: @@ -340,6 +345,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo break; } + if (as == SrsTsStreamReserved && vs == SrsTsStreamReserved) { + ret = ERROR_HLS_NO_STREAM; + srs_error("hls: no video or audio stream, vcodec=%d, acodec=%d. ret=%d", vc, ac, ret); + return ret; + } + // when any codec changed, write PAT/PMT table. if (vcodec != vc || acodec != ac) { vcodec = vc; @@ -360,6 +371,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo int SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as) { int ret = ERROR_SUCCESS; + + if (vs != SrsTsStreamVideoH264 && as != SrsTsStreamAudioAAC && as != SrsTsStreamAudioMp3) { + ret = ERROR_HLS_NO_STREAM; + srs_error("hls: no pmt pcr pid, vs=%d, as=%d. ret=%d", vs, as, ret); + return ret; + } int16_t pmt_number = TS_PMT_NUMBER; int16_t pmt_pid = TS_PMT_PID; @@ -754,15 +771,17 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number, pmt->last_section_number = 0; pmt->program_info_length = 0; - // use audio to carray pcr by default. - // for hls, there must be atleast one audio channel. - pmt->PCR_PID = apid; - pmt->infos.push_back(new SrsTsPayloadPMTESInfo(as, apid)); - // if h.264 specified, use video to carry pcr. if (vs == SrsTsStreamVideoH264) { pmt->PCR_PID = vpid; pmt->infos.push_back(new SrsTsPayloadPMTESInfo(vs, vpid)); + } else if (as == SrsTsStreamAudioAAC || as == SrsTsStreamAudioMp3) { + // use audio to carray pcr by default. + // for hls, there must be atleast one audio channel. + pmt->PCR_PID = apid; + pmt->infos.push_back(new SrsTsPayloadPMTESInfo(as, apid)); + } else { + srs_assert(false); } pmt->CRC_32 = 0; // calc in encode.