winlin

support pure video hls.

@@ -346,6 +346,7 @@ Remark: @@ -346,6 +346,7 @@ Remark:
346 * v3.0, 2015-03-15, fork srs2 and start srs3. 3.0.0 346 * v3.0, 2015-03-15, fork srs2 and start srs3. 3.0.0
347 347
348 ### SRS 2.0 history 348 ### SRS 2.0 history
  349 +* v2.0, 2015-05-29, fix [#409](https://github.com/simple-rtmp-server/srs/issues/409) support pure video hls. 2.0.172.
349 * v2.0, 2015-05-28, support [srs-dolphin][srs-dolphin], the multiple-process SRS. 350 * v2.0, 2015-05-28, support [srs-dolphin][srs-dolphin], the multiple-process SRS.
350 * 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. 351 * 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.
351 * v2.0, 2015-05-23, refine the thread, protocol, kbps code. 2.0.166 352 * v2.0, 2015-05-23, refine the thread, protocol, kbps code. 2.0.166
@@ -735,7 +736,7 @@ The latency between encoder and player with realtime config( @@ -735,7 +736,7 @@ The latency between encoder and player with realtime config(
735 [CN](https://github.com/simple-rtmp-server/srs/wiki/v2_CN_LowLatency), 736 [CN](https://github.com/simple-rtmp-server/srs/wiki/v2_CN_LowLatency),
736 [EN](https://github.com/simple-rtmp-server/srs/wiki/v2_EN_LowLatency) 737 [EN](https://github.com/simple-rtmp-server/srs/wiki/v2_EN_LowLatency)
737 ): 738 ):
738 - 739 +|
739 740
740 | Update | SRS | VP6 | H.264 | VP6+MP3 | H.264+MP3 | 741 | Update | SRS | VP6 | H.264 | VP6+MP3 | H.264+MP3 |
741 | ------------- | --------- | --------- | --------- | --------- | -------- | 742 | ------------- | --------- | --------- | --------- | --------- | -------- |
@@ -747,6 +748,32 @@ We use FMLE as encoder for benchmark. The latency of server is 0.1s+, @@ -747,6 +748,32 @@ We use FMLE as encoder for benchmark. The latency of server is 0.1s+,
747 and the bottleneck is the encoder. For more information, read 748 and the bottleneck is the encoder. For more information, read
748 [bug #257](https://github.com/simple-rtmp-server/srs/issues/257#issuecomment-66864413). 749 [bug #257](https://github.com/simple-rtmp-server/srs/issues/257#issuecomment-66864413).
749 750
  751 +### HLS overhead
  752 +
  753 +About the HLS overhead of SRS, we compare the overhead to FLV by remux the HLS to FLV by ffmpeg.
  754 +
  755 +| Bitrate | Duration | FLV(KB) | HLS(KB) | Overhead |
  756 +| ------- | -------- | ------- | -------- | --------- |
  757 +| 275kbps | 600s | 11144 | 12756 | 14.46% |
  758 +| 260kbps | 1860s | 59344 | 68004 | 14.59% |
  759 +| 697kbps | 60s | 5116 | 5476 | 7.03% |
  760 +| 565kbps | 453s | 31316 | 33544 | 7.11% |
  761 +| 565kbps | 1813s | 125224 | 134140 | 7.12% |
  762 +| 861kbps | 497s | 52316 | 54924 | 4.98% |
  763 +| 857kbps | 1862s | 195008 | 204768 | 5.00% |
  764 +| 1301kbps | 505s | 80320 | 83676 | 4.17% |
  765 +| 1312kbps | 1915s | 306920 | 319680 | 4.15% |
  766 +| 2707kbps | 600s | 198356 | 204560 | 3.12% |
  767 +| 2814kbps | 1800s | 618456 | 637660 | 3.10% |
  768 +| 2828kbps | 60s | 20716 | 21356 | 3.08% |
  769 +| 2599kbps | 307s | 97580 | 100672 | 3.16% |
  770 +| 2640kbps | 1283s | 413880 | 426912 | 3.14% |
  771 +| 5254kbps | 71s | 45832 | 47056 | 2.67% |
  772 +| 5147kbps | 370s | 195040 | 200280 | 2.68% |
  773 +| 5158kbps | 1327s | 835664 | 858092 | 2.68% |
  774 +
  775 +The HLS overhead is calc by: (HLS - FLV) / FLV * 100%
  776 +
750 ## Architecture 777 ## Architecture
751 778
752 SRS always use the most simple architecture to support complex transaction. 779 SRS always use the most simple architecture to support complex transaction.
@@ -608,7 +608,7 @@ vhost with-hls.srs.com { @@ -608,7 +608,7 @@ vhost with-hls.srs.com {
608 # when codec changed, write the PAT/PMT table, but maybe ok util next ts. 608 # when codec changed, write the PAT/PMT table, but maybe ok util next ts.
609 # so user can set the default codec for mp3. 609 # so user can set the default codec for mp3.
610 # the available audio codec: 610 # the available audio codec:
611 - # aac, mp3 611 + # aac, mp3, an
612 # default: aac 612 # default: aac
613 hls_acodec aac; 613 hls_acodec aac;
614 # the default video codec of hls. 614 # the default video codec of hls.
@@ -420,6 +420,9 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) @@ -420,6 +420,9 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
420 } else if (default_acodec_str == "aac") { 420 } else if (default_acodec_str == "aac") {
421 default_acodec = SrsCodecAudioAAC; 421 default_acodec = SrsCodecAudioAAC;
422 srs_info("hls: use default aac acodec"); 422 srs_info("hls: use default aac acodec");
  423 + } else if (default_acodec_str == "an") {
  424 + default_acodec = SrsCodecAudioDisabled;
  425 + srs_info("hls: use default an acodec for pure video");
423 } else { 426 } else {
424 srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str()); 427 srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str());
425 } 428 }
@@ -136,6 +136,9 @@ enum SrsCodecAudio @@ -136,6 +136,9 @@ enum SrsCodecAudio
136 // set to the max value to reserved, for array map. 136 // set to the max value to reserved, for array map.
137 SrsCodecAudioReserved1 = 16, 137 SrsCodecAudioReserved1 = 16,
138 138
  139 + // for user to disable audio, for example, use pure video hls.
  140 + SrsCodecAudioDisabled = 17,
  141 +
139 SrsCodecAudioLinearPCMPlatformEndian = 0, 142 SrsCodecAudioLinearPCMPlatformEndian = 0,
140 SrsCodecAudioADPCM = 1, 143 SrsCodecAudioADPCM = 1,
141 SrsCodecAudioMP3 = 2, 144 SrsCodecAudioMP3 = 2,
@@ -215,13 +215,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -215,13 +215,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
215 #define ERROR_HTTP_DVR_CREATE_REQUEST 3053 215 #define ERROR_HTTP_DVR_CREATE_REQUEST 3053
216 #define ERROR_HTTP_DVR_NO_TAEGET 3054 216 #define ERROR_HTTP_DVR_NO_TAEGET 3054
217 #define ERROR_ADTS_ID_NOT_AAC 3055 217 #define ERROR_ADTS_ID_NOT_AAC 3055
218 -// HDS error code  
219 #define ERROR_HDS_OPEN_F4M_FAILED 3056 218 #define ERROR_HDS_OPEN_F4M_FAILED 3056
220 #define ERROR_HDS_WRITE_F4M_FAILED 3057 219 #define ERROR_HDS_WRITE_F4M_FAILED 3057
221 #define ERROR_HDS_OPEN_BOOTSTRAP_FAILED 3058 220 #define ERROR_HDS_OPEN_BOOTSTRAP_FAILED 3058
222 #define ERROR_HDS_WRITE_BOOTSTRAP_FAILED 3059 221 #define ERROR_HDS_WRITE_BOOTSTRAP_FAILED 3059
223 #define ERROR_HDS_OPEN_FRAGMENT_FAILED 3060 222 #define ERROR_HDS_OPEN_FRAGMENT_FAILED 3060
224 #define ERROR_HDS_WRITE_FRAGMENT_FAILED 3061 223 #define ERROR_HDS_WRITE_FRAGMENT_FAILED 3061
  224 +#define ERROR_HLS_NO_STREAM 3062
225 225
226 /////////////////////////////////////////////////////// 226 ///////////////////////////////////////////////////////
227 // HTTP/StreamCaster protocol error. 227 // HTTP/StreamCaster protocol error.
@@ -302,10 +302,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo @@ -302,10 +302,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo
302 vs = SrsTsStreamVideoH264; 302 vs = SrsTsStreamVideoH264;
303 video_pid = TS_VIDEO_AVC_PID; 303 video_pid = TS_VIDEO_AVC_PID;
304 break; 304 break;
  305 + case SrsCodecVideoDisabled:
  306 + vs = SrsTsStreamReserved;
  307 + break;
305 case SrsCodecVideoReserved: 308 case SrsCodecVideoReserved:
306 case SrsCodecVideoReserved1: 309 case SrsCodecVideoReserved1:
307 case SrsCodecVideoReserved2: 310 case SrsCodecVideoReserved2:
308 - case SrsCodecVideoDisabled:  
309 case SrsCodecVideoSorensonH263: 311 case SrsCodecVideoSorensonH263:
310 case SrsCodecVideoScreenVideo: 312 case SrsCodecVideoScreenVideo:
311 case SrsCodecVideoOn2VP6: 313 case SrsCodecVideoOn2VP6:
@@ -323,6 +325,9 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo @@ -323,6 +325,9 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo
323 as = SrsTsStreamAudioMp3; 325 as = SrsTsStreamAudioMp3;
324 audio_pid = TS_AUDIO_MP3_PID; 326 audio_pid = TS_AUDIO_MP3_PID;
325 break; 327 break;
  328 + case SrsCodecAudioDisabled:
  329 + as = SrsTsStreamReserved;
  330 + break;
326 case SrsCodecAudioReserved1: 331 case SrsCodecAudioReserved1:
327 case SrsCodecAudioLinearPCMPlatformEndian: 332 case SrsCodecAudioLinearPCMPlatformEndian:
328 case SrsCodecAudioADPCM: 333 case SrsCodecAudioADPCM:
@@ -340,6 +345,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo @@ -340,6 +345,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo
340 break; 345 break;
341 } 346 }
342 347
  348 + if (as == SrsTsStreamReserved && vs == SrsTsStreamReserved) {
  349 + ret = ERROR_HLS_NO_STREAM;
  350 + srs_error("hls: no video or audio stream, vcodec=%d, acodec=%d. ret=%d", vc, ac, ret);
  351 + return ret;
  352 + }
  353 +
343 // when any codec changed, write PAT/PMT table. 354 // when any codec changed, write PAT/PMT table.
344 if (vcodec != vc || acodec != ac) { 355 if (vcodec != vc || acodec != ac) {
345 vcodec = vc; 356 vcodec = vc;
@@ -360,6 +371,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo @@ -360,6 +371,12 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo
360 int SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as) 371 int SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as)
361 { 372 {
362 int ret = ERROR_SUCCESS; 373 int ret = ERROR_SUCCESS;
  374 +
  375 + if (vs != SrsTsStreamVideoH264 && as != SrsTsStreamAudioAAC && as != SrsTsStreamAudioMp3) {
  376 + ret = ERROR_HLS_NO_STREAM;
  377 + srs_error("hls: no pmt pcr pid, vs=%d, as=%d. ret=%d", vs, as, ret);
  378 + return ret;
  379 + }
363 380
364 int16_t pmt_number = TS_PMT_NUMBER; 381 int16_t pmt_number = TS_PMT_NUMBER;
365 int16_t pmt_pid = TS_PMT_PID; 382 int16_t pmt_pid = TS_PMT_PID;
@@ -754,15 +771,17 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number, @@ -754,15 +771,17 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number,
754 pmt->last_section_number = 0; 771 pmt->last_section_number = 0;
755 pmt->program_info_length = 0; 772 pmt->program_info_length = 0;
756 773
757 - // use audio to carray pcr by default.  
758 - // for hls, there must be atleast one audio channel.  
759 - pmt->PCR_PID = apid;  
760 - pmt->infos.push_back(new SrsTsPayloadPMTESInfo(as, apid));  
761 -  
762 // if h.264 specified, use video to carry pcr. 774 // if h.264 specified, use video to carry pcr.
763 if (vs == SrsTsStreamVideoH264) { 775 if (vs == SrsTsStreamVideoH264) {
764 pmt->PCR_PID = vpid; 776 pmt->PCR_PID = vpid;
765 pmt->infos.push_back(new SrsTsPayloadPMTESInfo(vs, vpid)); 777 pmt->infos.push_back(new SrsTsPayloadPMTESInfo(vs, vpid));
  778 + } else if (as == SrsTsStreamAudioAAC || as == SrsTsStreamAudioMp3) {
  779 + // use audio to carray pcr by default.
  780 + // for hls, there must be atleast one audio channel.
  781 + pmt->PCR_PID = apid;
  782 + pmt->infos.push_back(new SrsTsPayloadPMTESInfo(as, apid));
  783 + } else {
  784 + srs_assert(false);
766 } 785 }
767 786
768 pmt->CRC_32 = 0; // calc in encode. 787 pmt->CRC_32 = 0; // calc in encode.