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

DVR: Fix large file mp4 dvr failed. (#2800)

This commit is contained in:
john 2021-12-23 04:41:05 -06:00 committed by GitHub
parent 2f52d0aefa
commit aa85ce024b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 15 deletions

View file

@ -2858,6 +2858,18 @@ void SrsMp4SampleTableBox::set_stco(SrsMp4ChunkOffsetBox* v)
boxes.push_back(v);
}
SrsMp4ChunkLargeOffsetBox* SrsMp4SampleTableBox::co64()
{
SrsMp4Box* box = get(SrsMp4BoxTypeCO64);
return dynamic_cast<SrsMp4ChunkLargeOffsetBox*>(box);
}
void SrsMp4SampleTableBox::set_co64(SrsMp4ChunkLargeOffsetBox* v)
{
remove(SrsMp4BoxTypeCO64);
boxes.push_back(v);
}
SrsMp4SampleSizeBox* SrsMp4SampleTableBox::stsz()
{
SrsMp4Box* box = get(SrsMp4BoxTypeSTSZ);
@ -4840,10 +4852,19 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieBox* moov)
SrsMp4SampleSizeBox* stsz = new SrsMp4SampleSizeBox();
stbl->set_stsz(stsz);
SrsMp4ChunkOffsetBox* stco = new SrsMp4ChunkOffsetBox();
stbl->set_stco(stco);
SrsMp4FullBox* co = NULL;
// When sample offset less than UINT32_MAX, we use stco(support 32bit offset) box to save storage space.
if (samples.empty() || (*samples.rbegin())->offset < UINT32_MAX) {
// stco support 32bit offset.
co = new SrsMp4ChunkOffsetBox();
stbl->set_stco(static_cast<SrsMp4ChunkOffsetBox*>(co));
} else {
// When sample offset bigger than UINT32_MAX, we use co64(support 64bit offset) box to avoid overflow.
co = new SrsMp4ChunkLargeOffsetBox();
stbl->set_co64(static_cast<SrsMp4ChunkLargeOffsetBox*>(co));
}
if ((err = write_track(SrsFrameTypeVideo, stts, stss, ctts, stsc, stsz, stco)) != srs_success) {
if ((err = write_track(SrsFrameTypeVideo, stts, stss, ctts, stsc, stsz, co)) != srs_success) {
return srs_error_wrap(err, "write vide track");
}
}
@ -4864,10 +4885,16 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieBox* moov)
SrsMp4SampleSizeBox* stsz = new SrsMp4SampleSizeBox();
stbl->set_stsz(stsz);
SrsMp4ChunkOffsetBox* stco = new SrsMp4ChunkOffsetBox();
stbl->set_stco(stco);
SrsMp4FullBox* co = NULL;
if (samples.empty() || (*samples.rbegin())->offset < UINT32_MAX) {
co = new SrsMp4ChunkOffsetBox();
stbl->set_stco(static_cast<SrsMp4ChunkOffsetBox*>(co));
} else {
co = new SrsMp4ChunkLargeOffsetBox();
stbl->set_co64(static_cast<SrsMp4ChunkLargeOffsetBox*>(co));
}
if ((err = write_track(SrsFrameTypeAudio, stts, stss, ctts, stsc, stsz, stco)) != srs_success) {
if ((err = write_track(SrsFrameTypeAudio, stts, stss, ctts, stsc, stsz, co)) != srs_success) {
return srs_error_wrap(err, "write soun track");
}
}
@ -4919,7 +4946,7 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieFragmentBox* moof, uint64_t& d
srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track,
SrsMp4DecodingTime2SampleBox* stts, SrsMp4SyncSampleBox* stss, SrsMp4CompositionTime2SampleBox* ctts,
SrsMp4Sample2ChunkBox* stsc, SrsMp4SampleSizeBox* stsz, SrsMp4ChunkOffsetBox* stco)
SrsMp4Sample2ChunkBox* stsc, SrsMp4SampleSizeBox* stsz, SrsMp4FullBox* co)
{
srs_error_t err = srs_success;
@ -4930,7 +4957,7 @@ srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track,
vector<SrsMp4CttsEntry> ctts_entries;
vector<uint32_t> stsz_entries;
vector<uint32_t> stco_entries;
vector<uint64_t> co_entries;
vector<uint32_t> stss_entries;
SrsMp4Sample* previous = NULL;
@ -4942,7 +4969,7 @@ srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track,
}
stsz_entries.push_back(sample->nb_data);
stco_entries.push_back((uint32_t)sample->offset);
co_entries.push_back((uint64_t)sample->offset);
if (sample->frame_type == SrsVideoAvcFrameTypeKeyFrame) {
stss_entries.push_back(sample->index + 1);
@ -5015,11 +5042,22 @@ srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track,
}
}
if (stco && !stco_entries.empty()) {
stco->entry_count = (uint32_t)stco_entries.size();
stco->entries = new uint32_t[stco->entry_count];
for (int i = 0; i < (int)stco->entry_count; i++) {
stco->entries[i] = stco_entries.at(i);
if (!co_entries.empty()) {
SrsMp4ChunkOffsetBox* stco = dynamic_cast<SrsMp4ChunkOffsetBox*>(co);
SrsMp4ChunkLargeOffsetBox* co64 = dynamic_cast<SrsMp4ChunkLargeOffsetBox*>(co);
if (stco) {
stco->entry_count = (uint32_t)co_entries.size();
stco->entries = new uint32_t[stco->entry_count];
for (int i = 0; i < (int)stco->entry_count; i++) {
stco->entries[i] = co_entries.at(i);
}
} else if (co64) {
co64->entry_count = (uint32_t)co_entries.size();
co64->entries = new uint64_t[co64->entry_count];
for (int i = 0; i < (int)co64->entry_count; i++) {
co64->entries[i] = co_entries.at(i);
}
}
}
@ -6162,6 +6200,7 @@ srs_error_t SrsMp4M2tsInitEncoder::write(SrsFormat* format, bool video, int tid)
SrsMp4SampleSizeBox* stsz = new SrsMp4SampleSizeBox();
stbl->set_stsz(stsz);
// TODO: FIXME: need to check using stco or co64?
SrsMp4ChunkOffsetBox* stco = new SrsMp4ChunkOffsetBox();
stbl->set_stco(stco);
@ -6262,6 +6301,7 @@ srs_error_t SrsMp4M2tsInitEncoder::write(SrsFormat* format, bool video, int tid)
SrsMp4SampleSizeBox* stsz = new SrsMp4SampleSizeBox();
stbl->set_stsz(stsz);
// TODO: FIXME: need to check using stco or co64?
SrsMp4ChunkOffsetBox* stco = new SrsMp4ChunkOffsetBox();
stbl->set_stco(stco);

View file

@ -36,6 +36,7 @@ class SrsMp4AvccBox;
class SrsMp4AudioSampleEntry;
class SrsMp4EsdsBox;
class SrsMp4ChunkOffsetBox;
class SrsMp4ChunkLargeOffsetBox;
class SrsMp4SampleSizeBox;
class SrsMp4Sample2ChunkBox;
class SrsMp4DecodingTime2SampleBox;
@ -1188,6 +1189,9 @@ public:
// Get the chunk offset box.
virtual SrsMp4ChunkOffsetBox* stco();
virtual void set_stco(SrsMp4ChunkOffsetBox* v);
// Get the chunk large offset box.
virtual SrsMp4ChunkLargeOffsetBox* co64();
virtual void set_co64(SrsMp4ChunkLargeOffsetBox* v);
// Get the sample size box.
virtual SrsMp4SampleSizeBox* stsz();
virtual void set_stsz(SrsMp4SampleSizeBox* v);
@ -1902,7 +1906,7 @@ public:
private:
virtual srs_error_t write_track(SrsFrameType track,
SrsMp4DecodingTime2SampleBox* stts, SrsMp4SyncSampleBox* stss, SrsMp4CompositionTime2SampleBox* ctts,
SrsMp4Sample2ChunkBox* stsc, SrsMp4SampleSizeBox* stsz, SrsMp4ChunkOffsetBox* stco);
SrsMp4Sample2ChunkBox* stsc, SrsMp4SampleSizeBox* stsz, SrsMp4FullBox* co);
virtual srs_error_t do_load(std::map<uint64_t, SrsMp4Sample*>& tses, SrsMp4MovieBox* moov);
private:
// Load the samples of track from stco, stsz and stsc.