winlin

refine hls code, reorder classes.

@@ -349,28 +349,6 @@ private: @@ -349,28 +349,6 @@ private:
349 } 349 }
350 }; 350 };
351 351
352 -SrsM3u8Segment::SrsM3u8Segment()  
353 -{  
354 - duration = 0;  
355 - sequence_no = 0;  
356 - muxer = new SrsTSMuxer();  
357 - segment_start_dts = 0;  
358 -}  
359 -  
360 -SrsM3u8Segment::~SrsM3u8Segment()  
361 -{  
362 - srs_freep(muxer);  
363 -}  
364 -  
365 -SrsHlsAacJitter::SrsHlsAacJitter()  
366 -{  
367 - base_pts = 0;  
368 - nb_samples = 0;  
369 -  
370 - // TODO: config it, 0 means no adjust  
371 - sync_ms = SRS_CONF_DEFAULT_AAC_SYNC;  
372 -}  
373 -  
374 SrsHlsAacJitter::~SrsHlsAacJitter() 352 SrsHlsAacJitter::~SrsHlsAacJitter()
375 { 353 {
376 } 354 }
@@ -421,6 +399,111 @@ void SrsHlsAacJitter::on_buffer_continue() @@ -421,6 +399,111 @@ void SrsHlsAacJitter::on_buffer_continue()
421 nb_samples++; 399 nb_samples++;
422 } 400 }
423 401
  402 +SrsM3u8Segment::SrsM3u8Segment()
  403 +{
  404 + duration = 0;
  405 + sequence_no = 0;
  406 + muxer = new SrsTSMuxer();
  407 + segment_start_dts = 0;
  408 +}
  409 +
  410 +SrsM3u8Segment::~SrsM3u8Segment()
  411 +{
  412 + srs_freep(muxer);
  413 +}
  414 +
  415 +double SrsM3u8Segment::update_duration(int64_t video_stream_dts)
  416 +{
  417 + duration = (video_stream_dts - segment_start_dts) / 90000.0;
  418 + srs_assert(duration > 0);
  419 +
  420 + return duration;
  421 +}
  422 +
  423 +SrsHlsAacJitter::SrsHlsAacJitter()
  424 +{
  425 + base_pts = 0;
  426 + nb_samples = 0;
  427 +
  428 + // TODO: config it, 0 means no adjust
  429 + sync_ms = SRS_CONF_DEFAULT_AAC_SYNC;
  430 +}
  431 +
  432 +SrsTSMuxer::SrsTSMuxer()
  433 +{
  434 + fd = -1;
  435 + _fresh = false;
  436 +}
  437 +
  438 +SrsTSMuxer::~SrsTSMuxer()
  439 +{
  440 + close();
  441 +}
  442 +
  443 +int SrsTSMuxer::open(std::string _path)
  444 +{
  445 + int ret = ERROR_SUCCESS;
  446 +
  447 + path = _path;
  448 +
  449 + close();
  450 +
  451 + int flags = O_CREAT|O_WRONLY|O_TRUNC;
  452 + mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
  453 + if ((fd = ::open(path.c_str(), flags, mode)) < 0) {
  454 + ret = ERROR_HLS_OPEN_FAILED;
  455 + srs_error("open ts file %s failed. ret=%d", path.c_str(), ret);
  456 + return ret;
  457 + }
  458 +
  459 + // write mpegts header
  460 + if ((ret = SrsMpegtsWriter::write_header(fd)) != ERROR_SUCCESS) {
  461 + return ret;
  462 + }
  463 +
  464 + _fresh = true;
  465 +
  466 + return ret;
  467 +}
  468 +
  469 +int SrsTSMuxer::write_audio(SrsMpegtsFrame* audio_frame, SrsCodecBuffer* audio_buffer)
  470 +{
  471 + int ret = ERROR_SUCCESS;
  472 +
  473 + if ((ret = SrsMpegtsWriter::write_frame(fd, audio_frame, audio_buffer)) != ERROR_SUCCESS) {
  474 + return ret;
  475 + }
  476 +
  477 + _fresh = false;
  478 +
  479 + return ret;
  480 +}
  481 +
  482 +int SrsTSMuxer::write_video(SrsMpegtsFrame* video_frame, SrsCodecBuffer* video_buffer)
  483 +{
  484 + int ret = ERROR_SUCCESS;
  485 +
  486 + if ((ret = SrsMpegtsWriter::write_frame(fd, video_frame, video_buffer)) != ERROR_SUCCESS) {
  487 + return ret;
  488 + }
  489 +
  490 + return ret;
  491 +}
  492 +
  493 +void SrsTSMuxer::close()
  494 +{
  495 + if (fd > 0) {
  496 + ::close(fd);
  497 + fd = -1;
  498 + _fresh = false;
  499 + }
  500 +}
  501 +
  502 +bool SrsTSMuxer::fresh()
  503 +{
  504 + return _fresh;
  505 +}
  506 +
424 SrsHls::SrsHls() 507 SrsHls::SrsHls()
425 { 508 {
426 hls_enabled = false; 509 hls_enabled = false;
@@ -430,7 +513,7 @@ SrsHls::SrsHls() @@ -430,7 +513,7 @@ SrsHls::SrsHls()
430 jitter = new SrsRtmpJitter(); 513 jitter = new SrsRtmpJitter();
431 aac_jitter = new SrsHlsAacJitter(); 514 aac_jitter = new SrsHlsAacJitter();
432 file_index = 0; 515 file_index = 0;
433 - audio_buffer_start_pts = m3u8_dts = stream_dts = 0; 516 + audio_buffer_start_pts = video_stream_dts = 0;
434 hls_fragment = hls_window = 0; 517 hls_fragment = hls_window = 0;
435 518
436 // TODO: config it. 519 // TODO: config it.
@@ -583,14 +666,15 @@ int SrsHls::on_audio(SrsSharedPtrMessage* audio) @@ -583,14 +666,15 @@ int SrsHls::on_audio(SrsSharedPtrMessage* audio)
583 return ret; 666 return ret;
584 } 667 }
585 668
586 - if ((ret = jitter->correct(audio, 0, 0)) != ERROR_SUCCESS) { 669 + int64_t corrected_time = 0;
  670 + if ((ret = jitter->correct(audio, 0, 0, &corrected_time)) != ERROR_SUCCESS) {
587 return ret; 671 return ret;
588 } 672 }
589 673
590 srs_assert(current); 674 srs_assert(current);
591 675
592 // the pts calc from rtmp/flv header. 676 // the pts calc from rtmp/flv header.
593 - int64_t pts = audio->header.timestamp * 90; 677 + int64_t pts = corrected_time * 90;
594 678
595 // flush if audio delay exceed 679 // flush if audio delay exceed
596 if (pts - audio_buffer_start_pts > audio_delay * 90) { 680 if (pts - audio_buffer_start_pts > audio_delay * 90) {
@@ -650,7 +734,8 @@ int SrsHls::on_video(SrsSharedPtrMessage* video) @@ -650,7 +734,8 @@ int SrsHls::on_video(SrsSharedPtrMessage* video)
650 return ret; 734 return ret;
651 } 735 }
652 736
653 - if ((ret = jitter->correct(video, 0, 0)) != ERROR_SUCCESS) { 737 + int64_t corrected_time = 0;
  738 + if ((ret = jitter->correct(video, 0, 0, &corrected_time)) != ERROR_SUCCESS) {
654 return ret; 739 return ret;
655 } 740 }
656 741
@@ -659,16 +744,16 @@ int SrsHls::on_video(SrsSharedPtrMessage* video) @@ -659,16 +744,16 @@ int SrsHls::on_video(SrsSharedPtrMessage* video)
659 return ret; 744 return ret;
660 } 745 }
661 746
662 - stream_dts = video_frame->dts = video->header.timestamp * 90; 747 + video_stream_dts = video_frame->dts = corrected_time * 90;
663 video_frame->pts = video_frame->dts + sample->cts * 90; 748 video_frame->pts = video_frame->dts + sample->cts * 90;
664 video_frame->pid = TS_VIDEO_PID; 749 video_frame->pid = TS_VIDEO_PID;
665 video_frame->sid = TS_VIDEO_AVC; 750 video_frame->sid = TS_VIDEO_AVC;
666 video_frame->key = sample->frame_type == SrsCodecVideoAVCFrameKeyFrame; 751 video_frame->key = sample->frame_type == SrsCodecVideoAVCFrameKeyFrame;
667 752
668 // reopen the muxer for a gop 753 // reopen the muxer for a gop
  754 + srs_assert(current);
669 if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { 755 if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) {
670 - int64_t diff = stream_dts - m3u8_dts;  
671 - if (diff / 90000 >= hls_fragment) { 756 + if (current->duration >= hls_fragment) {
672 if ((ret = reopen()) != ERROR_SUCCESS) { 757 if ((ret = reopen()) != ERROR_SUCCESS) {
673 return ret; 758 return ret;
674 } 759 }
@@ -676,6 +761,9 @@ int SrsHls::on_video(SrsSharedPtrMessage* video) @@ -676,6 +761,9 @@ int SrsHls::on_video(SrsSharedPtrMessage* video)
676 } 761 }
677 762
678 srs_assert(current); 763 srs_assert(current);
  764 + // update the duration of segment.
  765 + current->update_duration(video_stream_dts);
  766 +
679 if ((ret = current->muxer->write_video(video_frame, video_buffer)) != ERROR_SUCCESS) { 767 if ((ret = current->muxer->write_video(video_frame, video_buffer)) != ERROR_SUCCESS) {
680 return ret; 768 return ret;
681 } 769 }
@@ -712,11 +800,8 @@ int SrsHls::reopen() @@ -712,11 +800,8 @@ int SrsHls::reopen()
712 return ret; 800 return ret;
713 } 801 }
714 802
715 - // start new segment. 803 + // close current segment and update the m3u8 file.
716 if (current) { 804 if (current) {
717 - current->duration = (stream_dts - current->segment_start_dts) / 90000.0;  
718 - srs_assert(current->duration > 0);  
719 -  
720 // assert segment duplicate. 805 // assert segment duplicate.
721 std::vector<SrsM3u8Segment*>::iterator it; 806 std::vector<SrsM3u8Segment*>::iterator it;
722 it = std::find(segments.begin(), segments.end(), current); 807 it = std::find(segments.begin(), segments.end(), current);
@@ -774,7 +859,7 @@ int SrsHls::reopen() @@ -774,7 +859,7 @@ int SrsHls::reopen()
774 // new segment. 859 // new segment.
775 current = new SrsM3u8Segment(); 860 current = new SrsM3u8Segment();
776 current->sequence_no = file_index++; 861 current->sequence_no = file_index++;
777 - m3u8_dts = current->segment_start_dts = stream_dts; 862 + current->segment_start_dts = video_stream_dts;
778 863
779 // generate filename. 864 // generate filename.
780 char filename[128]; 865 char filename[128];
@@ -1106,80 +1191,5 @@ int SrsHls::flush_audio() @@ -1106,80 +1191,5 @@ int SrsHls::flush_audio()
1106 return ret; 1191 return ret;
1107 } 1192 }
1108 1193
1109 -SrsTSMuxer::SrsTSMuxer()  
1110 -{  
1111 - fd = -1;  
1112 - _fresh = false;  
1113 -}  
1114 -  
1115 -SrsTSMuxer::~SrsTSMuxer()  
1116 -{  
1117 - close();  
1118 -}  
1119 -  
1120 -int SrsTSMuxer::open(std::string _path)  
1121 -{  
1122 - int ret = ERROR_SUCCESS;  
1123 -  
1124 - path = _path;  
1125 -  
1126 - close();  
1127 -  
1128 - int flags = O_CREAT|O_WRONLY|O_TRUNC;  
1129 - mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;  
1130 - if ((fd = ::open(path.c_str(), flags, mode)) < 0) {  
1131 - ret = ERROR_HLS_OPEN_FAILED;  
1132 - srs_error("open ts file %s failed. ret=%d", path.c_str(), ret);  
1133 - return ret;  
1134 - }  
1135 -  
1136 - // write mpegts header  
1137 - if ((ret = SrsMpegtsWriter::write_header(fd)) != ERROR_SUCCESS) {  
1138 - return ret;  
1139 - }  
1140 -  
1141 - _fresh = true;  
1142 -  
1143 - return ret;  
1144 -}  
1145 -  
1146 -int SrsTSMuxer::write_audio(SrsMpegtsFrame* audio_frame, SrsCodecBuffer* audio_buffer)  
1147 -{  
1148 - int ret = ERROR_SUCCESS;  
1149 -  
1150 - if ((ret = SrsMpegtsWriter::write_frame(fd, audio_frame, audio_buffer)) != ERROR_SUCCESS) {  
1151 - return ret;  
1152 - }  
1153 -  
1154 - _fresh = false;  
1155 -  
1156 - return ret;  
1157 -}  
1158 -  
1159 -int SrsTSMuxer::write_video(SrsMpegtsFrame* video_frame, SrsCodecBuffer* video_buffer)  
1160 -{  
1161 - int ret = ERROR_SUCCESS;  
1162 -  
1163 - if ((ret = SrsMpegtsWriter::write_frame(fd, video_frame, video_buffer)) != ERROR_SUCCESS) {  
1164 - return ret;  
1165 - }  
1166 -  
1167 - return ret;  
1168 -}  
1169 -  
1170 -void SrsTSMuxer::close()  
1171 -{  
1172 - if (fd > 0) {  
1173 - ::close(fd);  
1174 - fd = -1;  
1175 - _fresh = false;  
1176 - }  
1177 -}  
1178 -  
1179 -bool SrsTSMuxer::fresh()  
1180 -{  
1181 - return _fresh;  
1182 -}  
1183 -  
1184 #endif 1194 #endif
1185 1195
@@ -45,29 +45,6 @@ class SrsCodec; @@ -45,29 +45,6 @@ class SrsCodec;
45 class SrsRequest; 45 class SrsRequest;
46 46
47 /** 47 /**
48 -* 3.3.2. EXTINF  
49 -* The EXTINF tag specifies the duration of a media segment.  
50 -*/  
51 -struct SrsM3u8Segment  
52 -{  
53 - // duration in seconds in m3u8.  
54 - double duration;  
55 - // sequence number in m3u8.  
56 - int sequence_no;  
57 - // ts uri in m3u8.  
58 - std::string uri;  
59 - // ts full file to write.  
60 - std::string full_path;  
61 - // the muxer to write ts.  
62 - SrsTSMuxer* muxer;  
63 - // current segment start dts for m3u8  
64 - int64_t segment_start_dts;  
65 -  
66 - SrsM3u8Segment();  
67 - virtual ~SrsM3u8Segment();  
68 -};  
69 -  
70 -/**  
71 * jitter correct for audio, 48 * jitter correct for audio,
72 * the sample rate 44100/32000 will lost precise, 49 * the sample rate 44100/32000 will lost precise,
73 * when mp4/ts(tbn=90000) covert to flv/rtmp(1000), 50 * when mp4/ts(tbn=90000) covert to flv/rtmp(1000),
@@ -98,6 +75,52 @@ public: @@ -98,6 +75,52 @@ public:
98 }; 75 };
99 76
100 /** 77 /**
  78 +* 3.3.2. EXTINF
  79 +* The EXTINF tag specifies the duration of a media segment.
  80 +*/
  81 +struct SrsM3u8Segment
  82 +{
  83 + // duration in seconds in m3u8.
  84 + double duration;
  85 + // sequence number in m3u8.
  86 + int sequence_no;
  87 + // ts uri in m3u8.
  88 + std::string uri;
  89 + // ts full file to write.
  90 + std::string full_path;
  91 + // the muxer to write ts.
  92 + SrsTSMuxer* muxer;
  93 + // current segment start dts for m3u8
  94 + int64_t segment_start_dts;
  95 +
  96 + SrsM3u8Segment();
  97 + virtual ~SrsM3u8Segment();
  98 +
  99 + /**
  100 + * update the segment duration.
  101 + */
  102 + virtual double update_duration(int64_t video_stream_dts);
  103 +};
  104 +
  105 +//TODO: refine the ts muxer, do more jobs.
  106 +class SrsTSMuxer
  107 +{
  108 +private:
  109 + int fd;
  110 + std::string path;
  111 + bool _fresh;
  112 +public:
  113 + SrsTSMuxer();
  114 + virtual ~SrsTSMuxer();
  115 +public:
  116 + virtual int open(std::string _path);
  117 + virtual int write_audio(SrsMpegtsFrame* audio_frame, SrsCodecBuffer* audio_buffer);
  118 + virtual int write_video(SrsMpegtsFrame* video_frame, SrsCodecBuffer* video_buffer);
  119 + virtual void close();
  120 + virtual bool fresh();
  121 +};
  122 +
  123 +/**
101 * write m3u8 hls. 124 * write m3u8 hls.
102 */ 125 */
103 class SrsHls 126 class SrsHls
@@ -127,10 +150,8 @@ private: @@ -127,10 +150,8 @@ private:
127 SrsMpegtsFrame* video_frame; 150 SrsMpegtsFrame* video_frame;
128 SrsCodecBuffer* video_buffer; 151 SrsCodecBuffer* video_buffer;
129 // last known dts 152 // last known dts
130 - int64_t stream_dts; 153 + int64_t video_stream_dts;
131 int64_t audio_buffer_start_pts; 154 int64_t audio_buffer_start_pts;
132 - // last segment dts in m3u8  
133 - int64_t m3u8_dts;  
134 // in ms, audio delay to flush the audios. 155 // in ms, audio delay to flush the audios.
135 int64_t audio_delay; 156 int64_t audio_delay;
136 private: 157 private:
@@ -159,24 +180,6 @@ private: @@ -159,24 +180,6 @@ private:
159 virtual int flush_audio(); 180 virtual int flush_audio();
160 }; 181 };
161 182
162 -//TODO: refine the ts muxer, do more jobs.  
163 -class SrsTSMuxer  
164 -{  
165 -private:  
166 - int fd;  
167 - std::string path;  
168 - bool _fresh;  
169 -public:  
170 - SrsTSMuxer();  
171 - virtual ~SrsTSMuxer();  
172 -public:  
173 - virtual int open(std::string _path);  
174 - virtual int write_audio(SrsMpegtsFrame* audio_frame, SrsCodecBuffer* audio_buffer);  
175 - virtual int write_video(SrsMpegtsFrame* video_frame, SrsCodecBuffer* video_buffer);  
176 - virtual void close();  
177 - virtual bool fresh();  
178 -};  
179 -  
180 #endif 183 #endif
181 184
182 #endif 185 #endif
@@ -49,7 +49,7 @@ SrsRtmpJitter::~SrsRtmpJitter() @@ -49,7 +49,7 @@ SrsRtmpJitter::~SrsRtmpJitter()
49 { 49 {
50 } 50 }
51 51
52 -int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv) 52 +int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, int64_t* corrected_time)
53 { 53 {
54 int ret = ERROR_SUCCESS; 54 int ret = ERROR_SUCCESS;
55 55
@@ -93,7 +93,12 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv) @@ -93,7 +93,12 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv)
93 } 93 }
94 94
95 last_pkt_correct_time = srs_max(0, last_pkt_correct_time + delta); 95 last_pkt_correct_time = srs_max(0, last_pkt_correct_time + delta);
  96 +
  97 + if (corrected_time) {
  98 + *corrected_time = last_pkt_correct_time;
  99 + }
96 msg->header.timestamp = last_pkt_correct_time; 100 msg->header.timestamp = last_pkt_correct_time;
  101 +
97 last_pkt_time = time; 102 last_pkt_time = time;
98 103
99 return ret; 104 return ret;
@@ -62,8 +62,10 @@ public: @@ -62,8 +62,10 @@ public:
62 public: 62 public:
63 /** 63 /**
64 * detect the time jitter and correct it. 64 * detect the time jitter and correct it.
  65 + * @param corrected_time output the 64bits time.
  66 + * ignore if NULL.
65 */ 67 */
66 - virtual int correct(SrsSharedPtrMessage* msg, int tba, int tbv); 68 + virtual int correct(SrsSharedPtrMessage* msg, int tba, int tbv, int64_t* corrected_time = NULL);
67 /** 69 /**
68 * get current client time, the last packet time. 70 * get current client time, the last packet time.
69 */ 71 */