update dvr, extract flv segment

pull/133/head
winlin 11 years ago
parent 7ff8df4d97
commit 0c0010d529

@ -297,6 +297,20 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s
return ret; return ret;
} }
SrsFlvSegment::SrsFlvSegment()
{
current_flv_path = "";
segment_has_keyframe = false;
duration = 0;
starttime = -1;
}
void SrsFlvSegment::reset()
{
duration = 0;
starttime = -1;
}
SrsDvrPlan::SrsDvrPlan() SrsDvrPlan::SrsDvrPlan()
{ {
_source = NULL; _source = NULL;
@ -305,9 +319,7 @@ SrsDvrPlan::SrsDvrPlan()
dvr_enabled = false; dvr_enabled = false;
fs = new SrsFileStream(); fs = new SrsFileStream();
enc = new SrsFlvEncoder(); enc = new SrsFlvEncoder();
segment_has_keyframe = true; segment = NULL;
starttime = -1;
duration = 0;
} }
SrsDvrPlan::~SrsDvrPlan() SrsDvrPlan::~SrsDvrPlan()
@ -315,6 +327,7 @@ SrsDvrPlan::~SrsDvrPlan()
srs_freep(jitter); srs_freep(jitter);
srs_freep(fs); srs_freep(fs);
srs_freep(enc); srs_freep(enc);
srs_freep(segment);
} }
int SrsDvrPlan::initialize(SrsSource* source, SrsRequest* req) int SrsDvrPlan::initialize(SrsSource* source, SrsRequest* req)
@ -439,7 +452,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video)
#ifdef SRS_AUTO_HTTP_CALLBACK #ifdef SRS_AUTO_HTTP_CALLBACK
bool is_key_frame = SrsCodec::video_is_keyframe((int8_t*)payload, size); bool is_key_frame = SrsCodec::video_is_keyframe((int8_t*)payload, size);
if (is_key_frame) { if (is_key_frame) {
segment_has_keyframe = true; segment->segment_has_keyframe = true;
} }
srs_verbose("dvr video is key: %d", is_key_frame); srs_verbose("dvr video is key: %d", is_key_frame);
#endif #endif
@ -455,7 +468,9 @@ int SrsDvrPlan::flv_open(string stream, string path)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
current_flv_path = path; srs_freep(segment);
segment = new SrsFlvSegment();
std::string tmp_file = path + ".tmp"; std::string tmp_file = path + ".tmp";
if ((ret = fs->open(tmp_file)) != ERROR_SUCCESS) { if ((ret = fs->open(tmp_file)) != ERROR_SUCCESS) {
srs_error("open file stream for file %s failed. ret=%d", path.c_str(), ret); 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)
return ret; return ret;
} }
segment_has_keyframe = false; segment->current_flv_path = path;
srs_trace("dvr stream %s to file %s", stream.c_str(), path.c_str()); srs_trace("dvr stream %s to file %s", stream.c_str(), path.c_str());
return ret; return ret;
@ -486,16 +501,16 @@ int SrsDvrPlan::flv_close()
return ret; return ret;
} }
std::string tmp_file = current_flv_path + ".tmp"; std::string tmp_file = segment->current_flv_path + ".tmp";
if (rename(tmp_file.c_str(), current_flv_path.c_str()) < 0) { if (rename(tmp_file.c_str(), segment->current_flv_path.c_str()) < 0) {
ret = ERROR_SYSTEM_FILE_RENAME; ret = ERROR_SYSTEM_FILE_RENAME;
srs_error("rename flv file failed, %s => %s. ret=%d", srs_error("rename flv file failed, %s => %s. ret=%d",
tmp_file.c_str(), current_flv_path.c_str(), ret); tmp_file.c_str(), segment->current_flv_path.c_str(), ret);
return ret; return ret;
} }
#ifdef SRS_AUTO_HTTP_CALLBACK #ifdef SRS_AUTO_HTTP_CALLBACK
if (segment_has_keyframe) { if (segment->segment_has_keyframe) {
if ((ret = on_dvr_keyframe()) != ERROR_SUCCESS) { if ((ret = on_dvr_keyframe()) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -510,11 +525,11 @@ int SrsDvrPlan::update_duration(SrsSharedPtrMessage* msg)
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// foreach msg, collect the duration. // foreach msg, collect the duration.
if (starttime < 0 || starttime > msg->header.timestamp) { if (segment->starttime < 0 || segment->starttime > msg->header.timestamp) {
starttime = msg->header.timestamp; segment->starttime = msg->header.timestamp;
} }
duration += msg->header.timestamp - starttime; segment->duration += msg->header.timestamp - segment->starttime;
starttime = msg->header.timestamp; segment->starttime = msg->header.timestamp;
return ret; return ret;
} }
@ -630,10 +645,11 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
return ret; return ret;
} }
srs_assert(segment);
// reap if exceed duration. // reap if exceed duration.
if (duration > 0 && segment_duration > 0 && duration > segment_duration) { if (segment->duration > 0 && segment_duration > 0 && segment->duration > segment_duration) {
duration = 0; segment->reset();
starttime = -1;
if ((ret = flv_close()) != ERROR_SUCCESS) { if ((ret = flv_close()) != ERROR_SUCCESS) {
return ret; return ret;

@ -107,6 +107,30 @@ private:
virtual int write_tag(char* header, int header_size, char* tag, int tag_size); virtual int write_tag(char* header, int header_size, char* tag, int tag_size);
}; };
/**
* a piece of flv segment.
*/
class SrsFlvSegment
{
public:
/**
* current flv file path.
*/
std::string current_flv_path;
/**
* whether current segment has keyframe.
*/
bool segment_has_keyframe;
/**
* current segment duration and starttime.
*/
int64_t duration;
int64_t starttime;
public:
SrsFlvSegment();
virtual void reset();
};
/** /**
* the plan for dvr. * the plan for dvr.
* use to control the following dvr params: * use to control the following dvr params:
@ -127,20 +151,7 @@ protected:
SrsSource* _source; SrsSource* _source;
SrsRequest* _req; SrsRequest* _req;
SrsRtmpJitter* jitter; SrsRtmpJitter* jitter;
protected: SrsFlvSegment* segment;
/**
* current flv file path.
*/
std::string current_flv_path;
/**
* whether current segment has keyframe.
*/
bool segment_has_keyframe;
/**
* current segment duration and starttime.
*/
int64_t duration;
int64_t starttime;
public: public:
SrsDvrPlan(); SrsDvrPlan();
virtual ~SrsDvrPlan(); virtual ~SrsDvrPlan();

Loading…
Cancel
Save