[MP4] Truncate segment references in 'sidx' if necessary
The reference count in 'sidx' box is a uint16 field, which allows at most 0xFFFF entries, i.e. at most 0xFFFF subsegments, which is roughly 18 hours for one second segments. Do not fail packaging when it happens. Instead, generate a warning and truncate the number of references to 0xFFFF instead. Note that the actual number of mp4 fragments in the mp4 file can still be more than 0xFFFF. The stream will not play to the end in DASH, but it will play successfully in HLS. Workarounds #862. Change-Id: Ib3930418d1528df1f9ea64cda0d0ebaa78d26abb
This commit is contained in:
parent
c6b01f90ae
commit
516430bde1
|
@ -5,6 +5,7 @@
|
||||||
#include "packager/media/formats/mp4/box_definitions.h"
|
#include "packager/media/formats/mp4/box_definitions.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include "packager/base/logging.h"
|
#include "packager/base/logging.h"
|
||||||
|
@ -2747,10 +2748,22 @@ bool SegmentIndex::ReadWriteInternal(BoxBuffer* buffer) {
|
||||||
buffer->ReadWriteUInt64NBytes(&earliest_presentation_time, num_bytes) &&
|
buffer->ReadWriteUInt64NBytes(&earliest_presentation_time, num_bytes) &&
|
||||||
buffer->ReadWriteUInt64NBytes(&first_offset, num_bytes));
|
buffer->ReadWriteUInt64NBytes(&first_offset, num_bytes));
|
||||||
|
|
||||||
uint16_t reference_count = static_cast<uint16_t>(references.size());
|
uint16_t reference_count;
|
||||||
|
if (references.size() <= std::numeric_limits<uint16_t>::max()) {
|
||||||
|
reference_count = static_cast<uint16_t>(references.size());
|
||||||
|
} else {
|
||||||
|
reference_count = std::numeric_limits<uint16_t>::max();
|
||||||
|
LOG(WARNING) << "Seeing " << references.size()
|
||||||
|
<< " subsegment references, but at most " << reference_count
|
||||||
|
<< " references can be stored in 'sidx' box."
|
||||||
|
<< " The extra references are truncated.";
|
||||||
|
LOG(WARNING) << "The stream will not play to the end in DASH.";
|
||||||
|
LOG(WARNING) << "A possible workaround is to increase segment duration.";
|
||||||
|
}
|
||||||
RCHECK(buffer->IgnoreBytes(2) && // reserved.
|
RCHECK(buffer->IgnoreBytes(2) && // reserved.
|
||||||
buffer->ReadWriteUInt16(&reference_count));
|
buffer->ReadWriteUInt16(&reference_count));
|
||||||
references.resize(reference_count);
|
if (buffer->Reading())
|
||||||
|
references.resize(reference_count);
|
||||||
|
|
||||||
uint32_t reference_type_size;
|
uint32_t reference_type_size;
|
||||||
uint32_t sap;
|
uint32_t sap;
|
||||||
|
@ -2782,7 +2795,10 @@ size_t SegmentIndex::ComputeSizeInternal() {
|
||||||
version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
|
version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
|
||||||
return HeaderSize() + sizeof(reference_id) + sizeof(timescale) +
|
return HeaderSize() + sizeof(reference_id) + sizeof(timescale) +
|
||||||
sizeof(uint32_t) * (1 + version) * 2 + 2 * sizeof(uint16_t) +
|
sizeof(uint32_t) * (1 + version) * 2 + 2 * sizeof(uint16_t) +
|
||||||
3 * sizeof(uint32_t) * references.size();
|
3 * sizeof(uint32_t) *
|
||||||
|
std::min(
|
||||||
|
references.size(),
|
||||||
|
static_cast<size_t>(std::numeric_limits<uint16_t>::max()));
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaData::MediaData() = default;
|
MediaData::MediaData() = default;
|
||||||
|
|
Loading…
Reference in New Issue