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:
parent
2f52d0aefa
commit
aa85ce024b
2 changed files with 59 additions and 15 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue