For #299, increase dash segment size for avsync issue. 3.0.89

pull/1568/head
winlin 5 years ago
parent d11a7b2e00
commit 8a28a11648

@ -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;
}
@ -6302,18 +6316,10 @@ srs_error_t SrsMp4M2tsSegmentEncoder::initialize(ISrsWriter* w, uint32_t sequenc
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");
}
// Used for sidx to calcalute the referenced size.
styp_bytes = styp->nb_bytes();
// TODO: FIXME: Ensure write ok.
if ((err = writer->write(&data[0], nb_data, NULL)) != srs_success) {
if ((err = srs_mp4_write_box(writer, styp)) != srs_success) {
return srs_error_wrap(err, "write styp");
}
}
@ -6366,15 +6372,35 @@ srs_error_t SrsMp4M2tsSegmentEncoder::flush(uint64_t& dts)
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);
int moof_bytes = moof->nb_bytes();
trun->data_offset = (int32_t)(moof_bytes + mdat->sz_header());
mdat->nb_data = (int)mdat_bytes;
if ((err = moof->encode(buffer)) != srs_success) {
return srs_error_wrap(err, "encode moof");
// 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…
Cancel
Save