mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
For #913: TS/HLS/MPEGTS support complex error
This commit is contained in:
parent
20a42599f3
commit
abcaba33ee
24 changed files with 699 additions and 823 deletions
|
@ -56,14 +56,14 @@ SrsAsyncCallWorker::~SrsAsyncCallWorker()
|
|||
srs_cond_destroy(wait);
|
||||
}
|
||||
|
||||
int SrsAsyncCallWorker::execute(ISrsAsyncCallTask* t)
|
||||
srs_error_t SrsAsyncCallWorker::execute(ISrsAsyncCallTask* t)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
tasks.push_back(t);
|
||||
srs_cond_signal(wait);
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsAsyncCallWorker::count()
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
SrsAsyncCallWorker();
|
||||
virtual ~SrsAsyncCallWorker();
|
||||
public:
|
||||
virtual int execute(ISrsAsyncCallTask* t);
|
||||
virtual srs_error_t execute(ISrsAsyncCallTask* t);
|
||||
virtual int count();
|
||||
public:
|
||||
virtual srs_error_t start();
|
||||
|
|
|
@ -85,6 +85,7 @@ SrsFragmentedMp4::~SrsFragmentedMp4()
|
|||
int SrsFragmentedMp4::initialize(SrsRequest* r, bool video, SrsMpdWriter* mpd, uint32_t tid)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
string file_home;
|
||||
string file_name;
|
||||
|
@ -97,7 +98,10 @@ int SrsFragmentedMp4::initialize(SrsRequest* r, bool video, SrsMpdWriter* mpd, u
|
|||
string home = _srs_config->get_dash_path(r->vhost);
|
||||
set_path(home + "/" + file_home + "/" + file_name);
|
||||
|
||||
if ((ret = create_dir()) != ERROR_SUCCESS) {
|
||||
if ((err = create_dir()) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -146,6 +150,7 @@ int SrsFragmentedMp4::write(SrsSharedPtrMessage* shared_msg, SrsFormat* format)
|
|||
int SrsFragmentedMp4::reap(uint64_t& dts)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((ret = enc->flush(dts)) != ERROR_SUCCESS) {
|
||||
srs_error("DASH: Flush encoder failed, ret=%d", ret);
|
||||
|
@ -154,7 +159,10 @@ int SrsFragmentedMp4::reap(uint64_t& dts)
|
|||
|
||||
srs_freep(fw);
|
||||
|
||||
if ((ret = rename()) != ERROR_SUCCESS) {
|
||||
if ((err = rename()) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -191,6 +199,7 @@ srs_error_t SrsMpdWriter::initialize(SrsRequest* r)
|
|||
int SrsMpdWriter::write(SrsFormat* format)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// MPD is not expired?
|
||||
if (last_update_mpd != -1 && srs_get_system_time_ms() - last_update_mpd < update_period) {
|
||||
|
@ -204,7 +213,10 @@ int SrsMpdWriter::write(SrsFormat* format)
|
|||
|
||||
fragment_home = srs_path_dirname(mpd_path) + "/" + req->stream;
|
||||
|
||||
if ((ret = srs_create_dir_recursively(full_home)) != ERROR_SUCCESS) {
|
||||
if ((err = srs_create_dir_recursively(full_home)) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("DASH: Create MPD home failed, home=%s, ret=%d", full_home.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -427,6 +439,7 @@ int SrsDashController::refresh_mpd(SrsFormat* format)
|
|||
int SrsDashController::refresh_init_mp4(SrsSharedPtrMessage* msg, SrsFormat* format)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (msg->size <= 0 || (msg->is_video() && !format->vcodec->is_avc_codec_ok())
|
||||
|| (msg->is_audio() && !format->acodec->is_aac_codec_ok())) {
|
||||
|
@ -435,7 +448,10 @@ int SrsDashController::refresh_init_mp4(SrsSharedPtrMessage* msg, SrsFormat* for
|
|||
}
|
||||
|
||||
string full_home = home + "/" + req->app + "/" + req->stream;
|
||||
if ((ret = srs_create_dir_recursively(full_home)) != ERROR_SUCCESS) {
|
||||
if ((err = srs_create_dir_recursively(full_home)) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("DASH: Create media home failed, home=%s, ret=%d", full_home.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -457,7 +473,10 @@ int SrsDashController::refresh_init_mp4(SrsSharedPtrMessage* msg, SrsFormat* for
|
|||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = init_mp4->rename()) != ERROR_SUCCESS) {
|
||||
if ((err = init_mp4->rename()) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ SrsFragment* SrsDvrSegmenter::current()
|
|||
int SrsDvrSegmenter::open()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// ignore when already open.
|
||||
if (fs->is_open()) {
|
||||
|
@ -99,7 +100,10 @@ int SrsDvrSegmenter::open()
|
|||
fragment->set_path(path);
|
||||
|
||||
// create dir first.
|
||||
if ((ret = fragment->create_dir()) != ERROR_SUCCESS) {
|
||||
if ((err = fragment->create_dir()) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -177,6 +181,7 @@ int SrsDvrSegmenter::write_video(SrsSharedPtrMessage* shared_video, SrsFormat* f
|
|||
int SrsDvrSegmenter::close()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// ignore when already closed.
|
||||
if (!fs->is_open()) {
|
||||
|
@ -191,13 +196,19 @@ int SrsDvrSegmenter::close()
|
|||
fs->close();
|
||||
|
||||
// when tmp flv file exists, reap it.
|
||||
if ((ret = fragment->rename()) != ERROR_SUCCESS) {
|
||||
if ((err = fragment->rename()) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: FIXME: the http callback is async, which will trigger thread switch,
|
||||
// so the on_video maybe invoked during the http callback, and error.
|
||||
if ((ret = plan->on_reap_segment()) != ERROR_SUCCESS) {
|
||||
if ((err = plan->on_reap_segment()) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("dvr: notify plan to reap segment failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -669,20 +680,20 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsDvrPlan::on_reap_segment()
|
||||
srs_error_t SrsDvrPlan::on_reap_segment()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int cid = _srs_context->get_id();
|
||||
|
||||
SrsFragment* fragment = segment->current();
|
||||
string fullpath = fragment->fullpath();
|
||||
|
||||
if ((ret = async->execute(new SrsDvrAsyncCallOnDvr(cid, req, fullpath))) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = async->execute(new SrsDvrAsyncCallOnDvr(cid, req, fullpath))) != srs_success) {
|
||||
return srs_error_wrap(err, "reap segment");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsDvrPlan::create_plan(string vhost, SrsDvrPlan** pplan)
|
||||
|
|
|
@ -203,7 +203,7 @@ public:
|
|||
// Internal interface for segmenter.
|
||||
public:
|
||||
// When segmenter close a segment.
|
||||
virtual int on_reap_segment();
|
||||
virtual srs_error_t on_reap_segment();
|
||||
public:
|
||||
static srs_error_t create_plan(std::string vhost, SrsDvrPlan** pplan);
|
||||
};
|
||||
|
|
|
@ -158,12 +158,16 @@ void SrsForwarder::on_unpublish()
|
|||
int SrsForwarder::on_meta_data(SrsSharedPtrMessage* shared_metadata)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsSharedPtrMessage* metadata = shared_metadata->copy();
|
||||
|
||||
// TODO: FIXME: config the jitter of Forwarder.
|
||||
if ((ret = jitter->correct(metadata, SrsRtmpJitterAlgorithmOFF)) != ERROR_SUCCESS) {
|
||||
if ((err = jitter->correct(metadata, SrsRtmpJitterAlgorithmOFF)) != srs_success) {
|
||||
srs_freep(metadata);
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -177,12 +181,16 @@ int SrsForwarder::on_meta_data(SrsSharedPtrMessage* shared_metadata)
|
|||
int SrsForwarder::on_audio(SrsSharedPtrMessage* shared_audio)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsSharedPtrMessage* msg = shared_audio->copy();
|
||||
|
||||
// TODO: FIXME: config the jitter of Forwarder.
|
||||
if ((ret = jitter->correct(msg, SrsRtmpJitterAlgorithmOFF)) != ERROR_SUCCESS) {
|
||||
if ((err = jitter->correct(msg, SrsRtmpJitterAlgorithmOFF)) != srs_success) {
|
||||
srs_freep(msg);
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -201,12 +209,16 @@ int SrsForwarder::on_audio(SrsSharedPtrMessage* shared_audio)
|
|||
int SrsForwarder::on_video(SrsSharedPtrMessage* shared_video)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsSharedPtrMessage* msg = shared_video->copy();
|
||||
|
||||
// TODO: FIXME: config the jitter of Forwarder.
|
||||
if ((ret = jitter->correct(msg, SrsRtmpJitterAlgorithmOFF)) != ERROR_SUCCESS) {
|
||||
if ((err = jitter->correct(msg, SrsRtmpJitterAlgorithmOFF)) != srs_success) {
|
||||
srs_freep(msg);
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,33 +77,30 @@ void SrsFragment::set_path(string v)
|
|||
filepath = v;
|
||||
}
|
||||
|
||||
int SrsFragment::unlink_file()
|
||||
srs_error_t SrsFragment::unlink_file()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (::unlink(filepath.c_str()) < 0) {
|
||||
ret = ERROR_SYSTEM_FRAGMENT_UNLINK;
|
||||
srs_error("Unlink fragment failed, file=%s, ret=%d.", filepath.c_str(), ret);
|
||||
return ret;
|
||||
return srs_error_new(ERROR_SYSTEM_FRAGMENT_UNLINK, "unlink %s", filepath.c_str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsFragment::create_dir()
|
||||
srs_error_t SrsFragment::create_dir()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::string segment_dir = srs_path_dirname(filepath);
|
||||
|
||||
if ((ret = srs_create_dir_recursively(segment_dir)) != ERROR_SUCCESS) {
|
||||
srs_error("Create dir %s failed. ret=%d", segment_dir.c_str(), ret);
|
||||
return ret;
|
||||
if ((err = srs_create_dir_recursively(segment_dir)) != srs_success) {
|
||||
return srs_error_wrap(err, "create %s", segment_dir.c_str());
|
||||
}
|
||||
|
||||
srs_info("Create dir %s ok", segment_dir.c_str());
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
string SrsFragment::tmppath()
|
||||
|
@ -111,34 +108,30 @@ string SrsFragment::tmppath()
|
|||
return filepath + ".tmp";
|
||||
}
|
||||
|
||||
int SrsFragment::unlink_tmpfile()
|
||||
srs_error_t SrsFragment::unlink_tmpfile()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
string filepath = tmppath();
|
||||
if (::unlink(filepath.c_str()) < 0) {
|
||||
ret = ERROR_SYSTEM_FRAGMENT_UNLINK;
|
||||
srs_error("Unlink temporary fragment failed, file=%s, ret=%d.", filepath.c_str(), ret);
|
||||
return ret;
|
||||
return srs_error_new(ERROR_SYSTEM_FRAGMENT_UNLINK, "unlink tmp file %s", filepath.c_str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsFragment::rename()
|
||||
srs_error_t SrsFragment::rename()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
string full_path = fullpath();
|
||||
string tmp_file = tmppath();
|
||||
|
||||
if (::rename(tmp_file.c_str(), full_path.c_str()) < 0) {
|
||||
ret = ERROR_SYSTEM_FRAGMENT_RENAME;
|
||||
srs_error("rename ts file failed, %s => %s. ret=%d", tmp_file.c_str(), full_path.c_str(), ret);
|
||||
return ret;
|
||||
return srs_error_new(ERROR_SYSTEM_FRAGMENT_RENAME, "rename %s to %s", tmp_file.c_str(), full_path.c_str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsFragmentWindow::SrsFragmentWindow()
|
||||
|
@ -164,14 +157,15 @@ SrsFragmentWindow::~SrsFragmentWindow()
|
|||
|
||||
void SrsFragmentWindow::dispose()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::vector<SrsFragment*>::iterator it;
|
||||
|
||||
for (it = fragments.begin(); it != fragments.end(); ++it) {
|
||||
SrsFragment* fragment = *it;
|
||||
if ((ret = fragment->unlink_file()) != ERROR_SUCCESS) {
|
||||
srs_warn("Unlink ts failed, file=%s, ret=%d", fragment->fullpath().c_str(), ret);
|
||||
if ((err = fragment->unlink_file()) != srs_success) {
|
||||
srs_warn("Unlink ts failed %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
srs_freep(fragment);
|
||||
}
|
||||
|
@ -179,8 +173,9 @@ void SrsFragmentWindow::dispose()
|
|||
|
||||
for (it = expired_fragments.begin(); it != expired_fragments.end(); ++it) {
|
||||
SrsFragment* fragment = *it;
|
||||
if ((ret = fragment->unlink_file()) != ERROR_SUCCESS) {
|
||||
srs_warn("Unlink ts failed, file=%s, ret=%d", fragment->fullpath().c_str(), ret);
|
||||
if ((err = fragment->unlink_file()) != srs_success) {
|
||||
srs_warn("Unlink ts failed %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
srs_freep(fragment);
|
||||
}
|
||||
|
@ -217,14 +212,15 @@ void SrsFragmentWindow::shrink(int64_t window)
|
|||
|
||||
void SrsFragmentWindow::clear_expired(bool delete_files)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::vector<SrsFragment*>::iterator it;
|
||||
|
||||
for (it = expired_fragments.begin(); it != expired_fragments.end(); ++it) {
|
||||
SrsFragment* fragment = *it;
|
||||
if (delete_files && (ret = fragment->unlink_file()) != ERROR_SUCCESS) {
|
||||
srs_warn("Unlink ts failed, file=%s, ret=%d", fragment->fullpath().c_str(), ret);
|
||||
if (delete_files && (err = fragment->unlink_file()) != srs_success) {
|
||||
srs_warn("Unlink ts failed, %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
srs_freep(fragment);
|
||||
}
|
||||
|
|
|
@ -63,16 +63,16 @@ public:
|
|||
virtual void set_path(std::string v);
|
||||
// Unlink the fragment, to delete the file.
|
||||
// @remark Ignore any error.
|
||||
virtual int unlink_file();
|
||||
virtual srs_error_t unlink_file();
|
||||
// Create the dir for file recursively.
|
||||
virtual int create_dir();
|
||||
virtual srs_error_t create_dir();
|
||||
public:
|
||||
// Get the temporary path for file.
|
||||
virtual std::string tmppath();
|
||||
// Unlink the temporary file.
|
||||
virtual int unlink_tmpfile();
|
||||
virtual srs_error_t unlink_tmpfile();
|
||||
// Rename the temp file to final file.
|
||||
virtual int rename();
|
||||
virtual srs_error_t rename();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -433,6 +433,7 @@ int SrsHds::on_audio(SrsSharedPtrMessage* msg)
|
|||
int SrsHds::flush_mainfest()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
char buf[1024] = {0};
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||||
|
@ -446,7 +447,10 @@ int SrsHds::flush_mainfest()
|
|||
, hds_req->stream.c_str(), hds_req->stream.c_str(), hds_req->stream.c_str());
|
||||
|
||||
string dir = _srs_config->get_hds_path(hds_req->vhost) + "/" + hds_req->app;
|
||||
if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) {
|
||||
if ((err = srs_create_dir_recursively(dir)) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("hds create dir failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -210,13 +210,14 @@ SrsHlsMuxer::~SrsHlsMuxer()
|
|||
|
||||
void SrsHlsMuxer::dispose()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
segments->dispose();
|
||||
|
||||
if (current) {
|
||||
if ((ret = current->unlink_tmpfile()) != ERROR_SUCCESS) {
|
||||
srs_warn("Unlink tmp ts failed, ret=%d", ret);
|
||||
if ((err = current->unlink_tmpfile()) != srs_success) {
|
||||
srs_warn("Unlink tmp ts failed %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
srs_freep(current);
|
||||
}
|
||||
|
@ -264,11 +265,11 @@ srs_error_t SrsHlsMuxer::initialize()
|
|||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
|
||||
srs_error_t SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
|
||||
string path, string m3u8_file, string ts_file, double fragment, double window,
|
||||
bool ts_floor, double aof_ratio, bool cleanup, bool wait_keyframe
|
||||
) {
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
srs_freep(req);
|
||||
req = r->copy();
|
||||
|
@ -295,22 +296,21 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
|
|||
|
||||
// create m3u8 dir once.
|
||||
m3u8_dir = srs_path_dirname(m3u8);
|
||||
if ((ret = srs_create_dir_recursively(m3u8_dir)) != ERROR_SUCCESS) {
|
||||
srs_error("create app dir %s failed. ret=%d", m3u8_dir.c_str(), ret);
|
||||
return ret;
|
||||
if ((err = srs_create_dir_recursively(m3u8_dir)) != srs_success) {
|
||||
return srs_error_wrap(err, "create dir");
|
||||
}
|
||||
srs_info("create m3u8 dir %s ok", m3u8_dir.c_str());
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::segment_open()
|
||||
srs_error_t SrsHlsMuxer::segment_open()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (current) {
|
||||
srs_warn("ignore the segment open, for segment is already open.");
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// when segment open, the current segment must be NULL.
|
||||
|
@ -421,24 +421,23 @@ int SrsHlsMuxer::segment_open()
|
|||
current->uri += ts_url;
|
||||
|
||||
// create dir recursively for hls.
|
||||
if ((ret = current->create_dir()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = current->create_dir()) != srs_success) {
|
||||
return srs_error_wrap(err, "create dir");
|
||||
}
|
||||
|
||||
// open temp ts file.
|
||||
std::string tmp_file = current->tmppath();
|
||||
if ((ret = current->tscw->open(tmp_file.c_str())) != ERROR_SUCCESS) {
|
||||
srs_error("open hls muxer failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = current->tscw->open(tmp_file.c_str())) != srs_success) {
|
||||
return srs_error_wrap(err, "open hls muxer");
|
||||
}
|
||||
srs_info("open HLS muxer success. path=%s, tmp=%s", current->fullpath().c_str(), tmp_file.c_str());
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::on_sequence_header()
|
||||
srs_error_t SrsHlsMuxer::on_sequence_header()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
srs_assert(current);
|
||||
|
||||
|
@ -446,7 +445,7 @@ int SrsHlsMuxer::on_sequence_header()
|
|||
// when close the segement, it will write a discontinuity to m3u8 file.
|
||||
current->set_sequence_header(true);
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
bool SrsHlsMuxer::is_segment_overflow()
|
||||
|
@ -494,45 +493,45 @@ bool SrsHlsMuxer::pure_audio()
|
|||
return current && current->tscw && current->tscw->video_codec() == SrsVideoCodecIdDisabled;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::flush_audio(SrsTsMessageCache* cache)
|
||||
srs_error_t SrsHlsMuxer::flush_audio(SrsTsMessageCache* cache)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// if current is NULL, segment is not open, ignore the flush event.
|
||||
if (!current) {
|
||||
srs_warn("flush audio ignored, for segment is not open.");
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!cache->audio || cache->audio->payload->length() <= 0) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// update the duration of segment.
|
||||
current->append(cache->audio->pts / 90);
|
||||
|
||||
if ((ret = current->tscw->write_audio(cache->audio)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = current->tscw->write_audio(cache->audio)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: write audio");
|
||||
}
|
||||
|
||||
// write success, clear and free the msg
|
||||
srs_freep(cache->audio);
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::flush_video(SrsTsMessageCache* cache)
|
||||
srs_error_t SrsHlsMuxer::flush_video(SrsTsMessageCache* cache)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// if current is NULL, segment is not open, ignore the flush event.
|
||||
if (!current) {
|
||||
srs_warn("flush video ignored, for segment is not open.");
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!cache->video || cache->video->payload->length() <= 0) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_assert(current);
|
||||
|
@ -540,23 +539,23 @@ int SrsHlsMuxer::flush_video(SrsTsMessageCache* cache)
|
|||
// update the duration of segment.
|
||||
current->append(cache->video->dts / 90);
|
||||
|
||||
if ((ret = current->tscw->write_video(cache->video)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = current->tscw->write_video(cache->video)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: write video");
|
||||
}
|
||||
|
||||
// write success, clear and free the msg
|
||||
srs_freep(cache->video);
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::segment_close()
|
||||
srs_error_t SrsHlsMuxer::segment_close()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!current) {
|
||||
srs_warn("ignore the segment close, for segment is not open.");
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// when close current segment, the current segment must not be NULL.
|
||||
|
@ -568,17 +567,14 @@ int SrsHlsMuxer::segment_close()
|
|||
// make the segment more acceptable, when in [min, max_td * 2], it's ok.
|
||||
if (current->duration() >= SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS && (int)current->duration() <= max_td * 2 * 1000) {
|
||||
// use async to call the http hooks, for it will cause thread switch.
|
||||
if ((ret = async->execute(new SrsDvrAsyncCallOnHls(
|
||||
_srs_context->get_id(), req,
|
||||
current->fullpath(), current->uri, m3u8, m3u8_url,
|
||||
current->sequence_no, current->duration() / 1000.0))) != ERROR_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
if ((err = async->execute(new SrsDvrAsyncCallOnHls(_srs_context->get_id(), req, current->fullpath(),
|
||||
current->uri, m3u8, m3u8_url, current->sequence_no, current->duration() / 1000.0))) != srs_success) {
|
||||
return srs_error_wrap(err, "segment close");
|
||||
}
|
||||
|
||||
// use async to call the http hooks, for it will cause thread switch.
|
||||
if ((ret = async->execute(new SrsDvrAsyncCallOnHlsNotify(_srs_context->get_id(), req, current->uri))) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = async->execute(new SrsDvrAsyncCallOnHlsNotify(_srs_context->get_id(), req, current->uri))) != srs_success) {
|
||||
return srs_error_wrap(err, "segment close");
|
||||
}
|
||||
srs_info("Reap ts segment, sequence_no=%d, uri=%s, duration=%" PRId64 "ms", current->sequence_no, current->uri.c_str(), current->duration());
|
||||
|
||||
|
@ -586,8 +582,8 @@ int SrsHlsMuxer::segment_close()
|
|||
srs_freep(current->tscw);
|
||||
|
||||
// rename from tmp to real path
|
||||
if ((ret = current->rename()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = current->rename()) != srs_success) {
|
||||
return srs_error_wrap(err, "rename");
|
||||
}
|
||||
|
||||
segments->append(current);
|
||||
|
@ -599,8 +595,8 @@ int SrsHlsMuxer::segment_close()
|
|||
srs_trace("Drop ts segment, sequence_no=%d, uri=%s, duration=%" PRId64 "ms", current->sequence_no, current->uri.c_str(), current->duration());
|
||||
|
||||
// rename from tmp to real path
|
||||
if ((ret = current->unlink_tmpfile()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = current->unlink_tmpfile()) != srs_success) {
|
||||
return srs_error_wrap(err, "rename");
|
||||
}
|
||||
srs_freep(current);
|
||||
}
|
||||
|
@ -609,34 +605,32 @@ int SrsHlsMuxer::segment_close()
|
|||
segments->shrink(hls_window * 1000);
|
||||
|
||||
// refresh the m3u8, donot contains the removed ts
|
||||
ret = refresh_m3u8();
|
||||
err = refresh_m3u8();
|
||||
|
||||
// remove the ts file.
|
||||
segments->clear_expired(hls_cleanup);
|
||||
|
||||
// check ret of refresh m3u8
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
srs_error("refresh m3u8 failed. ret=%d", ret);
|
||||
return ret;
|
||||
if (err != srs_success) {
|
||||
return srs_error_wrap(err, "hls: refresh m3u8");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::refresh_m3u8()
|
||||
srs_error_t SrsHlsMuxer::refresh_m3u8()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// no segments, also no m3u8, return.
|
||||
if (segments->empty()) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
std::string temp_m3u8 = m3u8 + ".temp";
|
||||
if ((ret = _refresh_m3u8(temp_m3u8)) == ERROR_SUCCESS) {
|
||||
if ((err = _refresh_m3u8(temp_m3u8)) == srs_success) {
|
||||
if (rename(temp_m3u8.c_str(), m3u8.c_str()) < 0) {
|
||||
ret = ERROR_HLS_WRITE_FAILED;
|
||||
srs_error("rename m3u8 file failed. %s => %s, ret=%d", temp_m3u8.c_str(), m3u8.c_str(), ret);
|
||||
err = srs_error_new(ERROR_HLS_WRITE_FAILED, "hls: rename m3u8 file failed. %s => %s", temp_m3u8.c_str(), m3u8.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -647,22 +641,22 @@ int SrsHlsMuxer::refresh_m3u8()
|
|||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
|
||||
srs_error_t SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// no segments, return.
|
||||
if (segments->empty()) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsFileWriter writer;
|
||||
if ((ret = writer.open(m3u8_file)) != ERROR_SUCCESS) {
|
||||
srs_error("open m3u8 file %s failed. ret=%d", m3u8_file.c_str(), ret);
|
||||
return ret;
|
||||
return srs_error_new(ret, "hls: open m3u8 file %s", m3u8_file.c_str());
|
||||
}
|
||||
srs_info("open m3u8 file %s success.", m3u8_file.c_str());
|
||||
|
||||
|
@ -723,12 +717,11 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
|
|||
// write m3u8 to writer.
|
||||
std::string m3u8 = ss.str();
|
||||
if ((ret = writer.write((char*)m3u8.c_str(), (int)m3u8.length(), NULL)) != ERROR_SUCCESS) {
|
||||
srs_error("write m3u8 failed. ret=%d", ret);
|
||||
return ret;
|
||||
return srs_error_new(ret, "hls: write m3u8");
|
||||
}
|
||||
srs_info("write m3u8 %s success.", m3u8_file.c_str());
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsHlsController::SrsHlsController()
|
||||
|
@ -777,9 +770,9 @@ int SrsHlsController::deviation()
|
|||
return muxer->deviation();
|
||||
}
|
||||
|
||||
int SrsHlsController::on_publish(SrsRequest* req)
|
||||
srs_error_t SrsHlsController::on_publish(SrsRequest* req)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::string vhost = req->vhost;
|
||||
std::string stream = req->stream;
|
||||
|
@ -807,42 +800,37 @@ int SrsHlsController::on_publish(SrsRequest* req)
|
|||
// for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase.
|
||||
|
||||
// open muxer
|
||||
if ((ret = muxer->update_config(req, entry_prefix,
|
||||
path, m3u8_file, ts_file, hls_fragment, hls_window, ts_floor, hls_aof_ratio,
|
||||
cleanup, wait_keyframe)) != ERROR_SUCCESS
|
||||
) {
|
||||
srs_error("m3u8 muxer update config failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = muxer->update_config(req, entry_prefix, path, m3u8_file, ts_file, hls_fragment,
|
||||
hls_window, ts_floor, hls_aof_ratio, cleanup, wait_keyframe)) != srs_success ) {
|
||||
return srs_error_wrap(err, "hls: update config");
|
||||
}
|
||||
|
||||
if ((ret = muxer->segment_open()) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer open segment failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = muxer->segment_open()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: segment open");
|
||||
}
|
||||
srs_trace("hls: win=%.2f, frag=%.2f, prefix=%s, path=%s, m3u8=%s, ts=%s, aof=%.2f, floor=%d, clean=%d, waitk=%d, dispose=%d",
|
||||
hls_window, hls_fragment, entry_prefix.c_str(), path.c_str(), m3u8_file.c_str(),
|
||||
ts_file.c_str(), hls_aof_ratio, ts_floor, cleanup, wait_keyframe, hls_dispose);
|
||||
hls_window, hls_fragment, entry_prefix.c_str(), path.c_str(), m3u8_file.c_str(),
|
||||
ts_file.c_str(), hls_aof_ratio, ts_floor, cleanup, wait_keyframe, hls_dispose);
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsController::on_unpublish()
|
||||
srs_error_t SrsHlsController::on_unpublish()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((ret = muxer->flush_audio(tsmc)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer flush audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = muxer->flush_audio(tsmc)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: flush audio");
|
||||
}
|
||||
|
||||
if ((ret = muxer->segment_close()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = muxer->segment_close()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: segment close");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsController::on_sequence_header()
|
||||
srs_error_t SrsHlsController::on_sequence_header()
|
||||
{
|
||||
// TODO: support discontinuity for the same stream
|
||||
// currently we reap and insert discontinity when encoder republish,
|
||||
|
@ -853,13 +841,13 @@ int SrsHlsController::on_sequence_header()
|
|||
return muxer->on_sequence_header();
|
||||
}
|
||||
|
||||
int SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
|
||||
srs_error_t SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// write audio to cache.
|
||||
if ((ret = tsmc->cache_audio(frame, pts)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = tsmc->cache_audio(frame, pts)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: cache audio");
|
||||
}
|
||||
|
||||
// reap when current source is pure audio.
|
||||
|
@ -871,9 +859,8 @@ int SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
|
|||
// we use absolutely overflow of segment to make jwplayer/ffplay happy
|
||||
// @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184
|
||||
if (tsmc->audio && muxer->is_segment_absolutely_overflow()) {
|
||||
srs_info("hls: absolute audio reap segment.");
|
||||
if ((ret = reap_segment()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = reap_segment()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: reap segment");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -881,7 +868,7 @@ int SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
|
|||
// TODO: FIXME: Check whether it's necessary.
|
||||
if (muxer->pure_audio() && tsmc->audio) {
|
||||
if (pts - tsmc->audio->start_pts < SRS_CONSTS_HLS_PURE_AUDIO_AGGREGATE) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -889,20 +876,20 @@ int SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
|
|||
// it's ok for the hls overload, or maybe cause the audio corrupt,
|
||||
// which introduced by aggregate the audios to a big one.
|
||||
// @see https://github.com/ossrs/srs/issues/512
|
||||
if ((ret = muxer->flush_audio(tsmc)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = muxer->flush_audio(tsmc)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: flush audio");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsController::write_video(SrsVideoFrame* frame, int64_t dts)
|
||||
srs_error_t SrsHlsController::write_video(SrsVideoFrame* frame, int64_t dts)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// write video to cache.
|
||||
if ((ret = tsmc->cache_video(frame, dts)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = tsmc->cache_video(frame, dts)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: cache video");
|
||||
}
|
||||
|
||||
// when segment overflow, reap if possible.
|
||||
|
@ -912,55 +899,50 @@ int SrsHlsController::write_video(SrsVideoFrame* frame, int64_t dts)
|
|||
// b. always reap when not wait keyframe.
|
||||
if (!muxer->wait_keyframe() || frame->frame_type == SrsVideoAvcFrameTypeKeyFrame) {
|
||||
// reap the segment, which will also flush the video.
|
||||
if ((ret = reap_segment()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = reap_segment()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: reap segment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// flush video when got one
|
||||
if ((ret = muxer->flush_video(tsmc)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer flush video failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = muxer->flush_video(tsmc)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: flush video");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHlsController::reap_segment()
|
||||
srs_error_t SrsHlsController::reap_segment()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// TODO: flush audio before or after segment?
|
||||
// TODO: fresh segment begin with audio or video?
|
||||
|
||||
// close current ts.
|
||||
if ((ret = muxer->segment_close()) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer close segment failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = muxer->segment_close()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: segment close");
|
||||
}
|
||||
|
||||
// open new ts.
|
||||
if ((ret = muxer->segment_open()) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer open segment failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = muxer->segment_open()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: segment open");
|
||||
}
|
||||
|
||||
// segment open, flush video first.
|
||||
if ((ret = muxer->flush_video(tsmc)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer flush video failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = muxer->flush_video(tsmc)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: flush video");
|
||||
}
|
||||
|
||||
// segment open, flush the audio.
|
||||
// @see: ngx_rtmp_hls_open_fragment
|
||||
/* start fragment with audio to make iPhone happy */
|
||||
if ((ret = muxer->flush_audio(tsmc)) != ERROR_SUCCESS) {
|
||||
srs_error("m3u8 muxer flush audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = muxer->flush_audio(tsmc)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: flush audio");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsHls::SrsHls()
|
||||
|
@ -1050,24 +1032,24 @@ srs_error_t SrsHls::initialize(SrsOriginHub* h, SrsRequest* r)
|
|||
return err;
|
||||
}
|
||||
|
||||
int SrsHls::on_publish()
|
||||
srs_error_t SrsHls::on_publish()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// update the hls time, for hls_dispose.
|
||||
last_update_time = srs_get_system_time_ms();
|
||||
|
||||
// support multiple publish.
|
||||
if (enabled) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!_srs_config->get_hls_enabled(req->vhost)) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((ret = controller->on_publish(req)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
if ((err = controller->on_publish(req)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: on publish");
|
||||
}
|
||||
|
||||
// if enabled, open the muxer.
|
||||
|
@ -1076,31 +1058,32 @@ int SrsHls::on_publish()
|
|||
// ok, the hls can be dispose, or need to be dispose.
|
||||
disposable = true;
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
void SrsHls::on_unpublish()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// support multiple unpublish.
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = controller->on_unpublish()) != ERROR_SUCCESS) {
|
||||
srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret);
|
||||
if ((err = controller->on_unpublish()) != srs_success) {
|
||||
srs_warn("hls: ignore unpublish failed %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format)
|
||||
srs_error_t SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!enabled) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// update the hls time, for hls_dispose.
|
||||
|
@ -1113,7 +1096,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format)
|
|||
srs_assert(format->acodec);
|
||||
SrsAudioCodecId acodec = format->acodec->id;
|
||||
if (acodec != SrsAudioCodecIdAAC && acodec != SrsAudioCodecIdMP3) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// ignore sequence header
|
||||
|
@ -1123,9 +1106,8 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format)
|
|||
}
|
||||
|
||||
// TODO: FIXME: config the jitter of HLS.
|
||||
if ((ret = jitter->correct(audio, SrsRtmpJitterAlgorithmOFF)) != ERROR_SUCCESS) {
|
||||
srs_error("rtmp jitter correct audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = jitter->correct(audio, SrsRtmpJitterAlgorithmOFF)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: jitter");
|
||||
}
|
||||
|
||||
// Reset the aac samples counter when DTS jitter.
|
||||
|
@ -1145,20 +1127,19 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format)
|
|||
int64_t dts = 90000 * aac_samples / srs_flv_srates[format->acodec->sound_rate];
|
||||
aac_samples += nb_samples_per_frame;
|
||||
|
||||
if ((ret = controller->write_audio(format->audio, dts)) != ERROR_SUCCESS) {
|
||||
srs_error("hls cache write audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = controller->write_audio(format->audio, dts)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: write audio");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format)
|
||||
srs_error_t SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!enabled) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// update the hls time, for hls_dispose.
|
||||
|
@ -1171,12 +1152,12 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format)
|
|||
// @see https://github.com/ossrs/srs/issues/288#issuecomment-69863909
|
||||
srs_assert(format->video);
|
||||
if (format->video->frame_type == SrsVideoAvcFrameTypeVideoInfoFrame) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_assert(format->vcodec);
|
||||
if (format->vcodec->id != SrsVideoCodecIdAVC) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// ignore sequence header
|
||||
|
@ -1185,21 +1166,19 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format)
|
|||
}
|
||||
|
||||
// TODO: FIXME: config the jitter of HLS.
|
||||
if ((ret = jitter->correct(video, SrsRtmpJitterAlgorithmOFF)) != ERROR_SUCCESS) {
|
||||
srs_error("rtmp jitter correct video failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = jitter->correct(video, SrsRtmpJitterAlgorithmOFF)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: jitter");
|
||||
}
|
||||
|
||||
int64_t dts = video->timestamp * 90;
|
||||
if ((ret = controller->write_video(format->video, dts)) != ERROR_SUCCESS) {
|
||||
srs_error("hls cache write video failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = controller->write_video(format->video, dts)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: write video");
|
||||
}
|
||||
|
||||
// pithy print message.
|
||||
hls_show_mux_log();
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
void SrsHls::hls_show_mux_log()
|
||||
|
|
|
@ -179,15 +179,15 @@ public:
|
|||
/**
|
||||
* when publish, update the config for muxer.
|
||||
*/
|
||||
virtual int update_config(SrsRequest* r, std::string entry_prefix,
|
||||
virtual srs_error_t update_config(SrsRequest* r, std::string entry_prefix,
|
||||
std::string path, std::string m3u8_file, std::string ts_file,
|
||||
double fragment, double window, bool ts_floor, double aof_ratio,
|
||||
bool cleanup, bool wait_keyframe);
|
||||
/**
|
||||
* open a new segment(a new ts file)
|
||||
*/
|
||||
virtual int segment_open();
|
||||
virtual int on_sequence_header();
|
||||
virtual srs_error_t segment_open();
|
||||
virtual srs_error_t on_sequence_header();
|
||||
/**
|
||||
* whether segment overflow,
|
||||
* that is whether the current segment duration>=(the segment in config)
|
||||
|
@ -208,15 +208,15 @@ public:
|
|||
* whether current hls muxer is pure audio mode.
|
||||
*/
|
||||
virtual bool pure_audio();
|
||||
virtual int flush_audio(SrsTsMessageCache* cache);
|
||||
virtual int flush_video(SrsTsMessageCache* cache);
|
||||
virtual srs_error_t flush_audio(SrsTsMessageCache* cache);
|
||||
virtual srs_error_t flush_video(SrsTsMessageCache* cache);
|
||||
/**
|
||||
* Close segment(ts).
|
||||
*/
|
||||
virtual int segment_close();
|
||||
virtual srs_error_t segment_close();
|
||||
private:
|
||||
virtual int refresh_m3u8();
|
||||
virtual int _refresh_m3u8(std::string m3u8_file);
|
||||
virtual srs_error_t refresh_m3u8();
|
||||
virtual srs_error_t _refresh_m3u8(std::string m3u8_file);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -258,23 +258,23 @@ public:
|
|||
/**
|
||||
* when publish or unpublish stream.
|
||||
*/
|
||||
virtual int on_publish(SrsRequest* req);
|
||||
virtual int on_unpublish();
|
||||
virtual srs_error_t on_publish(SrsRequest* req);
|
||||
virtual srs_error_t on_unpublish();
|
||||
/**
|
||||
* when get sequence header,
|
||||
* must write a #EXT-X-DISCONTINUITY to m3u8.
|
||||
* @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt
|
||||
* @see: 3.4.11. EXT-X-DISCONTINUITY
|
||||
*/
|
||||
virtual int on_sequence_header();
|
||||
virtual srs_error_t on_sequence_header();
|
||||
/**
|
||||
* write audio to cache, if need to flush, flush to muxer.
|
||||
*/
|
||||
virtual int write_audio(SrsAudioFrame* frame, int64_t pts);
|
||||
virtual srs_error_t write_audio(SrsAudioFrame* frame, int64_t pts);
|
||||
/**
|
||||
* write video to muxer.
|
||||
*/
|
||||
virtual int write_video(SrsVideoFrame* frame, int64_t dts);
|
||||
virtual srs_error_t write_video(SrsVideoFrame* frame, int64_t dts);
|
||||
private:
|
||||
/**
|
||||
* reopen the muxer for a new hls segment,
|
||||
|
@ -282,7 +282,7 @@ private:
|
|||
* then write the key frame to the new segment.
|
||||
* so, user must reap_segment then flush_video to hls muxer.
|
||||
*/
|
||||
virtual int reap_segment();
|
||||
virtual srs_error_t reap_segment();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -324,7 +324,7 @@ public:
|
|||
* for the muxer object not destroyed.
|
||||
* @param fetch_sequence_header whether fetch sequence from source.
|
||||
*/
|
||||
virtual int on_publish();
|
||||
virtual srs_error_t on_publish();
|
||||
/**
|
||||
* the unpublish event, only close the muxer, donot destroy the
|
||||
* muxer, for when we continue to publish, the m3u8 will continue.
|
||||
|
@ -334,14 +334,14 @@ public:
|
|||
* mux the audio packets to ts.
|
||||
* @param shared_audio, directly ptr, copy it if need to save it.
|
||||
*/
|
||||
virtual int on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format);
|
||||
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format);
|
||||
/**
|
||||
* mux the video packets to ts.
|
||||
* @param shared_video, directly ptr, copy it if need to save it.
|
||||
* @param is_sps_pps whether the video is h.264 sps/pps.
|
||||
*/
|
||||
// TODO: FIXME: Remove param is_sps_pps.
|
||||
virtual int on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
|
||||
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
|
||||
private:
|
||||
virtual void hls_show_mux_log();
|
||||
};
|
||||
|
|
|
@ -203,8 +203,12 @@ SrsTsStreamEncoder::~SrsTsStreamEncoder()
|
|||
int SrsTsStreamEncoder::initialize(SrsFileWriter* w, SrsBufferCache* /*c*/)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((ret = enc->initialize(w)) != ERROR_SUCCESS) {
|
||||
if ((err = enc->initialize(w)) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -213,12 +217,20 @@ int SrsTsStreamEncoder::initialize(SrsFileWriter* w, SrsBufferCache* /*c*/)
|
|||
|
||||
int SrsTsStreamEncoder::write_audio(int64_t timestamp, char* data, int size)
|
||||
{
|
||||
return enc->write_audio(timestamp, data, size);
|
||||
srs_error_t err = enc->write_audio(timestamp, data, size);
|
||||
// TODO: FIXME: Use error
|
||||
int ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsTsStreamEncoder::write_video(int64_t timestamp, char* data, int size)
|
||||
{
|
||||
return enc->write_video(timestamp, data, size);
|
||||
srs_error_t err = enc->write_video(timestamp, data, size);
|
||||
// TODO: FIXME: Use error
|
||||
int ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsTsStreamEncoder::write_metadata(int64_t /*timestamp*/, char* /*data*/, int /*size*/)
|
||||
|
|
|
@ -460,12 +460,12 @@ int SrsKafkaProducer::send(int key, SrsJsonObject* obj)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsKafkaProducer::on_client(int key, SrsListenerType type, string ip)
|
||||
srs_error_t SrsKafkaProducer::on_client(int key, SrsListenerType type, string ip)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!enabled) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
|
@ -477,12 +477,12 @@ int SrsKafkaProducer::on_client(int key, SrsListenerType type, string ip)
|
|||
return worker->execute(new SrsKafkaMessage(this, key, obj));
|
||||
}
|
||||
|
||||
int SrsKafkaProducer::on_close(int key)
|
||||
srs_error_t SrsKafkaProducer::on_close(int key)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!enabled) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
|
|
|
@ -141,12 +141,12 @@ public:
|
|||
* @param type the type of client.
|
||||
* @param ip the peer ip of client.
|
||||
*/
|
||||
virtual int on_client(int key, SrsListenerType type, std::string ip) = 0;
|
||||
virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip) = 0;
|
||||
/**
|
||||
* when client close or disconnect for error.
|
||||
* @param key the partition map key, the client id or hash(ip).
|
||||
*/
|
||||
virtual int on_close(int key) = 0;
|
||||
virtual srs_error_t on_close(int key) = 0;
|
||||
};
|
||||
|
||||
// @global kafka event producer.
|
||||
|
@ -192,8 +192,8 @@ public:
|
|||
virtual int send(int key, SrsJsonObject* obj);
|
||||
// interface ISrsKafkaCluster
|
||||
public:
|
||||
virtual int on_client(int key, SrsListenerType type, std::string ip);
|
||||
virtual int on_close(int key);
|
||||
virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip);
|
||||
virtual srs_error_t on_close(int key);
|
||||
// interface ISrsReusableThreadHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
|
|
|
@ -178,6 +178,7 @@ srs_error_t SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb
|
|||
int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// collect nMB data to parse in a time.
|
||||
// TODO: FIXME: comment the following for release.
|
||||
|
@ -237,7 +238,10 @@ int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
|
|||
}
|
||||
|
||||
// process each ts packet
|
||||
if ((ret = context->decode(stream, this)) != ERROR_SUCCESS) {
|
||||
if ((err = context->decode(stream, this)) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_warn("mpegts: ignore parse ts packet failed. ret=%d", ret);
|
||||
continue;
|
||||
}
|
||||
|
@ -253,9 +257,10 @@ int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
|
||||
srs_error_t SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
pprint->elapse();
|
||||
|
||||
|
@ -311,36 +316,35 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
|
|||
|
||||
// when not audio/video, or not adts/annexb format, donot support.
|
||||
if (msg->stream_number() != 0) {
|
||||
ret = ERROR_STREAM_CASTER_TS_ES;
|
||||
srs_error("mpegts: unsupported stream format, sid=%#x(%s-%d). ret=%d",
|
||||
msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number(), ret);
|
||||
return ret;
|
||||
return srs_error_new(ERROR_STREAM_CASTER_TS_ES, "ts: unsupported stream format, sid=%#x(%s-%d)",
|
||||
msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number());
|
||||
}
|
||||
|
||||
// check supported codec
|
||||
if (msg->channel->stream != SrsTsStreamVideoH264 && msg->channel->stream != SrsTsStreamAudioAAC) {
|
||||
ret = ERROR_STREAM_CASTER_TS_CODEC;
|
||||
srs_error("mpegts: unsupported stream codec=%d. ret=%d", msg->channel->stream, ret);
|
||||
return ret;
|
||||
return srs_error_new(ERROR_STREAM_CASTER_TS_CODEC, "ts: unsupported stream codec=%d", msg->channel->stream);
|
||||
}
|
||||
|
||||
// parse the stream.
|
||||
SrsBuffer avs;
|
||||
if ((ret = avs.initialize(msg->payload->bytes(), msg->payload->length())) != ERROR_SUCCESS) {
|
||||
srs_error("mpegts: initialize av stream failed. ret=%d", ret);
|
||||
return ret;
|
||||
return srs_error_new(ret, "ts: init av stream");
|
||||
}
|
||||
|
||||
// publish audio or video.
|
||||
if (msg->channel->stream == SrsTsStreamVideoH264) {
|
||||
return on_ts_video(msg, &avs);
|
||||
if ((ret = on_ts_video(msg, &avs)) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "ts: consume video");
|
||||
}
|
||||
}
|
||||
if (msg->channel->stream == SrsTsStreamAudioAAC) {
|
||||
return on_ts_audio(msg, &avs);
|
||||
if ((ret = on_ts_audio(msg, &avs)) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "ts: consume audio");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: FIXME: implements it.
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsBuffer* avs)
|
||||
|
|
|
@ -106,7 +106,7 @@ private:
|
|||
virtual int on_udp_bytes(std::string host, int port, char* buf, int nb_buf);
|
||||
// interface ISrsTsHandler
|
||||
public:
|
||||
virtual int on_ts_message(SrsTsMessage* msg);
|
||||
virtual srs_error_t on_ts_message(SrsTsMessage* msg);
|
||||
private:
|
||||
virtual int on_ts_video(SrsTsMessage* msg, SrsBuffer* avs);
|
||||
virtual int write_h264_sps_pps(uint32_t dts, uint32_t pts);
|
||||
|
|
|
@ -166,8 +166,8 @@ srs_error_t SrsRtmpConn::do_cycle()
|
|||
|
||||
// notify kafka cluster.
|
||||
#ifdef SRS_AUTO_KAFKA
|
||||
if ((ret = _srs_kafka->on_client(srs_id(), SrsListenerRtmpStream, ip)) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "kafka on client");
|
||||
if ((err = _srs_kafka->on_client(srs_id(), SrsListenerRtmpStream, ip)) != srs_success) {
|
||||
return srs_error_wrap(err, "kafka on client");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1411,14 +1411,13 @@ int SrsRtmpConn::do_token_traverse_auth(SrsRtmpClient* client)
|
|||
|
||||
srs_error_t SrsRtmpConn::on_disconnect()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
http_hooks_on_close();
|
||||
|
||||
#ifdef SRS_AUTO_KAFKA
|
||||
if ((ret = _srs_kafka->on_close(srs_id())) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "kafka on close");
|
||||
if ((err = _srs_kafka->on_close(srs_id())) != srs_success) {
|
||||
return srs_error_wrap(err, "kafka on close");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -85,15 +85,15 @@ SrsRtmpJitter::~SrsRtmpJitter()
|
|||
{
|
||||
}
|
||||
|
||||
int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag)
|
||||
srs_error_t SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// for performance issue
|
||||
if (ag != SrsRtmpJitterAlgorithmFULL) {
|
||||
// all jitter correct features is disabled, ignore.
|
||||
if (ag == SrsRtmpJitterAlgorithmOFF) {
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// start at zero, but donot ensure monotonically increasing.
|
||||
|
@ -103,18 +103,18 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag)
|
|||
last_pkt_correct_time = msg->timestamp;
|
||||
}
|
||||
msg->timestamp -= last_pkt_correct_time;
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// other algorithm, ignore.
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
// full jitter algorithm, do jitter correct.
|
||||
// set to 0 for metadata.
|
||||
if (!msg->is_av()) {
|
||||
msg->timestamp = 0;
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,7 +148,7 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag)
|
|||
msg->timestamp = last_pkt_correct_time;
|
||||
last_pkt_time = time;
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsRtmpJitter::get_time()
|
||||
|
@ -470,12 +470,16 @@ int SrsConsumer::get_time()
|
|||
int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsSharedPtrMessage* msg = shared_msg->copy();
|
||||
|
||||
if (!atc) {
|
||||
if ((ret = jitter->correct(msg, ag)) != ERROR_SUCCESS) {
|
||||
if ((err = jitter->correct(msg, ag)) != srs_success) {
|
||||
srs_freep(msg);
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -963,6 +967,7 @@ int SrsOriginHub::on_meta_data(SrsSharedPtrMessage* shared_metadata, SrsOnMetaDa
|
|||
int SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsSharedPtrMessage* msg = shared_audio;
|
||||
|
||||
|
@ -993,7 +998,11 @@ int SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio)
|
|||
srs_flv_srates[c->sound_rate]);
|
||||
}
|
||||
|
||||
if ((ret = hls->on_audio(msg, format)) != ERROR_SUCCESS) {
|
||||
if ((err = hls->on_audio(msg, format)) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
|
||||
// apply the error strategy for hls.
|
||||
// @see https://github.com/ossrs/srs/issues/264
|
||||
std::string hls_error_strategy = _srs_config->get_hls_on_error(req->vhost);
|
||||
|
@ -1063,6 +1072,7 @@ int SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio)
|
|||
int SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_header)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsSharedPtrMessage* msg = shared_video;
|
||||
|
||||
|
@ -1095,7 +1105,11 @@ int SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_h
|
|||
c->video_data_rate / 1000, c->frame_rate, c->duration);
|
||||
}
|
||||
|
||||
if ((ret = hls->on_video(msg, format)) != ERROR_SUCCESS) {
|
||||
if ((err = hls->on_video(msg, format)) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
|
||||
// apply the error strategy for hls.
|
||||
// @see https://github.com/ossrs/srs/issues/264
|
||||
std::string hls_error_strategy = _srs_config->get_hls_on_error(req->vhost);
|
||||
|
@ -1165,6 +1179,7 @@ int SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_h
|
|||
int SrsOriginHub::on_publish()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// create forwarders
|
||||
if ((ret = create_forwarders()) != ERROR_SUCCESS) {
|
||||
|
@ -1180,7 +1195,10 @@ int SrsOriginHub::on_publish()
|
|||
}
|
||||
#endif
|
||||
|
||||
if ((ret = hls->on_publish()) != ERROR_SUCCESS) {
|
||||
if ((err = hls->on_publish()) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("start hls failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1384,8 +1402,8 @@ srs_error_t SrsOriginHub::on_reload_vhost_hls(string vhost)
|
|||
return err;
|
||||
}
|
||||
|
||||
if ((ret = hls->on_publish()) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "hls publish failed");
|
||||
if ((err = hls->on_publish()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls publish failed");
|
||||
}
|
||||
srs_trace("vhost %s hls reload success", vhost.c_str());
|
||||
|
||||
|
@ -1399,8 +1417,8 @@ srs_error_t SrsOriginHub::on_reload_vhost_hls(string vhost)
|
|||
if ((ret = format->on_video(cache_sh_video)) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "format on_video");
|
||||
}
|
||||
if ((ret = hls->on_video(cache_sh_video, format)) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "hls on_video");
|
||||
if ((err = hls->on_video(cache_sh_video, format)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls on_video");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1409,8 +1427,8 @@ srs_error_t SrsOriginHub::on_reload_vhost_hls(string vhost)
|
|||
if ((ret = format->on_audio(cache_sh_audio)) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "format on_audio");
|
||||
}
|
||||
if ((ret = hls->on_audio(cache_sh_audio, format)) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "hls on_audio");
|
||||
if ((err = hls->on_audio(cache_sh_audio, format)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls on_audio");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
* detect the time jitter and correct it.
|
||||
* @param ag the algorithm to use for time jitter.
|
||||
*/
|
||||
virtual int correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag);
|
||||
virtual srs_error_t correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag);
|
||||
/**
|
||||
* get current client time, the last packet time.
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -283,7 +283,7 @@ public:
|
|||
/**
|
||||
* dumps all bytes in stream to ts message.
|
||||
*/
|
||||
virtual int dump(SrsBuffer* stream, int* pnb_bytes);
|
||||
virtual srs_error_t dump(SrsBuffer* stream, int* pnb_bytes);
|
||||
/**
|
||||
* whether ts message is completed to reap.
|
||||
* @param payload_unit_start_indicator whether new ts message start.
|
||||
|
@ -334,7 +334,7 @@ public:
|
|||
* @param msg the ts msg, user should never free it.
|
||||
* @return an int error code.
|
||||
*/
|
||||
virtual int on_ts_message(SrsTsMessage* msg) = 0;
|
||||
virtual srs_error_t on_ts_message(SrsTsMessage* msg) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -392,7 +392,7 @@ public:
|
|||
* @param handler the ts message handler to process the msg.
|
||||
* @remark we will consume all bytes in stream.
|
||||
*/
|
||||
virtual int decode(SrsBuffer* stream, ISrsTsHandler* handler);
|
||||
virtual srs_error_t decode(SrsBuffer* stream, ISrsTsHandler* handler);
|
||||
// encode methods
|
||||
public:
|
||||
/**
|
||||
|
@ -401,8 +401,8 @@ public:
|
|||
* @param vc the video codec, write the PAT/PMT table when changed.
|
||||
* @param ac the audio codec, write the PAT/PMT table when changed.
|
||||
*/
|
||||
virtual int encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac);
|
||||
// drm methods
|
||||
virtual srs_error_t encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac);
|
||||
// drm methods
|
||||
public:
|
||||
/**
|
||||
* set sync byte of ts segment.
|
||||
|
@ -410,8 +410,8 @@ public:
|
|||
*/
|
||||
virtual void set_sync_byte(int8_t sb);
|
||||
private:
|
||||
virtual int encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as);
|
||||
virtual int encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio);
|
||||
virtual srs_error_t encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as);
|
||||
virtual srs_error_t encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -516,10 +516,10 @@ public:
|
|||
SrsTsPacket(SrsTsContext* c);
|
||||
virtual ~SrsTsPacket();
|
||||
public:
|
||||
virtual int decode(SrsBuffer* stream, SrsTsMessage** ppmsg);
|
||||
virtual srs_error_t decode(SrsBuffer* stream, SrsTsMessage** ppmsg);
|
||||
public:
|
||||
virtual int size();
|
||||
virtual int encode(SrsBuffer* stream);
|
||||
virtual srs_error_t encode(SrsBuffer* stream);
|
||||
virtual void padding(int nb_stuffings);
|
||||
public:
|
||||
static SrsTsPacket* create_pat(SrsTsContext* context, int16_t pmt_number, int16_t pmt_pid);
|
||||
|
@ -832,10 +832,10 @@ public:
|
|||
SrsTsAdaptationField(SrsTsPacket* pkt);
|
||||
virtual ~SrsTsAdaptationField();
|
||||
public:
|
||||
virtual int decode(SrsBuffer* stream);
|
||||
virtual srs_error_t decode(SrsBuffer* stream);
|
||||
public:
|
||||
virtual int size();
|
||||
virtual int encode(SrsBuffer* stream);
|
||||
virtual srs_error_t encode(SrsBuffer* stream);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -880,10 +880,10 @@ public:
|
|||
SrsTsPayload(SrsTsPacket* p);
|
||||
virtual ~SrsTsPayload();
|
||||
public:
|
||||
virtual int decode(SrsBuffer* stream, SrsTsMessage** ppmsg) = 0;
|
||||
virtual srs_error_t decode(SrsBuffer* stream, SrsTsMessage** ppmsg) = 0;
|
||||
public:
|
||||
virtual int size() = 0;
|
||||
virtual int encode(SrsBuffer* stream) = 0;
|
||||
virtual srs_error_t encode(SrsBuffer* stream) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1222,13 +1222,13 @@ public:
|
|||
SrsTsPayloadPES(SrsTsPacket* p);
|
||||
virtual ~SrsTsPayloadPES();
|
||||
public:
|
||||
virtual int decode(SrsBuffer* stream, SrsTsMessage** ppmsg);
|
||||
virtual srs_error_t decode(SrsBuffer* stream, SrsTsMessage** ppmsg);
|
||||
public:
|
||||
virtual int size();
|
||||
virtual int encode(SrsBuffer* stream);
|
||||
virtual srs_error_t encode(SrsBuffer* stream);
|
||||
private:
|
||||
virtual int decode_33bits_dts_pts(SrsBuffer* stream, int64_t* pv);
|
||||
virtual int encode_33bits_dts_pts(SrsBuffer* stream, uint8_t fb, int64_t v);
|
||||
virtual srs_error_t decode_33bits_dts_pts(SrsBuffer* stream, int64_t* pv);
|
||||
virtual srs_error_t encode_33bits_dts_pts(SrsBuffer* stream, uint8_t fb, int64_t v);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1289,14 +1289,14 @@ public:
|
|||
SrsTsPayloadPSI(SrsTsPacket* p);
|
||||
virtual ~SrsTsPayloadPSI();
|
||||
public:
|
||||
virtual int decode(SrsBuffer* stream, SrsTsMessage** ppmsg);
|
||||
virtual srs_error_t decode(SrsBuffer* stream, SrsTsMessage** ppmsg);
|
||||
public:
|
||||
virtual int size();
|
||||
virtual int encode(SrsBuffer* stream);
|
||||
virtual srs_error_t encode(SrsBuffer* stream);
|
||||
protected:
|
||||
virtual int psi_size() = 0;
|
||||
virtual int psi_encode(SrsBuffer* stream) = 0;
|
||||
virtual int psi_decode(SrsBuffer* stream) = 0;
|
||||
virtual srs_error_t psi_encode(SrsBuffer* stream) = 0;
|
||||
virtual srs_error_t psi_decode(SrsBuffer* stream) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1329,10 +1329,10 @@ public:
|
|||
SrsTsPayloadPATProgram(int16_t n = 0, int16_t p = 0);
|
||||
virtual ~SrsTsPayloadPATProgram();
|
||||
public:
|
||||
virtual int decode(SrsBuffer* stream);
|
||||
virtual srs_error_t decode(SrsBuffer* stream);
|
||||
public:
|
||||
virtual int size();
|
||||
virtual int encode(SrsBuffer* stream);
|
||||
virtual srs_error_t encode(SrsBuffer* stream);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1393,10 +1393,10 @@ public:
|
|||
SrsTsPayloadPAT(SrsTsPacket* p);
|
||||
virtual ~SrsTsPayloadPAT();
|
||||
protected:
|
||||
virtual int psi_decode(SrsBuffer* stream);
|
||||
virtual srs_error_t psi_decode(SrsBuffer* stream);
|
||||
protected:
|
||||
virtual int psi_size();
|
||||
virtual int psi_encode(SrsBuffer* stream);
|
||||
virtual srs_error_t psi_encode(SrsBuffer* stream);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1433,10 +1433,10 @@ public:
|
|||
SrsTsPayloadPMTESInfo(SrsTsStream st = SrsTsStreamReserved, int16_t epid = 0);
|
||||
virtual ~SrsTsPayloadPMTESInfo();
|
||||
public:
|
||||
virtual int decode(SrsBuffer* stream);
|
||||
virtual srs_error_t decode(SrsBuffer* stream);
|
||||
public:
|
||||
virtual int size();
|
||||
virtual int encode(SrsBuffer* stream);
|
||||
virtual srs_error_t encode(SrsBuffer* stream);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1523,10 +1523,10 @@ public:
|
|||
SrsTsPayloadPMT(SrsTsPacket* p);
|
||||
virtual ~SrsTsPayloadPMT();
|
||||
protected:
|
||||
virtual int psi_decode(SrsBuffer* stream);
|
||||
virtual srs_error_t psi_decode(SrsBuffer* stream);
|
||||
protected:
|
||||
virtual int psi_size();
|
||||
virtual int psi_encode(SrsBuffer* stream);
|
||||
virtual srs_error_t psi_encode(SrsBuffer* stream);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1551,15 +1551,15 @@ public:
|
|||
* open the writer, donot write the PSI of ts.
|
||||
* @param p a string indicates the path of ts file to mux to.
|
||||
*/
|
||||
virtual int open(std::string p);
|
||||
virtual srs_error_t open(std::string p);
|
||||
/**
|
||||
* write an audio frame to ts,
|
||||
*/
|
||||
virtual int write_audio(SrsTsMessage* audio);
|
||||
virtual srs_error_t write_audio(SrsTsMessage* audio);
|
||||
/**
|
||||
* write a video frame to ts,
|
||||
*/
|
||||
virtual int write_video(SrsTsMessage* video);
|
||||
virtual srs_error_t write_video(SrsTsMessage* video);
|
||||
/**
|
||||
* close the writer.
|
||||
*/
|
||||
|
@ -1588,15 +1588,15 @@ public:
|
|||
/**
|
||||
* write audio to cache
|
||||
*/
|
||||
virtual int cache_audio(SrsAudioFrame* frame, int64_t dts);
|
||||
virtual srs_error_t cache_audio(SrsAudioFrame* frame, int64_t dts);
|
||||
/**
|
||||
* write video to muxer.
|
||||
*/
|
||||
virtual int cache_video(SrsVideoFrame* frame, int64_t dts);
|
||||
virtual srs_error_t cache_video(SrsVideoFrame* frame, int64_t dts);
|
||||
private:
|
||||
virtual int do_cache_mp3(SrsAudioFrame* frame);
|
||||
virtual int do_cache_aac(SrsAudioFrame* frame);
|
||||
virtual int do_cache_avc(SrsVideoFrame* frame);
|
||||
virtual srs_error_t do_cache_mp3(SrsAudioFrame* frame);
|
||||
virtual srs_error_t do_cache_aac(SrsAudioFrame* frame);
|
||||
virtual srs_error_t do_cache_avc(SrsVideoFrame* frame);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1619,17 +1619,17 @@ public:
|
|||
* initialize the underlayer file stream.
|
||||
* @param fw the writer to use for ts encoder, user must free it.
|
||||
*/
|
||||
virtual int initialize(SrsFileWriter* fw);
|
||||
virtual srs_error_t initialize(SrsFileWriter* fw);
|
||||
public:
|
||||
/**
|
||||
* write audio/video packet.
|
||||
* @remark assert data is not NULL.
|
||||
*/
|
||||
virtual int write_audio(int64_t timestamp, char* data, int size);
|
||||
virtual int write_video(int64_t timestamp, char* data, int size);
|
||||
virtual srs_error_t write_audio(int64_t timestamp, char* data, int size);
|
||||
virtual srs_error_t write_video(int64_t timestamp, char* data, int size);
|
||||
private:
|
||||
virtual int flush_audio();
|
||||
virtual int flush_video();
|
||||
virtual srs_error_t flush_audio();
|
||||
virtual srs_error_t flush_video();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -509,17 +509,15 @@ int srs_do_create_dir_recursively(string dir)
|
|||
return true;
|
||||
}
|
||||
|
||||
int srs_create_dir_recursively(string dir)
|
||||
srs_error_t srs_create_dir_recursively(string dir)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
ret = srs_do_create_dir_recursively(dir);
|
||||
int ret = srs_do_create_dir_recursively(dir);
|
||||
|
||||
if (ret == ERROR_SYSTEM_DIR_EXISTS) {
|
||||
return ERROR_SUCCESS;
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return srs_error_new(ret, "create dir %s", dir.c_str());
|
||||
}
|
||||
|
||||
bool srs_path_exists(std::string path)
|
||||
|
|
|
@ -102,7 +102,7 @@ extern std::vector<std::string> srs_string_split(std::string str, std::vector<st
|
|||
extern bool srs_bytes_equals(void* pa, void* pb, int size);
|
||||
|
||||
// create dir recursively
|
||||
extern int srs_create_dir_recursively(std::string dir);
|
||||
extern srs_error_t srs_create_dir_recursively(std::string dir);
|
||||
|
||||
// whether path exists.
|
||||
extern bool srs_path_exists(std::string path);
|
||||
|
|
|
@ -285,6 +285,7 @@ int SrsIngestHlsInput::parse(ISrsTsHandler* ts, ISrsAacHandler* aac)
|
|||
int SrsIngestHlsInput::parseTs(ISrsTsHandler* handler, char* body, int nb_body)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// use stream to parse ts packet.
|
||||
int nb_packet = (int)nb_body / SRS_TS_PACKET_SIZE;
|
||||
|
@ -295,7 +296,10 @@ int SrsIngestHlsInput::parseTs(ISrsTsHandler* handler, char* body, int nb_body)
|
|||
}
|
||||
|
||||
// process each ts packet
|
||||
if ((ret = context->decode(stream, handler)) != ERROR_SUCCESS) {
|
||||
if ((err = context->decode(stream, handler)) != srs_success) {
|
||||
// TODO: FIXME: Use error
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("mpegts: ignore parse ts packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -654,7 +658,7 @@ public:
|
|||
virtual ~SrsIngestHlsOutput();
|
||||
// interface ISrsTsHandler
|
||||
public:
|
||||
virtual int on_ts_message(SrsTsMessage* msg);
|
||||
virtual srs_error_t on_ts_message(SrsTsMessage* msg);
|
||||
// interface IAacHandler
|
||||
public:
|
||||
virtual int on_aac_frame(char* frame, int frame_size, double duration);
|
||||
|
@ -713,9 +717,10 @@ SrsIngestHlsOutput::~SrsIngestHlsOutput()
|
|||
queue.clear();
|
||||
}
|
||||
|
||||
int SrsIngestHlsOutput::on_ts_message(SrsTsMessage* msg)
|
||||
srs_error_t SrsIngestHlsOutput::on_ts_message(SrsTsMessage* msg)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// about the bytes of msg, specified by elementary stream which indicates by PES_packet_data_byte and stream_id
|
||||
// for example, when SrsTsStream of SrsTsChannel indicates stream_type is SrsTsStreamVideoMpeg4 and SrsTsStreamAudioMpeg4,
|
||||
|
@ -767,26 +772,22 @@ int SrsIngestHlsOutput::on_ts_message(SrsTsMessage* msg)
|
|||
|
||||
// when not audio/video, or not adts/annexb format, donot support.
|
||||
if (msg->stream_number() != 0) {
|
||||
ret = ERROR_STREAM_CASTER_TS_ES;
|
||||
srs_error("mpegts: unsupported stream format, sid=%#x(%s-%d). ret=%d",
|
||||
msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number(), ret);
|
||||
return ret;
|
||||
return srs_error_new(ERROR_STREAM_CASTER_TS_ES, "ts: unsupported stream format, sid=%#x(%s-%d)",
|
||||
msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number());
|
||||
}
|
||||
|
||||
// check supported codec
|
||||
if (msg->channel->stream != SrsTsStreamVideoH264 && msg->channel->stream != SrsTsStreamAudioAAC) {
|
||||
ret = ERROR_STREAM_CASTER_TS_CODEC;
|
||||
srs_error("mpegts: unsupported stream codec=%d. ret=%d", msg->channel->stream, ret);
|
||||
return ret;
|
||||
return srs_error_new(ERROR_STREAM_CASTER_TS_CODEC, "ts: unsupported stream codec=%d", msg->channel->stream);
|
||||
}
|
||||
|
||||
// we must use queue to cache the msg, then parse it if possible.
|
||||
queue.insert(std::make_pair(msg->dts, msg->detach()));
|
||||
if ((ret = parse_message_queue()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
return srs_error_new(ret, "ts: parse message");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsIngestHlsOutput::on_aac_frame(char* frame, int frame_size, double duration)
|
||||
|
|
Loading…
Reference in a new issue