Allow other text sample entries than wvtt
Before this change, the media file will fail to be parsed if it contains non-wvtt text streams. This change allows demuxing of video and audio streams in these media files even though the text stream is ignored. Fixes #74. Change-Id: I7ef108a51125c4965fe48c39efe9638f3a0e4759
This commit is contained in:
parent
bb3918e62b
commit
38c30bd7a1
|
@ -586,7 +586,7 @@ bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
|
||||||
count = audio_entries.size();
|
count = audio_entries.size();
|
||||||
break;
|
break;
|
||||||
case kText:
|
case kText:
|
||||||
count = wvtt_entries.size();
|
count = text_entries.size();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NOTIMPLEMENTED() << "SampleDecryption type " << type
|
NOTIMPLEMENTED() << "SampleDecryption type " << type
|
||||||
|
@ -609,8 +609,8 @@ bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
|
||||||
RCHECK(reader->ReadAllChildren(&audio_entries));
|
RCHECK(reader->ReadAllChildren(&audio_entries));
|
||||||
RCHECK(audio_entries.size() == count);
|
RCHECK(audio_entries.size() == count);
|
||||||
} else if (type == kText) {
|
} else if (type == kText) {
|
||||||
RCHECK(reader->ReadAllChildren(&wvtt_entries));
|
RCHECK(reader->ReadAllChildren(&text_entries));
|
||||||
RCHECK(wvtt_entries.size() == count);
|
RCHECK(text_entries.size() == count);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DCHECK_LT(0u, count);
|
DCHECK_LT(0u, count);
|
||||||
|
@ -622,7 +622,7 @@ bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
|
||||||
RCHECK(buffer->ReadWriteChild(&audio_entries[i]));
|
RCHECK(buffer->ReadWriteChild(&audio_entries[i]));
|
||||||
} else if (type == kText) {
|
} else if (type == kText) {
|
||||||
for (uint32_t i = 0; i < count; ++i)
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
RCHECK(buffer->ReadWriteChild(&wvtt_entries[i]));
|
RCHECK(buffer->ReadWriteChild(&text_entries[i]));
|
||||||
} else {
|
} else {
|
||||||
NOTIMPLEMENTED();
|
NOTIMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
@ -638,6 +638,9 @@ uint32_t SampleDescription::ComputeSizeInternal() {
|
||||||
} else if (type == kAudio) {
|
} else if (type == kAudio) {
|
||||||
for (uint32_t i = 0; i < audio_entries.size(); ++i)
|
for (uint32_t i = 0; i < audio_entries.size(); ++i)
|
||||||
box_size += audio_entries[i].ComputeSize();
|
box_size += audio_entries[i].ComputeSize();
|
||||||
|
} else if (type == kText) {
|
||||||
|
for (uint32_t i = 0; i < text_entries.size(); ++i)
|
||||||
|
box_size += text_entries[i].ComputeSize();
|
||||||
}
|
}
|
||||||
return box_size;
|
return box_size;
|
||||||
}
|
}
|
||||||
|
@ -1589,25 +1592,37 @@ uint32_t WebVTTSourceLabelBox::ComputeSizeInternal() {
|
||||||
return HeaderSize() + source_label.size();
|
return HeaderSize() + source_label.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
WVTTSampleEntry::WVTTSampleEntry() {}
|
TextSampleEntry::TextSampleEntry() : format(FOURCC_NULL) {}
|
||||||
WVTTSampleEntry::~WVTTSampleEntry() {}
|
TextSampleEntry::~TextSampleEntry() {}
|
||||||
|
|
||||||
FourCC WVTTSampleEntry::BoxType() const {
|
FourCC TextSampleEntry::BoxType() const {
|
||||||
return FOURCC_wvtt;
|
if (format == FOURCC_NULL) {
|
||||||
|
LOG(ERROR) << "TextSampleEntry should be parsed according to the "
|
||||||
|
<< "handler type recovered in its Media ancestor.";
|
||||||
|
}
|
||||||
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WVTTSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
|
bool TextSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
|
||||||
// TODO(rkuroiwa): Handle the optional MPEG4BitRateBox.
|
if (buffer->Reading()) {
|
||||||
RCHECK(ReadWriteHeaderInternal(buffer) &&
|
DCHECK(buffer->reader());
|
||||||
buffer->IgnoreBytes(6) && // reserved for SampleEntry.
|
format = buffer->reader()->type();
|
||||||
buffer->ReadWriteUInt16(&data_reference_index) &&
|
} else {
|
||||||
buffer->PrepareChildren() &&
|
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||||
buffer->ReadWriteChild(&config) &&
|
}
|
||||||
buffer->ReadWriteChild(&label));
|
RCHECK(buffer->IgnoreBytes(6) && // reserved for SampleEntry.
|
||||||
|
buffer->ReadWriteUInt16(&data_reference_index));
|
||||||
|
|
||||||
|
if (format == FOURCC_wvtt) {
|
||||||
|
// TODO(rkuroiwa): Handle the optional MPEG4BitRateBox.
|
||||||
|
RCHECK(buffer->PrepareChildren() &&
|
||||||
|
buffer->ReadWriteChild(&config) &&
|
||||||
|
buffer->ReadWriteChild(&label));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WVTTSampleEntry::ComputeSizeInternal() {
|
uint32_t TextSampleEntry::ComputeSizeInternal() {
|
||||||
// 6 for the (anonymous) reserved bytes for SampleEntry class.
|
// 6 for the (anonymous) reserved bytes for SampleEntry class.
|
||||||
return HeaderSize() + 6 + sizeof(data_reference_index) +
|
return HeaderSize() + 6 + sizeof(data_reference_index) +
|
||||||
config.ComputeSize() + label.ComputeSize();
|
config.ComputeSize() + label.ComputeSize();
|
||||||
|
@ -1762,7 +1777,7 @@ bool MediaInformation::ReadWriteInternal(BoxBuffer* buffer) {
|
||||||
RCHECK(buffer->ReadWriteChild(&smhd));
|
RCHECK(buffer->ReadWriteChild(&smhd));
|
||||||
break;
|
break;
|
||||||
case kText:
|
case kText:
|
||||||
RCHECK(buffer->ReadWriteChild(&sthd));
|
RCHECK(buffer->TryReadWriteChild(&sthd));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NOTIMPLEMENTED();
|
NOTIMPLEMENTED();
|
||||||
|
|
|
@ -374,11 +374,16 @@ struct WebVTTSourceLabelBox : Box {
|
||||||
std::string source_label;
|
std::string source_label;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WVTTSampleEntry : Box {
|
struct TextSampleEntry : Box {
|
||||||
DECLARE_BOX_METHODS(WVTTSampleEntry);
|
DECLARE_BOX_METHODS(TextSampleEntry);
|
||||||
|
|
||||||
|
// Specifies fourcc of this sample entry. It needs to be set on write, e.g.
|
||||||
|
// set to 'wvtt' to write WVTTSampleEntry; On read, it is recovered from box
|
||||||
|
// header.
|
||||||
|
FourCC format;
|
||||||
uint16_t data_reference_index;
|
uint16_t data_reference_index;
|
||||||
|
|
||||||
|
// Sub boxes for wvtt text sample entry.
|
||||||
WebVTTConfigurationBox config;
|
WebVTTConfigurationBox config;
|
||||||
WebVTTSourceLabelBox label;
|
WebVTTSourceLabelBox label;
|
||||||
// Optional MPEG4BitRateBox.
|
// Optional MPEG4BitRateBox.
|
||||||
|
@ -392,7 +397,7 @@ struct SampleDescription : FullBox {
|
||||||
// SampleEntry struct, std::vector<SampleEntry> sample_entries.
|
// SampleEntry struct, std::vector<SampleEntry> sample_entries.
|
||||||
std::vector<VideoSampleEntry> video_entries;
|
std::vector<VideoSampleEntry> video_entries;
|
||||||
std::vector<AudioSampleEntry> audio_entries;
|
std::vector<AudioSampleEntry> audio_entries;
|
||||||
std::vector<WVTTSampleEntry> wvtt_entries;
|
std::vector<TextSampleEntry> text_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DecodingTime {
|
struct DecodingTime {
|
||||||
|
|
|
@ -270,8 +270,7 @@ inline bool operator==(const WebVTTSourceLabelBox& lhs,
|
||||||
return lhs.source_label == rhs.source_label;
|
return lhs.source_label == rhs.source_label;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const WVTTSampleEntry& lhs,
|
inline bool operator==(const TextSampleEntry& lhs, const TextSampleEntry& rhs) {
|
||||||
const WVTTSampleEntry& rhs) {
|
|
||||||
return lhs.config == rhs.config && lhs.label == rhs.label;
|
return lhs.config == rhs.config && lhs.label == rhs.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FourCC for VideoSampleEntry is not a constant, e.g. could be avc1, or encv.
|
// FourCC for VideoSampleEntry is fixed, e.g. could be avc1, or encv.
|
||||||
bool ReadBack(VideoSampleEntry* video) {
|
bool ReadBack(VideoSampleEntry* video) {
|
||||||
scoped_ptr<BoxReader> reader(CreateReader());
|
scoped_ptr<BoxReader> reader(CreateReader());
|
||||||
std::vector<VideoSampleEntry> video_entries;
|
std::vector<VideoSampleEntry> video_entries;
|
||||||
|
@ -64,7 +64,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FourCC for AudioSampleEntry is not a constant, e.g. could be mp4a, or enca.
|
// FourCC for AudioSampleEntry is fixed, e.g. could be mp4a, or enca.
|
||||||
bool ReadBack(AudioSampleEntry* audio) {
|
bool ReadBack(AudioSampleEntry* audio) {
|
||||||
scoped_ptr<BoxReader> reader(CreateReader());
|
scoped_ptr<BoxReader> reader(CreateReader());
|
||||||
std::vector<AudioSampleEntry> audio_entries;
|
std::vector<AudioSampleEntry> audio_entries;
|
||||||
|
@ -74,6 +74,16 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FourCC for TextSampleEntry is fixed, e.g. could be text, or wvtt.
|
||||||
|
bool ReadBack(TextSampleEntry* text) {
|
||||||
|
scoped_ptr<BoxReader> reader(CreateReader());
|
||||||
|
std::vector<TextSampleEntry> text_entries;
|
||||||
|
RCHECK(reader->ReadAllChildren(&text_entries));
|
||||||
|
RCHECK(text_entries.size() == 1);
|
||||||
|
*text = text_entries[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// SampleDescription cannot parse on its own. Its type parameter should
|
// SampleDescription cannot parse on its own. Its type parameter should
|
||||||
// be preset before scanning the box.
|
// be preset before scanning the box.
|
||||||
bool ReadBack(SampleDescription* stsd) {
|
bool ReadBack(SampleDescription* stsd) {
|
||||||
|
@ -429,12 +439,13 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
||||||
vlab->source_label = "another_label";
|
vlab->source_label = "another_label";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fill(WVTTSampleEntry* wvtt) {
|
void Fill(TextSampleEntry* wvtt) {
|
||||||
|
wvtt->format = FOURCC_wvtt;
|
||||||
Fill(&wvtt->config);
|
Fill(&wvtt->config);
|
||||||
Fill(&wvtt->label);
|
Fill(&wvtt->label);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modify(WVTTSampleEntry* wvtt) {
|
void Modify(TextSampleEntry* wvtt) {
|
||||||
Modify(&wvtt->config);
|
Modify(&wvtt->config);
|
||||||
Modify(&wvtt->label);
|
Modify(&wvtt->label);
|
||||||
}
|
}
|
||||||
|
@ -953,7 +964,7 @@ typedef testing::Types<FileType,
|
||||||
AudioSampleEntry,
|
AudioSampleEntry,
|
||||||
WebVTTConfigurationBox,
|
WebVTTConfigurationBox,
|
||||||
WebVTTSourceLabelBox,
|
WebVTTSourceLabelBox,
|
||||||
WVTTSampleEntry,
|
TextSampleEntry,
|
||||||
SampleDescription,
|
SampleDescription,
|
||||||
DecodingTimeToSample,
|
DecodingTimeToSample,
|
||||||
CompositionTimeToSample,
|
CompositionTimeToSample,
|
||||||
|
|
Loading…
Reference in New Issue