winlin

update dvr, extract flv segment

@@ -297,6 +297,20 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s @@ -297,6 +297,20 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s
297 return ret; 297 return ret;
298 } 298 }
299 299
  300 +SrsFlvSegment::SrsFlvSegment()
  301 +{
  302 + current_flv_path = "";
  303 + segment_has_keyframe = false;
  304 + duration = 0;
  305 + starttime = -1;
  306 +}
  307 +
  308 +void SrsFlvSegment::reset()
  309 +{
  310 + duration = 0;
  311 + starttime = -1;
  312 +}
  313 +
300 SrsDvrPlan::SrsDvrPlan() 314 SrsDvrPlan::SrsDvrPlan()
301 { 315 {
302 _source = NULL; 316 _source = NULL;
@@ -305,9 +319,7 @@ SrsDvrPlan::SrsDvrPlan() @@ -305,9 +319,7 @@ SrsDvrPlan::SrsDvrPlan()
305 dvr_enabled = false; 319 dvr_enabled = false;
306 fs = new SrsFileStream(); 320 fs = new SrsFileStream();
307 enc = new SrsFlvEncoder(); 321 enc = new SrsFlvEncoder();
308 - segment_has_keyframe = true;  
309 - starttime = -1;  
310 - duration = 0; 322 + segment = NULL;
311 } 323 }
312 324
313 SrsDvrPlan::~SrsDvrPlan() 325 SrsDvrPlan::~SrsDvrPlan()
@@ -315,6 +327,7 @@ SrsDvrPlan::~SrsDvrPlan() @@ -315,6 +327,7 @@ SrsDvrPlan::~SrsDvrPlan()
315 srs_freep(jitter); 327 srs_freep(jitter);
316 srs_freep(fs); 328 srs_freep(fs);
317 srs_freep(enc); 329 srs_freep(enc);
  330 + srs_freep(segment);
318 } 331 }
319 332
320 int SrsDvrPlan::initialize(SrsSource* source, SrsRequest* req) 333 int SrsDvrPlan::initialize(SrsSource* source, SrsRequest* req)
@@ -439,7 +452,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video) @@ -439,7 +452,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video)
439 #ifdef SRS_AUTO_HTTP_CALLBACK 452 #ifdef SRS_AUTO_HTTP_CALLBACK
440 bool is_key_frame = SrsCodec::video_is_keyframe((int8_t*)payload, size); 453 bool is_key_frame = SrsCodec::video_is_keyframe((int8_t*)payload, size);
441 if (is_key_frame) { 454 if (is_key_frame) {
442 - segment_has_keyframe = true; 455 + segment->segment_has_keyframe = true;
443 } 456 }
444 srs_verbose("dvr video is key: %d", is_key_frame); 457 srs_verbose("dvr video is key: %d", is_key_frame);
445 #endif 458 #endif
@@ -455,7 +468,9 @@ int SrsDvrPlan::flv_open(string stream, string path) @@ -455,7 +468,9 @@ int SrsDvrPlan::flv_open(string stream, string path)
455 { 468 {
456 int ret = ERROR_SUCCESS; 469 int ret = ERROR_SUCCESS;
457 470
458 - current_flv_path = path; 471 + srs_freep(segment);
  472 + segment = new SrsFlvSegment();
  473 +
459 std::string tmp_file = path + ".tmp"; 474 std::string tmp_file = path + ".tmp";
460 if ((ret = fs->open(tmp_file)) != ERROR_SUCCESS) { 475 if ((ret = fs->open(tmp_file)) != ERROR_SUCCESS) {
461 srs_error("open file stream for file %s failed. ret=%d", path.c_str(), ret); 476 srs_error("open file stream for file %s failed. ret=%d", path.c_str(), ret);
@@ -472,7 +487,7 @@ int SrsDvrPlan::flv_open(string stream, string path) @@ -472,7 +487,7 @@ int SrsDvrPlan::flv_open(string stream, string path)
472 return ret; 487 return ret;
473 } 488 }
474 489
475 - segment_has_keyframe = false; 490 + segment->current_flv_path = path;
476 491
477 srs_trace("dvr stream %s to file %s", stream.c_str(), path.c_str()); 492 srs_trace("dvr stream %s to file %s", stream.c_str(), path.c_str());
478 return ret; 493 return ret;
@@ -486,16 +501,16 @@ int SrsDvrPlan::flv_close() @@ -486,16 +501,16 @@ int SrsDvrPlan::flv_close()
486 return ret; 501 return ret;
487 } 502 }
488 503
489 - std::string tmp_file = current_flv_path + ".tmp";  
490 - if (rename(tmp_file.c_str(), current_flv_path.c_str()) < 0) { 504 + std::string tmp_file = segment->current_flv_path + ".tmp";
  505 + if (rename(tmp_file.c_str(), segment->current_flv_path.c_str()) < 0) {
491 ret = ERROR_SYSTEM_FILE_RENAME; 506 ret = ERROR_SYSTEM_FILE_RENAME;
492 srs_error("rename flv file failed, %s => %s. ret=%d", 507 srs_error("rename flv file failed, %s => %s. ret=%d",
493 - tmp_file.c_str(), current_flv_path.c_str(), ret); 508 + tmp_file.c_str(), segment->current_flv_path.c_str(), ret);
494 return ret; 509 return ret;
495 } 510 }
496 511
497 #ifdef SRS_AUTO_HTTP_CALLBACK 512 #ifdef SRS_AUTO_HTTP_CALLBACK
498 - if (segment_has_keyframe) { 513 + if (segment->segment_has_keyframe) {
499 if ((ret = on_dvr_keyframe()) != ERROR_SUCCESS) { 514 if ((ret = on_dvr_keyframe()) != ERROR_SUCCESS) {
500 return ret; 515 return ret;
501 } 516 }
@@ -510,11 +525,11 @@ int SrsDvrPlan::update_duration(SrsSharedPtrMessage* msg) @@ -510,11 +525,11 @@ int SrsDvrPlan::update_duration(SrsSharedPtrMessage* msg)
510 int ret = ERROR_SUCCESS; 525 int ret = ERROR_SUCCESS;
511 526
512 // foreach msg, collect the duration. 527 // foreach msg, collect the duration.
513 - if (starttime < 0 || starttime > msg->header.timestamp) {  
514 - starttime = msg->header.timestamp; 528 + if (segment->starttime < 0 || segment->starttime > msg->header.timestamp) {
  529 + segment->starttime = msg->header.timestamp;
515 } 530 }
516 - duration += msg->header.timestamp - starttime;  
517 - starttime = msg->header.timestamp; 531 + segment->duration += msg->header.timestamp - segment->starttime;
  532 + segment->starttime = msg->header.timestamp;
518 533
519 return ret; 534 return ret;
520 } 535 }
@@ -630,10 +645,11 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg) @@ -630,10 +645,11 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
630 return ret; 645 return ret;
631 } 646 }
632 647
  648 + srs_assert(segment);
  649 +
633 // reap if exceed duration. 650 // reap if exceed duration.
634 - if (duration > 0 && segment_duration > 0 && duration > segment_duration) {  
635 - duration = 0;  
636 - starttime = -1; 651 + if (segment->duration > 0 && segment_duration > 0 && segment->duration > segment_duration) {
  652 + segment->reset();
637 653
638 if ((ret = flv_close()) != ERROR_SUCCESS) { 654 if ((ret = flv_close()) != ERROR_SUCCESS) {
639 return ret; 655 return ret;
@@ -108,6 +108,30 @@ private: @@ -108,6 +108,30 @@ private:
108 }; 108 };
109 109
110 /** 110 /**
  111 +* a piece of flv segment.
  112 +*/
  113 +class SrsFlvSegment
  114 +{
  115 +public:
  116 + /**
  117 + * current flv file path.
  118 + */
  119 + std::string current_flv_path;
  120 + /**
  121 + * whether current segment has keyframe.
  122 + */
  123 + bool segment_has_keyframe;
  124 + /**
  125 + * current segment duration and starttime.
  126 + */
  127 + int64_t duration;
  128 + int64_t starttime;
  129 +public:
  130 + SrsFlvSegment();
  131 + virtual void reset();
  132 +};
  133 +
  134 +/**
111 * the plan for dvr. 135 * the plan for dvr.
112 * use to control the following dvr params: 136 * use to control the following dvr params:
113 * 1. filename: the filename for record file. 137 * 1. filename: the filename for record file.
@@ -127,20 +151,7 @@ protected: @@ -127,20 +151,7 @@ protected:
127 SrsSource* _source; 151 SrsSource* _source;
128 SrsRequest* _req; 152 SrsRequest* _req;
129 SrsRtmpJitter* jitter; 153 SrsRtmpJitter* jitter;
130 -protected:  
131 - /**  
132 - * current flv file path.  
133 - */  
134 - std::string current_flv_path;  
135 - /**  
136 - * whether current segment has keyframe.  
137 - */  
138 - bool segment_has_keyframe;  
139 - /**  
140 - * current segment duration and starttime.  
141 - */  
142 - int64_t duration;  
143 - int64_t starttime; 154 + SrsFlvSegment* segment;
144 public: 155 public:
145 SrsDvrPlan(); 156 SrsDvrPlan();
146 virtual ~SrsDvrPlan(); 157 virtual ~SrsDvrPlan();