1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

For #821, support parse dash video segment

This commit is contained in:
winlin 2017-06-03 23:12:54 +08:00
parent 8cc3ab2fa2
commit baed1cc043
2 changed files with 725 additions and 1 deletions

View file

@ -409,6 +409,13 @@ int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox)
case SrsMp4BoxTypeUDTA: box = new SrsMp4UserDataBox(); break;
case SrsMp4BoxTypeMVEX: box = new SrsMp4MovieExtendsBox(); break;
case SrsMp4BoxTypeTREX: box = new SrsMp4TrackExtendsBox(); break;
case SrsMp4BoxTypeSTYP: box = new SrsMp4SegmentTypeBox(); break;
case SrsMp4BoxTypeMOOF: box = new SrsMp4MovieFragmentBox(); break;
case SrsMp4BoxTypeMFHD: box = new SrsMp4MovieFragmentHeaderBox(); break;
case SrsMp4BoxTypeTRAF: box = new SrsMp4TrackFragmentBox(); break;
case SrsMp4BoxTypeTFHD: box = new SrsMp4TrackFragmentHeaderBox(); break;
case SrsMp4BoxTypeTFDT: box = new SrsMp4TrackFragmentDecodeTimeBox(); break;
case SrsMp4BoxTypeTRUN: box = new SrsMp4TrackFragmentRunBox(); break;
// Skip some unknown boxes.
case SrsMp4BoxTypeFREE: case SrsMp4BoxTypeSKIP: case SrsMp4BoxTypePASP:
box = new SrsMp4FreeSpaceBox(type); break;
@ -810,6 +817,478 @@ stringstream& SrsMp4FileTypeBox::dumps_detail(stringstream& ss, SrsMp4DumpContex
return ss;
}
SrsMp4SegmentTypeBox::SrsMp4SegmentTypeBox()
{
type = SrsMp4BoxTypeSTYP;
}
SrsMp4SegmentTypeBox::~SrsMp4SegmentTypeBox()
{
}
SrsMp4MovieFragmentBox::SrsMp4MovieFragmentBox()
{
type = SrsMp4BoxTypeMOOF;
}
SrsMp4MovieFragmentBox::~SrsMp4MovieFragmentBox()
{
}
SrsMp4MovieFragmentHeaderBox::SrsMp4MovieFragmentHeaderBox()
{
type = SrsMp4BoxTypeMFHD;
sequence_number = 0;
}
SrsMp4MovieFragmentHeaderBox::~SrsMp4MovieFragmentHeaderBox()
{
}
int SrsMp4MovieFragmentHeaderBox::nb_header()
{
return SrsMp4FullBox::nb_header() + 4;
}
int SrsMp4MovieFragmentHeaderBox::encode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
buf->write_4bytes(sequence_number);
return ret;
}
int SrsMp4MovieFragmentHeaderBox::decode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
sequence_number = buf->read_4bytes();
return ret;
}
stringstream& SrsMp4MovieFragmentHeaderBox::dumps_detail(stringstream& ss, SrsMp4DumpContext dc)
{
SrsMp4FullBox::dumps_detail(ss, dc);
ss << ", sequence=" << sequence_number;
return ss;
}
SrsMp4TrackFragmentBox::SrsMp4TrackFragmentBox()
{
type = SrsMp4BoxTypeTRAF;
}
SrsMp4TrackFragmentBox::~SrsMp4TrackFragmentBox()
{
}
SrsMp4TrackFragmentHeaderBox::SrsMp4TrackFragmentHeaderBox()
{
type = SrsMp4BoxTypeTFHD;
flags = 0;
base_data_offset = 0;
track_id = sample_description_index = 0;
default_sample_duration = default_sample_size = 0;
default_sample_flags = 0;
}
SrsMp4TrackFragmentHeaderBox::~SrsMp4TrackFragmentHeaderBox()
{
}
int SrsMp4TrackFragmentHeaderBox::nb_header()
{
int size = SrsMp4FullBox::nb_header() + 4;
if ((flags&SrsMp4TfhdFlagsBaseDataOffset) == SrsMp4TfhdFlagsBaseDataOffset) {
size += 8;
}
if ((flags&SrsMp4TfhdFlagsSampleDescriptionIndex) == SrsMp4TfhdFlagsSampleDescriptionIndex) {
size += 4;
}
if ((flags&SrsMp4TfhdFlagsDefaultSampleDuration) == SrsMp4TfhdFlagsDefaultSampleDuration) {
size += 4;
}
if ((flags&SrsMp4TfhdFlagsDefautlSampleSize) == SrsMp4TfhdFlagsDefautlSampleSize) {
size += 4;
}
if ((flags&SrsMp4TfhdFlagsDefaultSampleFlags) == SrsMp4TfhdFlagsDefaultSampleFlags) {
size += 4;
}
return size;
}
int SrsMp4TrackFragmentHeaderBox::encode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
buf->write_4bytes(track_id);
if ((flags&SrsMp4TfhdFlagsBaseDataOffset) == SrsMp4TfhdFlagsBaseDataOffset) {
buf->write_8bytes(base_data_offset);
}
if ((flags&SrsMp4TfhdFlagsSampleDescriptionIndex) == SrsMp4TfhdFlagsSampleDescriptionIndex) {
buf->write_4bytes(sample_description_index);
}
if ((flags&SrsMp4TfhdFlagsDefaultSampleDuration) == SrsMp4TfhdFlagsDefaultSampleDuration) {
buf->write_4bytes(default_sample_duration);
}
if ((flags&SrsMp4TfhdFlagsDefautlSampleSize) == SrsMp4TfhdFlagsDefautlSampleSize) {
buf->write_4bytes(default_sample_size);
}
if ((flags&SrsMp4TfhdFlagsDefaultSampleFlags) == SrsMp4TfhdFlagsDefaultSampleFlags) {
buf->write_4bytes(default_sample_flags);
}
return ret;
}
int SrsMp4TrackFragmentHeaderBox::decode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
track_id = buf->read_4bytes();
if ((flags&SrsMp4TfhdFlagsBaseDataOffset) == SrsMp4TfhdFlagsBaseDataOffset) {
base_data_offset = buf->read_8bytes();
}
if ((flags&SrsMp4TfhdFlagsSampleDescriptionIndex) == SrsMp4TfhdFlagsSampleDescriptionIndex) {
sample_description_index = buf->read_4bytes();
}
if ((flags&SrsMp4TfhdFlagsDefaultSampleDuration) == SrsMp4TfhdFlagsDefaultSampleDuration) {
default_sample_duration = buf->read_4bytes();
}
if ((flags&SrsMp4TfhdFlagsDefautlSampleSize) == SrsMp4TfhdFlagsDefautlSampleSize) {
default_sample_size = buf->read_4bytes();
}
if ((flags&SrsMp4TfhdFlagsDefaultSampleFlags) == SrsMp4TfhdFlagsDefaultSampleFlags) {
default_sample_flags = buf->read_4bytes();
}
return ret;
}
stringstream& SrsMp4TrackFragmentHeaderBox::dumps_detail(stringstream& ss, SrsMp4DumpContext dc)
{
SrsMp4FullBox::dumps_detail(ss, dc);
ss << ", track=" << track_id;
if ((flags&SrsMp4TfhdFlagsBaseDataOffset) == SrsMp4TfhdFlagsBaseDataOffset) {
ss << ", bdo=" << base_data_offset;
}
if ((flags&SrsMp4TfhdFlagsSampleDescriptionIndex) == SrsMp4TfhdFlagsSampleDescriptionIndex) {
ss << ", sdi=" << sample_description_index;
}
if ((flags&SrsMp4TfhdFlagsDefaultSampleDuration) == SrsMp4TfhdFlagsDefaultSampleDuration) {
ss << ", dsu=" << default_sample_duration;
}
if ((flags&SrsMp4TfhdFlagsDefautlSampleSize) == SrsMp4TfhdFlagsDefautlSampleSize) {
ss << ", dss=" << default_sample_size;
}
if ((flags&SrsMp4TfhdFlagsDefaultSampleFlags) == SrsMp4TfhdFlagsDefaultSampleFlags) {
ss << ", dsf=" << default_sample_flags;
}
return ss;
}
SrsMp4TrackFragmentDecodeTimeBox::SrsMp4TrackFragmentDecodeTimeBox()
{
type = SrsMp4BoxTypeTFDT;
base_media_decode_time = 0;
}
SrsMp4TrackFragmentDecodeTimeBox::~SrsMp4TrackFragmentDecodeTimeBox()
{
}
int SrsMp4TrackFragmentDecodeTimeBox::nb_header()
{
return SrsMp4FullBox::nb_header() + (version? 8:4);
}
int SrsMp4TrackFragmentDecodeTimeBox::encode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
if (version) {
buf->write_8bytes(base_media_decode_time);
} else {
buf->write_4bytes((uint32_t)base_media_decode_time);
}
return ret;
}
int SrsMp4TrackFragmentDecodeTimeBox::decode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
if (version) {
base_media_decode_time = buf->read_8bytes();
} else {
base_media_decode_time = buf->read_4bytes();
}
return ret;
}
stringstream& SrsMp4TrackFragmentDecodeTimeBox::dumps_detail(stringstream& ss, SrsMp4DumpContext dc)
{
SrsMp4FullBox::dumps_detail(ss, dc);
ss << ", bmdt=" << base_media_decode_time;
return ss;
}
SrsMp4TrunEntry::SrsMp4TrunEntry(uint8_t v, uint32_t f)
{
flags = f;
version = v;
sample_duration = sample_size = sample_flags = 0;
sample_composition_time_offset = 0;
}
SrsMp4TrunEntry::~SrsMp4TrunEntry()
{
}
int SrsMp4TrunEntry::nb_header()
{
int size = 0;
if ((flags&SrsMp4TrunFlagsSampleDuration) == SrsMp4TrunFlagsSampleDuration) {
size += 4;
}
if ((flags&SrsMp4TrunFlagsSampleSize) == SrsMp4TrunFlagsSampleSize) {
size += 4;
}
if ((flags&SrsMp4TrunFlagsSampleFlag) == SrsMp4TrunFlagsSampleFlag) {
size += 4;
}
if ((flags&SrsMp4TrunFlagsSampleCtsOffset) == SrsMp4TrunFlagsSampleCtsOffset) {
size += 4;
}
return size;
}
int SrsMp4TrunEntry::encode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((flags&SrsMp4TrunFlagsSampleDuration) == SrsMp4TrunFlagsSampleDuration) {
buf->write_4bytes(sample_duration);
}
if ((flags&SrsMp4TrunFlagsSampleSize) == SrsMp4TrunFlagsSampleSize) {
buf->write_4bytes(sample_size);
}
if ((flags&SrsMp4TrunFlagsSampleFlag) == SrsMp4TrunFlagsSampleFlag) {
buf->write_4bytes(sample_flags);
}
if ((flags&SrsMp4TrunFlagsSampleCtsOffset) == SrsMp4TrunFlagsSampleCtsOffset) {
if (!version) {
uint32_t v = (uint32_t)sample_composition_time_offset;
buf->write_4bytes(v);
} else {
int32_t v = (int32_t)sample_composition_time_offset;
buf->write_4bytes(v);
}
}
return ret;
}
int SrsMp4TrunEntry::decode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((flags&SrsMp4TrunFlagsSampleDuration) == SrsMp4TrunFlagsSampleDuration) {
sample_duration = buf->read_4bytes();
}
if ((flags&SrsMp4TrunFlagsSampleSize) == SrsMp4TrunFlagsSampleSize) {
sample_size = buf->read_4bytes();
}
if ((flags&SrsMp4TrunFlagsSampleFlag) == SrsMp4TrunFlagsSampleFlag) {
sample_flags = buf->read_4bytes();
}
if ((flags&SrsMp4TrunFlagsSampleCtsOffset) == SrsMp4TrunFlagsSampleCtsOffset) {
if (!version) {
uint32_t v = buf->read_4bytes();
sample_composition_time_offset = v;
} else {
int32_t v = buf->read_4bytes();
sample_composition_time_offset = v;
}
}
return ret;
}
stringstream& SrsMp4TrunEntry::dumps_detail(stringstream& ss, SrsMp4DumpContext dc)
{
if ((flags&SrsMp4TrunFlagsSampleDuration) == SrsMp4TrunFlagsSampleDuration) {
ss << "duration=" << sample_duration;
}
if ((flags&SrsMp4TrunFlagsSampleSize) == SrsMp4TrunFlagsSampleSize) {
ss << ", size=" << sample_size;
}
if ((flags&SrsMp4TrunFlagsSampleFlag) == SrsMp4TrunFlagsSampleFlag) {
ss << ", flags=" << sample_flags;
}
if ((flags&SrsMp4TrunFlagsSampleCtsOffset) == SrsMp4TrunFlagsSampleCtsOffset) {
ss << ", cts-offset=" << sample_composition_time_offset;
}
return ss;
}
SrsMp4TrackFragmentRunBox::SrsMp4TrackFragmentRunBox()
{
type = SrsMp4BoxTypeTRUN;
sample_count = first_sample_flags = 0;
data_offset = 0;
}
SrsMp4TrackFragmentRunBox::~SrsMp4TrackFragmentRunBox()
{
vector<SrsMp4TrunEntry*>::iterator it;
for (it = entries.begin(); it != entries.end(); ++it) {
SrsMp4TrunEntry* entry = *it;
srs_freep(entry);
}
}
int SrsMp4TrackFragmentRunBox::nb_header()
{
int size = SrsMp4FullBox::nb_header() + 4;
if ((flags&SrsMp4TrunFlagsDataOffset) == SrsMp4TrunFlagsDataOffset) {
size += 4;
}
if ((flags&SrsMp4TrunFlagsFirstSample) == SrsMp4TrunFlagsFirstSample) {
size += 4;
}
vector<SrsMp4TrunEntry*>::iterator it;
for (it = entries.begin(); it != entries.end(); ++it) {
SrsMp4TrunEntry* entry = *it;
size += entry->nb_header();
}
return size;
}
int SrsMp4TrackFragmentRunBox::encode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
buf->write_4bytes(sample_count);
if ((flags&SrsMp4TrunFlagsDataOffset) == SrsMp4TrunFlagsDataOffset) {
buf->write_4bytes(data_offset);
}
if ((flags&SrsMp4TrunFlagsFirstSample) == SrsMp4TrunFlagsFirstSample) {
buf->write_4bytes(first_sample_flags);
}
vector<SrsMp4TrunEntry*>::iterator it;
for (it = entries.begin(); it != entries.end(); ++it) {
SrsMp4TrunEntry* entry = *it;
if ((ret = entry->encode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
}
return ret;
}
int SrsMp4TrackFragmentRunBox::decode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
sample_count = buf->read_4bytes();
if ((flags&SrsMp4TrunFlagsDataOffset) == SrsMp4TrunFlagsDataOffset) {
data_offset = buf->read_4bytes();
}
if ((flags&SrsMp4TrunFlagsFirstSample) == SrsMp4TrunFlagsFirstSample) {
first_sample_flags = buf->read_4bytes();
}
for (int i = 0; i < sample_count; i++) {
SrsMp4TrunEntry* entry = new SrsMp4TrunEntry(version, flags);
entries.push_back(entry);
if ((ret = entry->decode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
}
return ret;
}
stringstream& SrsMp4TrackFragmentRunBox::dumps_detail(stringstream& ss, SrsMp4DumpContext dc)
{
SrsMp4FullBox::dumps_detail(ss, dc);
ss << ", samples=" << sample_count;
if ((flags&SrsMp4TrunFlagsDataOffset) == SrsMp4TrunFlagsDataOffset) {
ss << ", do" << data_offset;
}
if ((flags&SrsMp4TrunFlagsFirstSample) == SrsMp4TrunFlagsFirstSample) {
ss << ", fsf=" << first_sample_flags;
}
if (sample_count > 0) {
ss << endl;
srs_padding(ss, dc.indent());
srs_dumps_array(entries, ss, dc.indent(), srs_pfn_pdetail, srs_delimiter_newline);
}
return ss;
}
SrsMp4MediaDataBox::SrsMp4MediaDataBox()
{
type = SrsMp4BoxTypeMDAT;