Skip to content

Commit

Permalink
for #738, refine code for DVR mp4.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Feb 6, 2017
1 parent 0a054cd commit 3209ad2
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 226 deletions.
153 changes: 46 additions & 107 deletions trunk/src/app/srs_app_dvr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ using namespace std;
#include <srs_app_utility.hpp>
#include <srs_kernel_mp4.hpp>

// update the flv duration and filesize every this interval in ms.
#define SRS_DVR_UPDATE_DURATION_INTERVAL 60000

SrsDvrSegmenter::SrsDvrSegmenter()
{
req = NULL;
Expand Down Expand Up @@ -87,9 +84,9 @@ string SrsDvrSegmenter::get_path()
return path;
}

bool SrsDvrSegmenter::is_overflow(int64_t max_duration)
int64_t SrsDvrSegmenter::get_duration()
{
return duration >= max_duration;
return duration;
}

int SrsDvrSegmenter::open()
Expand All @@ -108,6 +105,8 @@ int SrsDvrSegmenter::open()
return ret;
}

tmp_dvr_file = path + ".tmp";

// create dir first.
std::string dir = srs_path_dirname(path);
if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) {
Expand All @@ -117,13 +116,9 @@ int SrsDvrSegmenter::open()
srs_info("create dir=%s ok", dir.c_str());

// create jitter.
if ((ret = create_jitter()) != ERROR_SUCCESS) {
srs_error("create jitter failed, path=%s. ret=%d", path.c_str(), ret);
return ret;
}

// generate the tmp flv path.
tmp_dvr_file = path + ".tmp";
srs_freep(jitter);
jitter = new SrsRtmpJitter();
duration = 0;

// open file writer, in append or create mode.
if ((ret = fs->open(tmp_dvr_file)) != ERROR_SUCCESS) {
Expand Down Expand Up @@ -158,8 +153,7 @@ int SrsDvrSegmenter::write_audio(SrsSharedPtrMessage* shared_audio)
return ret;
}

int64_t timestamp = plan->filter_timestamp(audio->timestamp);
if ((ret = encode_audio(audio, timestamp)) != ERROR_SUCCESS) {
if ((ret = encode_audio(audio)) != ERROR_SUCCESS) {
return ret;
}

Expand All @@ -183,15 +177,7 @@ int SrsDvrSegmenter::write_video(SrsSharedPtrMessage* shared_video)
bool is_sequence_header = SrsFlvCodec::video_is_sequence_header(payload, size);
bool is_key_frame = SrsFlvCodec::video_is_h264(payload, size)
&& SrsFlvCodec::video_is_keyframe(payload, size) && !is_sequence_header;
if (is_key_frame) {
if ((ret = plan->on_video_keyframe()) != ERROR_SUCCESS) {
return ret;
}
}
srs_verbose("dvr video is key: %d", is_key_frame);

int64_t timestamp = plan->filter_timestamp(video->timestamp);
if ((ret = encode_video(video, timestamp, is_sequence_header, is_key_frame)) != ERROR_SUCCESS) {
if ((ret = encode_video(video, is_sequence_header, is_key_frame)) != ERROR_SUCCESS) {
return ret;
}

Expand Down Expand Up @@ -253,18 +239,6 @@ string SrsDvrSegmenter::generate_path()
return flv_path;
}

int SrsDvrSegmenter::create_jitter()
{
int ret = ERROR_SUCCESS;

srs_freep(jitter);
jitter = new SrsRtmpJitter();

duration = 0;

return ret;
}

int SrsDvrSegmenter::on_reload_vhost_dvr(std::string vhost)
{
int ret = ERROR_SUCCESS;
Expand Down Expand Up @@ -447,13 +421,13 @@ int SrsDvrFlvSegmenter::encode_metadata(SrsSharedPtrMessage* metadata)
return ret;
}

int SrsDvrFlvSegmenter::encode_audio(SrsSharedPtrMessage* audio, int64_t dts)
int SrsDvrFlvSegmenter::encode_audio(SrsSharedPtrMessage* audio)
{
int ret = ERROR_SUCCESS;

char* payload = audio->payload;
int size = audio->size;
if ((ret = enc->write_audio(dts, payload, size)) != ERROR_SUCCESS) {
if ((ret = enc->write_audio(audio->timestamp, payload, size)) != ERROR_SUCCESS) {
return ret;
}

Expand All @@ -464,7 +438,7 @@ int SrsDvrFlvSegmenter::encode_audio(SrsSharedPtrMessage* audio, int64_t dts)
return ret;
}

int SrsDvrFlvSegmenter::encode_video(SrsSharedPtrMessage* video, int64_t dts, bool sh, bool keyframe)
int SrsDvrFlvSegmenter::encode_video(SrsSharedPtrMessage* video, bool sh, bool keyframe)
{
int ret = ERROR_SUCCESS;

Expand All @@ -489,7 +463,7 @@ int SrsDvrFlvSegmenter::encode_video(SrsSharedPtrMessage* video, int64_t dts, bo

char* payload = video->payload;
int size = video->size;
if ((ret = enc->write_video(dts, payload, size)) != ERROR_SUCCESS) {
if ((ret = enc->write_video(video->timestamp, payload, size)) != ERROR_SUCCESS) {
return ret;
}

Expand Down Expand Up @@ -557,13 +531,13 @@ int SrsDvrMp4Segmenter::encode_metadata(SrsSharedPtrMessage* metadata)
return ret;
}

int SrsDvrMp4Segmenter::encode_audio(SrsSharedPtrMessage* audio, int64_t dts)
int SrsDvrMp4Segmenter::encode_audio(SrsSharedPtrMessage* audio)
{
int ret = ERROR_SUCCESS;
return ret;
}

int SrsDvrMp4Segmenter::encode_video(SrsSharedPtrMessage* video, int64_t dts, bool sh, bool keyframe)
int SrsDvrMp4Segmenter::encode_video(SrsSharedPtrMessage* video, bool sh, bool keyframe)
{
int ret = ERROR_SUCCESS;
return ret;
Expand Down Expand Up @@ -644,10 +618,11 @@ SrsDvrPlan::~SrsDvrPlan()
srs_freep(async);
}

int SrsDvrPlan::initialize(SrsDvrSegmenter* s, SrsRequest* r)
int SrsDvrPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, SrsRequest* r)
{
int ret = ERROR_SUCCESS;

hub = h;
req = r;
segment = s;

Expand All @@ -662,16 +637,6 @@ int SrsDvrPlan::initialize(SrsDvrSegmenter* s, SrsRequest* r)
return ret;
}

int SrsDvrPlan::on_video_keyframe()
{
return ERROR_SUCCESS;
}

int64_t SrsDvrPlan::filter_timestamp(int64_t timestamp)
{
return timestamp;
}

int SrsDvrPlan::on_meta_data(SrsSharedPtrMessage* shared_metadata)
{
int ret = ERROR_SUCCESS;
Expand Down Expand Up @@ -795,28 +760,27 @@ void SrsDvrSessionPlan::on_unpublish()

SrsDvrSegmentPlan::SrsDvrSegmentPlan()
{
segment_duration = -1;
metadata = sh_video = sh_audio = NULL;
cduration = -1;
wait_keyframe = false;
}

SrsDvrSegmentPlan::~SrsDvrSegmentPlan()
{
srs_freep(sh_video);
srs_freep(sh_audio);
srs_freep(metadata);
}

int SrsDvrSegmentPlan::initialize(SrsDvrSegmenter* s, SrsRequest* req)
int SrsDvrSegmentPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, SrsRequest* r)
{
int ret = ERROR_SUCCESS;

if ((ret = SrsDvrPlan::initialize(s, req)) != ERROR_SUCCESS) {
if ((ret = SrsDvrPlan::initialize(h, s, r)) != ERROR_SUCCESS) {
return ret;
}

segment_duration = _srs_config->get_dvr_duration(req->vhost);
wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost);

cduration = _srs_config->get_dvr_duration(req->vhost);
// to ms
segment_duration *= 1000;
cduration *= 1000;

return ret;
}
Expand Down Expand Up @@ -851,28 +815,9 @@ void SrsDvrSegmentPlan::on_unpublish()
{
}

int SrsDvrSegmentPlan::on_meta_data(SrsSharedPtrMessage* shared_metadata)
{
int ret = ERROR_SUCCESS;

srs_freep(metadata);
metadata = shared_metadata->copy();

if ((ret = SrsDvrPlan::on_meta_data(shared_metadata)) != ERROR_SUCCESS) {
return ret;
}

return ret;
}

int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* shared_audio)
{
int ret = ERROR_SUCCESS;

if (SrsFlvCodec::audio_is_sequence_header(shared_audio->payload, shared_audio->size)) {
srs_freep(sh_audio);
sh_audio = shared_audio->copy();
}

if ((ret = update_duration(shared_audio)) != ERROR_SUCCESS) {
return ret;
Expand All @@ -889,11 +834,6 @@ int SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage* shared_video)
{
int ret = ERROR_SUCCESS;

if (SrsFlvCodec::video_is_sequence_header(shared_video->payload, shared_video->size)) {
srs_freep(sh_video);
sh_video = shared_video->copy();
}

if ((ret = update_duration(shared_video)) != ERROR_SUCCESS) {
return ret;
}
Expand All @@ -912,13 +852,13 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
srs_assert(segment);

// ignore if duration ok.
if (segment_duration <= 0 || !segment->is_overflow(segment_duration)) {
if (cduration <= 0 || segment->get_duration() < cduration) {
return ret;
}

// when wait keyframe, ignore if no frame arrived.
// @see https://github.com/ossrs/srs/issues/177
if (_srs_config->get_dvr_wait_keyframe(req->vhost)) {
if (wait_keyframe) {
if (!msg->is_video()) {
return ret;
}
Expand All @@ -944,16 +884,27 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
}

// update sequence header
if (metadata && (ret = SrsDvrPlan::on_meta_data(metadata)) != ERROR_SUCCESS) {
return ret;
}
if (sh_video && (ret = SrsDvrPlan::on_video(sh_video)) != ERROR_SUCCESS) {
if ((ret = hub->on_dvr_request_sh()) != ERROR_SUCCESS) {
return ret;
}
if (sh_audio && (ret = SrsDvrPlan::on_audio(sh_audio)) != ERROR_SUCCESS) {

return ret;
}

int SrsDvrSegmentPlan::on_reload_vhost_dvr(string vhost)
{
int ret = ERROR_SUCCESS;

if (req->vhost != vhost) {
return ret;
}

wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost);

cduration = _srs_config->get_dvr_duration(req->vhost);
// to ms
cduration *= 1000;

return ret;
}

Expand Down Expand Up @@ -997,7 +948,7 @@ int SrsDvr::initialize(SrsOriginHub* h, SrsRequest* r)
segmenter = new SrsDvrFlvSegmenter();
}

if ((ret = plan->initialize(segmenter, r)) != ERROR_SUCCESS) {
if ((ret = plan->initialize(hub, segmenter, r)) != ERROR_SUCCESS) {
return ret;
}

Expand Down Expand Up @@ -1029,8 +980,7 @@ void SrsDvr::on_unpublish()
plan->on_unpublish();
}

// TODO: FIXME: source should use shared message instead.
int SrsDvr::on_meta_data(SrsOnMetaDataPacket* m)
int SrsDvr::on_meta_data(SrsSharedPtrMessage* metadata)
{
int ret = ERROR_SUCCESS;

Expand All @@ -1039,18 +989,7 @@ int SrsDvr::on_meta_data(SrsOnMetaDataPacket* m)
return ret;
}

int size = 0;
char* payload = NULL;
if ((ret = m->encode(size, payload)) != ERROR_SUCCESS) {
return ret;
}

SrsSharedPtrMessage metadata;
if ((ret = metadata.create(NULL, payload, size)) != ERROR_SUCCESS) {
return ret;
}

if ((ret = plan->on_meta_data(&metadata)) != ERROR_SUCCESS) {
if ((ret = plan->on_meta_data(metadata)) != ERROR_SUCCESS) {
return ret;
}

Expand Down
Loading

0 comments on commit 3209ad2

Please sign in to comment.