mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	update dvr, extract flv segment
This commit is contained in:
		
							parent
							
								
									7ff8df4d97
								
							
						
					
					
						commit
						0c0010d529
					
				
					 2 changed files with 58 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -297,6 +297,20 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s
 | 
			
		|||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsFlvSegment::SrsFlvSegment()
 | 
			
		||||
{
 | 
			
		||||
    current_flv_path = "";
 | 
			
		||||
    segment_has_keyframe = false;
 | 
			
		||||
    duration = 0;
 | 
			
		||||
    starttime = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SrsFlvSegment::reset()
 | 
			
		||||
{
 | 
			
		||||
    duration = 0;
 | 
			
		||||
    starttime = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsDvrPlan::SrsDvrPlan()
 | 
			
		||||
{
 | 
			
		||||
    _source = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -305,9 +319,7 @@ SrsDvrPlan::SrsDvrPlan()
 | 
			
		|||
    dvr_enabled = false;
 | 
			
		||||
    fs = new SrsFileStream();
 | 
			
		||||
    enc = new SrsFlvEncoder();
 | 
			
		||||
    segment_has_keyframe = true;
 | 
			
		||||
    starttime = -1;
 | 
			
		||||
    duration = 0;
 | 
			
		||||
    segment = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsDvrPlan::~SrsDvrPlan()
 | 
			
		||||
| 
						 | 
				
			
			@ -315,6 +327,7 @@ SrsDvrPlan::~SrsDvrPlan()
 | 
			
		|||
    srs_freep(jitter);
 | 
			
		||||
    srs_freep(fs);
 | 
			
		||||
    srs_freep(enc);
 | 
			
		||||
    srs_freep(segment);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SrsDvrPlan::initialize(SrsSource* source, SrsRequest* req)
 | 
			
		||||
| 
						 | 
				
			
			@ -439,7 +452,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video)
 | 
			
		|||
#ifdef SRS_AUTO_HTTP_CALLBACK
 | 
			
		||||
    bool is_key_frame = SrsCodec::video_is_keyframe((int8_t*)payload, size);
 | 
			
		||||
    if (is_key_frame) {
 | 
			
		||||
        segment_has_keyframe = true;
 | 
			
		||||
        segment->segment_has_keyframe = true;
 | 
			
		||||
    }
 | 
			
		||||
    srs_verbose("dvr video is key: %d", is_key_frame);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -455,7 +468,9 @@ int SrsDvrPlan::flv_open(string stream, string path)
 | 
			
		|||
{
 | 
			
		||||
    int ret = ERROR_SUCCESS;
 | 
			
		||||
    
 | 
			
		||||
    current_flv_path = path;
 | 
			
		||||
    srs_freep(segment);
 | 
			
		||||
    segment = new SrsFlvSegment();
 | 
			
		||||
    
 | 
			
		||||
    std::string tmp_file = path + ".tmp";
 | 
			
		||||
    if ((ret = fs->open(tmp_file)) != ERROR_SUCCESS) {
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    segment_has_keyframe = false;
 | 
			
		||||
    segment->current_flv_path = path;
 | 
			
		||||
    
 | 
			
		||||
    srs_trace("dvr stream %s to file %s", stream.c_str(), path.c_str());
 | 
			
		||||
    return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -486,16 +501,16 @@ int SrsDvrPlan::flv_close()
 | 
			
		|||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    std::string tmp_file = current_flv_path + ".tmp";
 | 
			
		||||
    if (rename(tmp_file.c_str(), current_flv_path.c_str()) < 0) {
 | 
			
		||||
    std::string tmp_file = segment->current_flv_path + ".tmp";
 | 
			
		||||
    if (rename(tmp_file.c_str(), segment->current_flv_path.c_str()) < 0) {
 | 
			
		||||
        ret = ERROR_SYSTEM_FILE_RENAME;
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
#ifdef SRS_AUTO_HTTP_CALLBACK
 | 
			
		||||
    if (segment_has_keyframe) {
 | 
			
		||||
    if (segment->segment_has_keyframe) {
 | 
			
		||||
        if ((ret = on_dvr_keyframe()) != ERROR_SUCCESS) {
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -510,11 +525,11 @@ int SrsDvrPlan::update_duration(SrsSharedPtrMessage* msg)
 | 
			
		|||
    int ret = ERROR_SUCCESS;
 | 
			
		||||
    
 | 
			
		||||
    // foreach msg, collect the duration.
 | 
			
		||||
    if (starttime < 0 || starttime > msg->header.timestamp) {
 | 
			
		||||
        starttime = msg->header.timestamp;
 | 
			
		||||
    if (segment->starttime < 0 || segment->starttime > msg->header.timestamp) {
 | 
			
		||||
        segment->starttime = msg->header.timestamp;
 | 
			
		||||
    }
 | 
			
		||||
    duration += msg->header.timestamp - starttime;
 | 
			
		||||
    starttime = msg->header.timestamp;
 | 
			
		||||
    segment->duration += msg->header.timestamp - segment->starttime;
 | 
			
		||||
    segment->starttime = msg->header.timestamp;
 | 
			
		||||
    
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -630,10 +645,11 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
 | 
			
		|||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    srs_assert(segment);
 | 
			
		||||
    
 | 
			
		||||
    // reap if exceed duration.
 | 
			
		||||
    if (duration > 0 && segment_duration > 0 && duration > segment_duration) {
 | 
			
		||||
        duration = 0;
 | 
			
		||||
        starttime = -1;
 | 
			
		||||
    if (segment->duration > 0 && segment_duration > 0 && segment->duration > segment_duration) {
 | 
			
		||||
        segment->reset();
 | 
			
		||||
        
 | 
			
		||||
        if ((ret = flv_close()) != ERROR_SUCCESS) {
 | 
			
		||||
            return ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,6 +107,30 @@ private:
 | 
			
		|||
    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.
 | 
			
		||||
* use to control the following dvr params:
 | 
			
		||||
| 
						 | 
				
			
			@ -127,20 +151,7 @@ protected:
 | 
			
		|||
    SrsSource* _source;
 | 
			
		||||
    SrsRequest* _req;
 | 
			
		||||
    SrsRtmpJitter* jitter;
 | 
			
		||||
protected:
 | 
			
		||||
    /**
 | 
			
		||||
    * 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;
 | 
			
		||||
    SrsFlvSegment* segment;
 | 
			
		||||
public:
 | 
			
		||||
    SrsDvrPlan();
 | 
			
		||||
    virtual ~SrsDvrPlan();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue