winlin

for #304, rewrite hls/ts code, support h.264+mp3 for hls. 2.0.117.

@@ -487,6 +487,8 @@ Supported operating systems and hardware: @@ -487,6 +487,8 @@ Supported operating systems and hardware:
487 [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301). 487 [#301](https://github.com/winlinvip/simple-rtmp-server/issues/301).
488 1. Support push MPEG-TS over UDP to SRS, read 488 1. Support push MPEG-TS over UDP to SRS, read
489 [#250](https://github.com/winlinvip/simple-rtmp-server/issues/250). 489 [#250](https://github.com/winlinvip/simple-rtmp-server/issues/250).
  490 +1. Rewrite HLS(h.264+aac/mp3) streaming, read
  491 +[#304](https://github.com/winlinvip/simple-rtmp-server/issues/304).
490 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech). 492 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech).
491 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92). 493 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92).
492 1. [no-plan] Support multiple processes, for both origin and edge 494 1. [no-plan] Support multiple processes, for both origin and edge
@@ -525,6 +527,7 @@ Supported operating systems and hardware: @@ -525,6 +527,7 @@ Supported operating systems and hardware:
525 527
526 ### SRS 2.0 history 528 ### SRS 2.0 history
527 529
  530 +* v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite hls/ts code, support h.264+mp3 for hls. 2.0.117.
528 * v2.0, 2015-02-12, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), use stringstream to generate m3u8, add hls_td_ratio. 2.0.116. 531 * v2.0, 2015-02-12, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), use stringstream to generate m3u8, add hls_td_ratio. 2.0.116.
529 * v2.0, 2015-02-11, dev code ZhouGuowen for 2.0.115. 532 * v2.0, 2015-02-11, dev code ZhouGuowen for 2.0.115.
530 * v2.0, 2015-02-10, for [#311](https://github.com/winlinvip/simple-rtmp-server/issues/311), set pcr_base to dts. 2.0.114. 533 * v2.0, 2015-02-10, for [#311](https://github.com/winlinvip/simple-rtmp-server/issues/311), set pcr_base to dts. 2.0.114.
@@ -492,6 +492,13 @@ vhost with-hls.srs.com { @@ -492,6 +492,13 @@ vhost with-hls.srs.com {
492 # @remark the hls_mount must endswith .m3u8. 492 # @remark the hls_mount must endswith .m3u8.
493 # default: [vhost]/[app]/[stream].m3u8 493 # default: [vhost]/[app]/[stream].m3u8
494 hls_mount [vhost]/[app]/[stream].m3u8; 494 hls_mount [vhost]/[app]/[stream].m3u8;
  495 + # the default audio codec of hls.
  496 + # when codec changed, write the PAT/PMT table, but maybe ok util next ts.
  497 + # so user can set the default codec for mp3.
  498 + # the available audio codec: aac, mp3
  499 + # default: aac
  500 + # TODO: FIXME: update wiki for it.
  501 + hls_acodec aac;
495 } 502 }
496 } 503 }
497 # the vhost with hls disabled. 504 # the vhost with hls disabled.
@@ -1480,7 +1480,7 @@ int SrsConfig::check_config() @@ -1480,7 +1480,7 @@ int SrsConfig::check_config()
1480 for (int j = 0; j < (int)conf->directives.size(); j++) { 1480 for (int j = 0; j < (int)conf->directives.size(); j++) {
1481 string m = conf->at(j)->name.c_str(); 1481 string m = conf->at(j)->name.c_str();
1482 if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error" 1482 if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error"
1483 - && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" 1483 + && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_acodec"
1484 ) { 1484 ) {
1485 ret = ERROR_SYSTEM_CONFIG_INVALID; 1485 ret = ERROR_SYSTEM_CONFIG_INVALID;
1486 srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); 1486 srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret);
@@ -3332,6 +3332,23 @@ string SrsConfig::get_hls_mount(string vhost) @@ -3332,6 +3332,23 @@ string SrsConfig::get_hls_mount(string vhost)
3332 return conf->arg0(); 3332 return conf->arg0();
3333 } 3333 }
3334 3334
  3335 +string SrsConfig::get_hls_acodec(string vhost)
  3336 +{
  3337 + SrsConfDirective* hls = get_hls(vhost);
  3338 +
  3339 + if (!hls) {
  3340 + return SRS_CONF_DEFAULT_HLS_ACODEC;
  3341 + }
  3342 +
  3343 + SrsConfDirective* conf = hls->get("hls_acodec");
  3344 +
  3345 + if (!conf) {
  3346 + return SRS_CONF_DEFAULT_HLS_ACODEC;
  3347 + }
  3348 +
  3349 + return conf->arg0();
  3350 +}
  3351 +
3335 SrsConfDirective* SrsConfig::get_dvr(string vhost) 3352 SrsConfDirective* SrsConfig::get_dvr(string vhost)
3336 { 3353 {
3337 SrsConfDirective* conf = get_vhost(vhost); 3354 SrsConfDirective* conf = get_vhost(vhost);
@@ -55,6 +55,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -55,6 +55,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55 #define SRS_CONF_DEFAULT_HLS_ON_ERROR SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE 55 #define SRS_CONF_DEFAULT_HLS_ON_ERROR SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE
56 #define SRS_CONF_DEFAULT_HLS_STORAGE "disk" 56 #define SRS_CONF_DEFAULT_HLS_STORAGE "disk"
57 #define SRS_CONF_DEFAULT_HLS_MOUNT "[vhost]/[app]/[stream].m3u8" 57 #define SRS_CONF_DEFAULT_HLS_MOUNT "[vhost]/[app]/[stream].m3u8"
  58 +#define SRS_CONF_DEFAULT_HLS_ACODEC "aac"
58 #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html" 59 #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html"
59 #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session" 60 #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session"
60 #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment" 61 #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment"
@@ -922,6 +923,10 @@ public: @@ -922,6 +923,10 @@ public:
922 * get the HLS mount url for HTTP server. 923 * get the HLS mount url for HTTP server.
923 */ 924 */
924 virtual std::string get_hls_mount(std::string vhost); 925 virtual std::string get_hls_mount(std::string vhost);
  926 + /**
  927 + * get the HLS default audio codec.
  928 + */
  929 + virtual std::string get_hls_acodec(std::string vhost);
925 // dvr section 930 // dvr section
926 private: 931 private:
927 /** 932 /**
@@ -131,14 +131,14 @@ string SrsHlsCacheWriter::cache() @@ -131,14 +131,14 @@ string SrsHlsCacheWriter::cache()
131 return data; 131 return data;
132 } 132 }
133 133
134 -SrsHlsSegment::SrsHlsSegment(bool write_cache, bool write_file) 134 +SrsHlsSegment::SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac)
135 { 135 {
136 duration = 0; 136 duration = 0;
137 sequence_no = 0; 137 sequence_no = 0;
138 segment_start_dts = 0; 138 segment_start_dts = 0;
139 is_sequence_header = false; 139 is_sequence_header = false;
140 writer = new SrsHlsCacheWriter(write_cache, write_file); 140 writer = new SrsHlsCacheWriter(write_cache, write_file);
141 - muxer = new SrsTSMuxer(writer); 141 + muxer = new SrsTSMuxer(writer, ac);
142 } 142 }
143 143
144 SrsHlsSegment::~SrsHlsSegment() 144 SrsHlsSegment::~SrsHlsSegment()
@@ -243,9 +243,22 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) @@ -243,9 +243,22 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
243 243
244 // when segment open, the current segment must be NULL. 244 // when segment open, the current segment must be NULL.
245 srs_assert(!current); 245 srs_assert(!current);
  246 +
  247 + // load the default acodec from config.
  248 + SrsCodecAudio default_acodec = SrsCodecAudioAAC;
  249 + std::string default_acodec_str = _srs_config->get_hls_acodec(req->vhost);
  250 + if (default_acodec_str == "mp3") {
  251 + default_acodec = SrsCodecAudioMP3;
  252 + srs_info("hls: use default mp3 acodec");
  253 + } else if (default_acodec_str == "aac") {
  254 + default_acodec = SrsCodecAudioAAC;
  255 + srs_info("hls: use default aac acodec");
  256 + } else {
  257 + srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str());
  258 + }
246 259
247 // new segment. 260 // new segment.
248 - current = new SrsHlsSegment(should_write_cache, should_write_file); 261 + current = new SrsHlsSegment(should_write_cache, should_write_file, default_acodec);
249 current->sequence_no = _sequence_no++; 262 current->sequence_no = _sequence_no++;
250 current->segment_start_dts = segment_start_dts; 263 current->segment_start_dts = segment_start_dts;
251 264
@@ -144,7 +144,7 @@ public: @@ -144,7 +144,7 @@ public:
144 // whether current segement is sequence header. 144 // whether current segement is sequence header.
145 bool is_sequence_header; 145 bool is_sequence_header;
146 public: 146 public:
147 - SrsHlsSegment(bool write_cache, bool write_file); 147 + SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac);
148 virtual ~SrsHlsSegment(); 148 virtual ~SrsHlsSegment();
149 public: 149 public:
150 /** 150 /**
@@ -2916,13 +2916,12 @@ int SrsTsPayloadPMT::psi_encode(SrsStream* stream) @@ -2916,13 +2916,12 @@ int SrsTsPayloadPMT::psi_encode(SrsStream* stream)
2916 return ret; 2916 return ret;
2917 } 2917 }
2918 2918
2919 -SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w) 2919 +SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac)
2920 { 2920 {
2921 writer = w; 2921 writer = w;
2922 context = NULL; 2922 context = NULL;
2923 2923
2924 - // default to aac.  
2925 - acodec = SrsCodecAudioAAC; 2924 + acodec = ac;
2926 // default to avc(h.264) 2925 // default to avc(h.264)
2927 vcodec = SrsCodecVideoAVC; 2926 vcodec = SrsCodecVideoAVC;
2928 } 2927 }
@@ -3296,7 +3295,7 @@ int SrsTsEncoder::initialize(SrsFileWriter* fs) @@ -3296,7 +3295,7 @@ int SrsTsEncoder::initialize(SrsFileWriter* fs)
3296 _fs = fs; 3295 _fs = fs;
3297 3296
3298 srs_freep(muxer); 3297 srs_freep(muxer);
3299 - muxer = new SrsTSMuxer(fs); 3298 + muxer = new SrsTSMuxer(fs, SrsCodecAudioAAC);
3300 3299
3301 if ((ret = muxer->open("")) != ERROR_SUCCESS) { 3300 if ((ret = muxer->open("")) != ERROR_SUCCESS) {
3302 return ret; 3301 return ret;
@@ -1547,7 +1547,7 @@ private: @@ -1547,7 +1547,7 @@ private:
1547 SrsFileWriter* writer; 1547 SrsFileWriter* writer;
1548 std::string path; 1548 std::string path;
1549 public: 1549 public:
1550 - SrsTSMuxer(SrsFileWriter* w); 1550 + SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac);
1551 virtual ~SrsTSMuxer(); 1551 virtual ~SrsTSMuxer();
1552 public: 1552 public:
1553 /** 1553 /**