mirror of
https://github.com/ossrs/srs.git
synced 2025-02-12 11:21:52 +00:00
For #299, increase dash segment size for avsync issue. 3.0.89
This commit is contained in:
parent
d11a7b2e00
commit
8a28a11648
7 changed files with 101 additions and 67 deletions
|
@ -146,6 +146,7 @@ For previous versions, please read:
|
|||
|
||||
## V3 changes
|
||||
|
||||
* v3.0, 2019-12-29, For [#299][bug #299], increase dash segment size for avsync issue. 3.0.89
|
||||
* v3.0, 2019-12-27, For [#299][bug #299], fix some bugs in dash, it works now. 3.0.88
|
||||
* v3.0, 2019-12-27, For [#1544][bug #1544], fix memory leaking for complex error. 3.0.87
|
||||
* v3.0, 2019-12-27, Add links for flv.js, hls.js and dash.js.
|
||||
|
|
|
@ -965,14 +965,14 @@ vhost dash.srs.com {
|
|||
# Default: off
|
||||
enabled on;
|
||||
# The duration of segment in seconds.
|
||||
# Default: 3
|
||||
dash_fragment 3;
|
||||
# The period to update the MPD in seconds.
|
||||
# Default: 30
|
||||
dash_update_period 30;
|
||||
dash_fragment 30;
|
||||
# The period to update the MPD in seconds.
|
||||
# Default: 150
|
||||
dash_update_period 150;
|
||||
# The depth of timeshift buffer in seconds.
|
||||
# Default: 60
|
||||
dash_timeshift 60;
|
||||
# Default: 300
|
||||
dash_timeshift 300;
|
||||
# The base/home dir/path for dash.
|
||||
# All init and segment files will write under this dir.
|
||||
dash_path ./objs/nginx/html;
|
||||
|
|
|
@ -5810,7 +5810,7 @@ bool SrsConfig::get_dash_enabled(string vhost)
|
|||
|
||||
srs_utime_t SrsConfig::get_dash_fragment(string vhost)
|
||||
{
|
||||
static int DEFAULT = 3 * SRS_UTIME_SECONDS;
|
||||
static int DEFAULT = 30 * SRS_UTIME_SECONDS;
|
||||
|
||||
SrsConfDirective* conf = get_dash(vhost);
|
||||
if (!conf) {
|
||||
|
@ -5827,7 +5827,7 @@ srs_utime_t SrsConfig::get_dash_fragment(string vhost)
|
|||
|
||||
srs_utime_t SrsConfig::get_dash_update_period(string vhost)
|
||||
{
|
||||
static srs_utime_t DEFAULT = 30 * SRS_UTIME_SECONDS;
|
||||
static srs_utime_t DEFAULT = 150 * SRS_UTIME_SECONDS;
|
||||
|
||||
SrsConfDirective* conf = get_dash(vhost);
|
||||
if (!conf) {
|
||||
|
@ -5844,7 +5844,7 @@ srs_utime_t SrsConfig::get_dash_update_period(string vhost)
|
|||
|
||||
srs_utime_t SrsConfig::get_dash_timeshift(string vhost)
|
||||
{
|
||||
static srs_utime_t DEFAULT = 60 * SRS_UTIME_SECONDS;
|
||||
static srs_utime_t DEFAULT = 300 * SRS_UTIME_SECONDS;
|
||||
|
||||
SrsConfDirective* conf = get_dash(vhost);
|
||||
if (!conf) {
|
||||
|
|
|
@ -363,7 +363,18 @@ void SrsDashController::on_unpublish()
|
|||
{
|
||||
mpd->on_unpublish();
|
||||
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((err = vcurrent->reap(video_dts)) != srs_success) {
|
||||
srs_warn("reap video err %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
srs_freep(vcurrent);
|
||||
|
||||
if ((err = acurrent->reap(audio_dts)) != srs_success) {
|
||||
srs_warn("reap audio err %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
srs_freep(acurrent);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
// The version config.
|
||||
#define VERSION_MAJOR 3
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 88
|
||||
#define VERSION_REVISION 89
|
||||
|
||||
// The macros generated by configure script.
|
||||
#include <srs_auto_headers.hpp>
|
||||
|
|
|
@ -41,6 +41,27 @@ using namespace std;
|
|||
|
||||
#define SRS_MP4_BUF_SIZE 4096
|
||||
|
||||
srs_error_t srs_mp4_write_box(ISrsWriter* writer, ISrsCodec* box)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int nb_data = box->nb_bytes();
|
||||
std::vector<char> data(nb_data);
|
||||
|
||||
SrsBuffer* buffer = new SrsBuffer(&data[0], nb_data);
|
||||
SrsAutoFree(SrsBuffer, buffer);
|
||||
|
||||
if ((err = box->encode(buffer)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode box");
|
||||
}
|
||||
|
||||
if ((err = writer->write(&data[0], nb_data, NULL)) != srs_success) {
|
||||
return srs_error_wrap(err, "write box");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
stringstream& srs_padding(stringstream& ss, SrsMp4DumpContext dc, int tab = 4)
|
||||
{
|
||||
for (int i = 0; i < (int)dc.level; i++) {
|
||||
|
@ -4587,7 +4608,7 @@ SrsMp4SegmentIndexBox::~SrsMp4SegmentIndexBox()
|
|||
|
||||
int SrsMp4SegmentIndexBox::nb_header()
|
||||
{
|
||||
return SrsMp4Box::nb_header() + 4+4+4 + (version? 4:8) + 4+4 + 12*entries.size();
|
||||
return SrsMp4Box::nb_header() + 4+4+4 + (!version? 8:16) + 4 + 12*entries.size();
|
||||
}
|
||||
|
||||
srs_error_t SrsMp4SegmentIndexBox::encode_header(SrsBuffer* buf)
|
||||
|
@ -6041,18 +6062,24 @@ srs_error_t SrsMp4M2tsInitEncoder::write(SrsFormat* format, bool video, int tid)
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
// Write ftyp box.
|
||||
SrsMp4FileTypeBox* ftyp = new SrsMp4FileTypeBox();
|
||||
SrsAutoFree(SrsMp4FileTypeBox, ftyp);
|
||||
if (true) {
|
||||
SrsMp4FileTypeBox* ftyp = new SrsMp4FileTypeBox();
|
||||
SrsAutoFree(SrsMp4FileTypeBox, ftyp);
|
||||
|
||||
ftyp->major_brand = SrsMp4BoxBrandISO5;
|
||||
ftyp->minor_version = 512;
|
||||
ftyp->set_compatible_brands(SrsMp4BoxBrandISO6, SrsMp4BoxBrandMP41);
|
||||
|
||||
if ((err = srs_mp4_write_box(writer, ftyp)) != srs_success) {
|
||||
return srs_error_wrap(err, "write ftyp");
|
||||
}
|
||||
}
|
||||
|
||||
// Write moov.
|
||||
SrsMp4MovieBox* moov = new SrsMp4MovieBox();
|
||||
SrsAutoFree(SrsMp4MovieBox, moov);
|
||||
if (true) {
|
||||
SrsMp4MovieBox* moov = new SrsMp4MovieBox();
|
||||
SrsAutoFree(SrsMp4MovieBox, moov);
|
||||
|
||||
SrsMp4MovieHeaderBox* mvhd = new SrsMp4MovieHeaderBox();
|
||||
moov->set_mvhd(mvhd);
|
||||
|
||||
|
@ -6244,24 +6271,10 @@ srs_error_t SrsMp4M2tsInitEncoder::write(SrsFormat* format, bool video, int tid)
|
|||
trex->track_ID = tid;
|
||||
trex->default_sample_description_index = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int nb_data = ftyp->nb_bytes() + moov->nb_bytes();
|
||||
uint8_t* data = new uint8_t[nb_data];
|
||||
SrsAutoFreeA(uint8_t, data);
|
||||
|
||||
SrsBuffer* buffer = new SrsBuffer((char*)data, nb_data);
|
||||
SrsAutoFree(SrsBuffer, buffer);
|
||||
|
||||
if ((err = ftyp->encode(buffer)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode ftyp");
|
||||
}
|
||||
if ((err = moov->encode(buffer)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode moov");
|
||||
}
|
||||
|
||||
if ((err = writer->write(data, nb_data, NULL)) != srs_success) {
|
||||
return srs_error_wrap(err, "write ftyp and moov");
|
||||
|
||||
if ((err = srs_mp4_write_box(writer, moov)) != srs_success) {
|
||||
return srs_error_wrap(err, "write moov");
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -6275,6 +6288,7 @@ SrsMp4M2tsSegmentEncoder::SrsMp4M2tsSegmentEncoder()
|
|||
buffer = new SrsBuffer();
|
||||
sequence_number = 0;
|
||||
decode_basetime = 0;
|
||||
styp_bytes = 0;
|
||||
mdat_bytes = 0;
|
||||
}
|
||||
|
||||
|
@ -6301,19 +6315,11 @@ srs_error_t SrsMp4M2tsSegmentEncoder::initialize(ISrsWriter* w, uint32_t sequenc
|
|||
styp->major_brand = SrsMp4BoxBrandMSDH;
|
||||
styp->minor_version = 0;
|
||||
styp->set_compatible_brands(SrsMp4BoxBrandMSDH, SrsMp4BoxBrandMSIX);
|
||||
|
||||
int nb_data = styp->nb_bytes();
|
||||
std::vector<char> data(nb_data);
|
||||
|
||||
SrsBuffer* buffer = new SrsBuffer(&data[0], nb_data);
|
||||
SrsAutoFree(SrsBuffer, buffer);
|
||||
|
||||
if ((err = styp->encode(buffer)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode styp");
|
||||
}
|
||||
|
||||
// TODO: FIXME: Ensure write ok.
|
||||
if ((err = writer->write(&data[0], nb_data, NULL)) != srs_success) {
|
||||
|
||||
// Used for sidx to calcalute the referenced size.
|
||||
styp_bytes = styp->nb_bytes();
|
||||
|
||||
if ((err = srs_mp4_write_box(writer, styp)) != srs_success) {
|
||||
return srs_error_wrap(err, "write styp");
|
||||
}
|
||||
}
|
||||
|
@ -6365,16 +6371,36 @@ srs_error_t SrsMp4M2tsSegmentEncoder::flush(uint64_t& dts)
|
|||
if (!nb_audios && !nb_videos) {
|
||||
return srs_error_new(ERROR_MP4_ILLEGAL_MOOF, "Missing audio and video track");
|
||||
}
|
||||
|
||||
|
||||
// Although the sidx is not required to start play DASH, but it's required for AV sync.
|
||||
SrsMp4SegmentIndexBox* sidx = new SrsMp4SegmentIndexBox();
|
||||
SrsAutoFree(SrsMp4SegmentIndexBox, sidx);
|
||||
if (true) {
|
||||
sidx->version = 1;
|
||||
sidx->reference_id = 1;
|
||||
sidx->timescale = 1000;
|
||||
sidx->earliest_presentation_time = uint64_t(decode_basetime / sidx->timescale);
|
||||
|
||||
uint64_t duration = 0;
|
||||
if (samples && !samples->samples.empty()) {
|
||||
SrsMp4Sample* first = samples->samples[0];
|
||||
SrsMp4Sample* last = samples->samples[samples->samples.size() - 1];
|
||||
duration = srs_max(0, last->dts - first->dts);
|
||||
}
|
||||
|
||||
SrsMp4SegmentIndexEntry entry;
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
entry.subsegment_duration = duration;
|
||||
entry.starts_with_SAP = 1;
|
||||
sidx->entries.push_back(entry);
|
||||
}
|
||||
|
||||
// Create a mdat box.
|
||||
// its payload will be writen by samples,
|
||||
// and we will update its header(size) when flush.
|
||||
SrsMp4MediaDataBox* mdat = new SrsMp4MediaDataBox();
|
||||
SrsAutoFree(SrsMp4MediaDataBox, mdat);
|
||||
|
||||
// Although the sidx is not required to start play DASH, but it's required for AV sync.
|
||||
// TODO: FIXME: Insert a sidx box.
|
||||
|
||||
// Write moof.
|
||||
if (true) {
|
||||
SrsMp4MovieFragmentBox* moof = new SrsMp4MovieFragmentBox();
|
||||
|
@ -6407,30 +6433,25 @@ srs_error_t SrsMp4M2tsSegmentEncoder::flush(uint64_t& dts)
|
|||
return srs_error_wrap(err, "write samples");
|
||||
}
|
||||
|
||||
int nb_data = moof->nb_bytes();
|
||||
// @remark Remember the data_offset of turn is size(moof)+header(mdat), not including styp or sidx.
|
||||
trun->data_offset = (int32_t)(nb_data + mdat->sz_header());
|
||||
|
||||
uint8_t* data = new uint8_t[nb_data];
|
||||
SrsAutoFreeA(uint8_t, data);
|
||||
|
||||
SrsBuffer* buffer = new SrsBuffer((char*)data, nb_data);
|
||||
SrsAutoFree(SrsBuffer, buffer);
|
||||
|
||||
if ((err = moof->encode(buffer)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode moof");
|
||||
int moof_bytes = moof->nb_bytes();
|
||||
trun->data_offset = (int32_t)(moof_bytes + mdat->sz_header());
|
||||
mdat->nb_data = (int)mdat_bytes;
|
||||
|
||||
// Update the size of sidx.
|
||||
SrsMp4SegmentIndexEntry* entry = &sidx->entries[0];
|
||||
entry->referenced_size = moof_bytes + mdat->nb_bytes();
|
||||
if ((err = srs_mp4_write_box(writer, sidx)) != srs_success) {
|
||||
return srs_error_wrap(err, "write sidx");
|
||||
}
|
||||
|
||||
// TODO: FIXME: Ensure all bytes are writen.
|
||||
if ((err = writer->write(data, nb_data, NULL)) != srs_success) {
|
||||
|
||||
if ((err = srs_mp4_write_box(writer, moof)) != srs_success) {
|
||||
return srs_error_wrap(err, "write moof");
|
||||
}
|
||||
}
|
||||
|
||||
// Write mdat.
|
||||
if (true) {
|
||||
mdat->nb_data = (int)mdat_bytes;
|
||||
|
||||
int nb_data = mdat->sz_header();
|
||||
uint8_t* data = new uint8_t[nb_data];
|
||||
SrsAutoFreeA(uint8_t, data);
|
||||
|
|
|
@ -1835,7 +1835,7 @@ public:
|
|||
uint32_t reference_id;
|
||||
uint32_t timescale;
|
||||
uint64_t earliest_presentation_time;
|
||||
uint32_t first_offset;
|
||||
uint64_t first_offset;
|
||||
// TODO: FIXME: Should double check buffer.
|
||||
std::vector<SrsMp4SegmentIndexEntry> entries;
|
||||
public:
|
||||
|
@ -2115,6 +2115,7 @@ private:
|
|||
private:
|
||||
uint32_t nb_audios;
|
||||
uint32_t nb_videos;
|
||||
uint32_t styp_bytes;
|
||||
uint64_t mdat_bytes;
|
||||
SrsMp4SampleManager* samples;
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue