Skip to content

Commit

Permalink
For #299, increase dash segment size for avsync issue. 3.0.89
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Dec 29, 2019
1 parent d11a7b2 commit 8a28a11
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 67 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 6 additions & 6 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down
11 changes: 11 additions & 0 deletions trunk/src/app/srs_app_dash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
133 changes: 77 additions & 56 deletions trunk/src/kernel/srs_kernel_mp4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand All @@ -6275,6 +6288,7 @@ SrsMp4M2tsSegmentEncoder::SrsMp4M2tsSegmentEncoder()
buffer = new SrsBuffer();
sequence_number = 0;
decode_basetime = 0;
styp_bytes = 0;
mdat_bytes = 0;
}

Expand All @@ -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");
}
}
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion trunk/src/kernel/srs_kernel_mp4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ class SrsMp4SegmentIndexBox : public SrsMp4Box
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:
Expand Down Expand Up @@ -2115,6 +2115,7 @@ class SrsMp4M2tsSegmentEncoder
private:
uint32_t nb_audios;
uint32_t nb_videos;
uint32_t styp_bytes;
uint64_t mdat_bytes;
SrsMp4SampleManager* samples;
public:
Expand Down

0 comments on commit 8a28a11

Please sign in to comment.