winlin

refine hls, ts temp file use ext .tmp

@@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #include <string.h> 32 #include <string.h>
33 33
34 #include <algorithm> 34 #include <algorithm>
  35 +using namespace std;
35 36
36 #include <srs_kernel_error.hpp> 37 #include <srs_kernel_error.hpp>
37 #include <srs_app_codec.hpp> 38 #include <srs_app_codec.hpp>
@@ -414,7 +415,7 @@ SrsTSMuxer::~SrsTSMuxer() @@ -414,7 +415,7 @@ SrsTSMuxer::~SrsTSMuxer()
414 close(); 415 close();
415 } 416 }
416 417
417 -int SrsTSMuxer::open(std::string _path) 418 +int SrsTSMuxer::open(string _path)
418 { 419 {
419 int ret = ERROR_SUCCESS; 420 int ret = ERROR_SUCCESS;
420 421
@@ -526,8 +527,7 @@ SrsHlsMuxer::~SrsHlsMuxer() @@ -526,8 +527,7 @@ SrsHlsMuxer::~SrsHlsMuxer()
526 } 527 }
527 528
528 int SrsHlsMuxer::update_config( 529 int SrsHlsMuxer::update_config(
529 - std::string _app, std::string _stream,  
530 - std::string path, int fragment, int window 530 + string _app, string _stream, string path, int fragment, int window
531 ) { 531 ) {
532 int ret = ERROR_SUCCESS; 532 int ret = ERROR_SUCCESS;
533 533
@@ -578,12 +578,13 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) @@ -578,12 +578,13 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
578 // TODO: support base url, and so on. 578 // TODO: support base url, and so on.
579 current->uri = filename; 579 current->uri = filename;
580 580
581 - if ((ret = current->muxer->open(current->full_path)) != ERROR_SUCCESS) { 581 + std::string tmp_file = current->full_path + ".tmp";
  582 + if ((ret = current->muxer->open(tmp_file.c_str())) != ERROR_SUCCESS) {
582 srs_error("open hls muxer failed. ret=%d", ret); 583 srs_error("open hls muxer failed. ret=%d", ret);
583 return ret; 584 return ret;
584 } 585 }
585 - srs_info("open HLS muxer success. vhost=%s, path=%s",  
586 - vhost.c_str(), current->full_path.c_str()); 586 + srs_info("open HLS muxer success. vhost=%s, path=%s, tmp=%s",
  587 + vhost.c_str(), current->full_path.c_str(), tmp_file.c_str());
587 588
588 return ret; 589 return ret;
589 } 590 }
@@ -648,7 +649,7 @@ int SrsHlsMuxer::flush_video( @@ -648,7 +649,7 @@ int SrsHlsMuxer::flush_video(
648 return ret; 649 return ret;
649 } 650 }
650 651
651 -int SrsHlsMuxer::segment_close() 652 +int SrsHlsMuxer::segment_close(string log_desc)
652 { 653 {
653 int ret = ERROR_SUCCESS; 654 int ret = ERROR_SUCCESS;
654 655
@@ -668,12 +669,20 @@ int SrsHlsMuxer::segment_close() @@ -668,12 +669,20 @@ int SrsHlsMuxer::segment_close()
668 // valid, add to segments. 669 // valid, add to segments.
669 segments.push_back(current); 670 segments.push_back(current);
670 671
671 - srs_trace("reap ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64"",  
672 - current->sequence_no, current->uri.c_str(), current->duration, 672 + srs_trace("%s reap ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64"",
  673 + log_desc.c_str(), current->sequence_no, current->uri.c_str(), current->duration,
673 current->segment_start_dts); 674 current->segment_start_dts);
674 675
675 // close the muxer of finished segment. 676 // close the muxer of finished segment.
676 srs_freep(current->muxer); 677 srs_freep(current->muxer);
  678 + // rename from tmp to real path
  679 + std::string tmp_file = current->full_path + ".tmp";
  680 + if (rename(tmp_file.c_str(), current->full_path.c_str()) < 0) {
  681 + ret = ERROR_HLS_WRITE_FAILED;
  682 + srs_error("rename ts file failed, %s => %s. ret=%d",
  683 + tmp_file.c_str(), current->full_path.c_str(), ret);
  684 + return ret;
  685 + }
677 current = NULL; 686 current = NULL;
678 687
679 // the segments to remove 688 // the segments to remove
@@ -737,7 +746,8 @@ int SrsHlsMuxer::refresh_m3u8() @@ -737,7 +746,8 @@ int SrsHlsMuxer::refresh_m3u8()
737 close(fd); 746 close(fd);
738 if (rename(m3u8_file.c_str(), m3u8.c_str()) < 0) { 747 if (rename(m3u8_file.c_str(), m3u8.c_str()) < 0) {
739 ret = ERROR_HLS_WRITE_FAILED; 748 ret = ERROR_HLS_WRITE_FAILED;
740 - srs_error("rename m3u8 file failed. ret=%d", ret); 749 + srs_error("rename m3u8 file failed. "
  750 + "%s => %s, ret=%d", m3u8_file.c_str(), m3u8.c_str(), ret);
741 } 751 }
742 } 752 }
743 753
@@ -747,7 +757,7 @@ int SrsHlsMuxer::refresh_m3u8() @@ -747,7 +757,7 @@ int SrsHlsMuxer::refresh_m3u8()
747 return ret; 757 return ret;
748 } 758 }
749 759
750 -int SrsHlsMuxer::_refresh_m3u8(int& fd, std::string m3u8_file) 760 +int SrsHlsMuxer::_refresh_m3u8(int& fd, string m3u8_file)
751 { 761 {
752 int ret = ERROR_SUCCESS; 762 int ret = ERROR_SUCCESS;
753 763
@@ -928,7 +938,7 @@ int SrsHlsCache::on_unpublish(SrsHlsMuxer* muxer) @@ -928,7 +938,7 @@ int SrsHlsCache::on_unpublish(SrsHlsMuxer* muxer)
928 return ret; 938 return ret;
929 } 939 }
930 940
931 - if ((ret = muxer->segment_close()) != ERROR_SUCCESS) { 941 + if ((ret = muxer->segment_close("unpublish")) != ERROR_SUCCESS) {
932 return ret; 942 return ret;
933 } 943 }
934 944
@@ -974,8 +984,7 @@ int SrsHlsCache::write_audio(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t pts, S @@ -974,8 +984,7 @@ int SrsHlsCache::write_audio(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t pts, S
974 // for pure audio 984 // for pure audio
975 // start new segment when duration overflow. 985 // start new segment when duration overflow.
976 if (video_count == 0 && muxer->is_segment_overflow()) { 986 if (video_count == 0 && muxer->is_segment_overflow()) {
977 - srs_trace("pure audio segment reap");  
978 - if ((ret = reap_segment(muxer, af->pts)) != ERROR_SUCCESS) { 987 + if ((ret = reap_segment("audio", muxer, af->pts)) != ERROR_SUCCESS) {
979 return ret; 988 return ret;
980 } 989 }
981 } 990 }
@@ -1005,7 +1014,7 @@ int SrsHlsCache::write_video( @@ -1005,7 +1014,7 @@ int SrsHlsCache::write_video(
1005 // 1. base on gop. 1014 // 1. base on gop.
1006 // 2. some gops duration overflow. 1015 // 2. some gops duration overflow.
1007 if (vf->key && muxer->is_segment_overflow()) { 1016 if (vf->key && muxer->is_segment_overflow()) {
1008 - if ((ret = reap_segment(muxer, vf->dts)) != ERROR_SUCCESS) { 1017 + if ((ret = reap_segment("video", muxer, vf->dts)) != ERROR_SUCCESS) {
1009 return ret; 1018 return ret;
1010 } 1019 }
1011 } 1020 }
@@ -1019,11 +1028,11 @@ int SrsHlsCache::write_video( @@ -1019,11 +1028,11 @@ int SrsHlsCache::write_video(
1019 return ret; 1028 return ret;
1020 } 1029 }
1021 1030
1022 -int SrsHlsCache::reap_segment(SrsHlsMuxer* muxer, int64_t segment_start_dts) 1031 +int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segment_start_dts)
1023 { 1032 {
1024 int ret = ERROR_SUCCESS; 1033 int ret = ERROR_SUCCESS;
1025 1034
1026 - if ((ret = muxer->segment_close()) != ERROR_SUCCESS) { 1035 + if ((ret = muxer->segment_close(log_desc)) != ERROR_SUCCESS) {
1027 srs_error("m3u8 muxer close segment failed. ret=%d", ret); 1036 srs_error("m3u8 muxer close segment failed. ret=%d", ret);
1028 return ret; 1037 return ret;
1029 } 1038 }
@@ -174,7 +174,11 @@ public: @@ -174,7 +174,11 @@ public:
174 virtual bool is_segment_overflow(); 174 virtual bool is_segment_overflow();
175 virtual int flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab); 175 virtual int flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab);
176 virtual int flush_video(SrsMpegtsFrame* af, SrsCodecBuffer* ab, SrsMpegtsFrame* vf, SrsCodecBuffer* vb); 176 virtual int flush_video(SrsMpegtsFrame* af, SrsCodecBuffer* ab, SrsMpegtsFrame* vf, SrsCodecBuffer* vb);
177 - virtual int segment_close(); 177 + /**
  178 + * close segment(ts).
  179 + * @param log_desc the description for log.
  180 + */
  181 + virtual int segment_close(std::string log_desc);
178 private: 182 private:
179 virtual int refresh_m3u8(); 183 virtual int refresh_m3u8();
180 virtual int _refresh_m3u8(int& fd, std::string m3u8_file); 184 virtual int _refresh_m3u8(int& fd, std::string m3u8_file);
@@ -243,7 +247,7 @@ private: @@ -243,7 +247,7 @@ private:
243 * then write the key frame to the new segment. 247 * then write the key frame to the new segment.
244 * so, user must reap_segment then flush_video to hls muxer. 248 * so, user must reap_segment then flush_video to hls muxer.
245 */ 249 */
246 - virtual int reap_segment(SrsHlsMuxer* muxer, int64_t segment_start_dts); 250 + virtual int reap_segment(std::string log_desc, SrsHlsMuxer* muxer, int64_t segment_start_dts);
247 virtual int cache_audio(SrsCodec* codec, SrsCodecSample* sample); 251 virtual int cache_audio(SrsCodec* codec, SrsCodecSample* sample);
248 virtual int cache_video(SrsCodec* codec, SrsCodecSample* sample); 252 virtual int cache_video(SrsCodec* codec, SrsCodecSample* sample);
249 }; 253 };