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:
KongQun Yang 2016-02-03 15:58:35 -08:00
parent bb3918e62b
commit 38c30bd7a1
4 changed files with 58 additions and 28 deletions

View File

@ -586,7 +586,7 @@ bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
count = audio_entries.size();
break;
case kText:
count = wvtt_entries.size();
count = text_entries.size();
break;
default:
NOTIMPLEMENTED() << "SampleDecryption type " << type
@ -609,8 +609,8 @@ bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
RCHECK(reader->ReadAllChildren(&audio_entries));
RCHECK(audio_entries.size() == count);
} else if (type == kText) {
RCHECK(reader->ReadAllChildren(&wvtt_entries));
RCHECK(wvtt_entries.size() == count);
RCHECK(reader->ReadAllChildren(&text_entries));
RCHECK(text_entries.size() == count);
}
} else {
DCHECK_LT(0u, count);
@ -622,7 +622,7 @@ bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
RCHECK(buffer->ReadWriteChild(&audio_entries[i]));
} else if (type == kText) {
for (uint32_t i = 0; i < count; ++i)
RCHECK(buffer->ReadWriteChild(&wvtt_entries[i]));
RCHECK(buffer->ReadWriteChild(&text_entries[i]));
} else {
NOTIMPLEMENTED();
}
@ -638,6 +638,9 @@ uint32_t SampleDescription::ComputeSizeInternal() {
} else if (type == kAudio) {
for (uint32_t i = 0; i < audio_entries.size(); ++i)
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;
}
@ -1589,25 +1592,37 @@ uint32_t WebVTTSourceLabelBox::ComputeSizeInternal() {
return HeaderSize() + source_label.size();
}
WVTTSampleEntry::WVTTSampleEntry() {}
WVTTSampleEntry::~WVTTSampleEntry() {}
TextSampleEntry::TextSampleEntry() : format(FOURCC_NULL) {}
TextSampleEntry::~TextSampleEntry() {}
FourCC WVTTSampleEntry::BoxType() const {
return FOURCC_wvtt;
FourCC TextSampleEntry::BoxType() const {
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) {
// TODO(rkuroiwa): Handle the optional MPEG4BitRateBox.
RCHECK(ReadWriteHeaderInternal(buffer) &&
buffer->IgnoreBytes(6) && // reserved for SampleEntry.
buffer->ReadWriteUInt16(&data_reference_index) &&
buffer->PrepareChildren() &&
buffer->ReadWriteChild(&config) &&
buffer->ReadWriteChild(&label));
bool TextSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
if (buffer->Reading()) {
DCHECK(buffer->reader());
format = buffer->reader()->type();
} else {
RCHECK(ReadWriteHeaderInternal(buffer));
}
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;
}
uint32_t WVTTSampleEntry::ComputeSizeInternal() {
uint32_t TextSampleEntry::ComputeSizeInternal() {
// 6 for the (anonymous) reserved bytes for SampleEntry class.
return HeaderSize() + 6 + sizeof(data_reference_index) +
config.ComputeSize() + label.ComputeSize();
@ -1762,7 +1777,7 @@ bool MediaInformation::ReadWriteInternal(BoxBuffer* buffer) {
RCHECK(buffer->ReadWriteChild(&smhd));
break;
case kText:
RCHECK(buffer->ReadWriteChild(&sthd));
RCHECK(buffer->TryReadWriteChild(&sthd));
break;
default:
NOTIMPLEMENTED();

View File

@ -374,11 +374,16 @@ struct WebVTTSourceLabelBox : Box {
std::string source_label;
};
struct WVTTSampleEntry : Box {
DECLARE_BOX_METHODS(WVTTSampleEntry);
struct TextSampleEntry : Box {
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;
// Sub boxes for wvtt text sample entry.
WebVTTConfigurationBox config;
WebVTTSourceLabelBox label;
// Optional MPEG4BitRateBox.
@ -392,7 +397,7 @@ struct SampleDescription : FullBox {
// SampleEntry struct, std::vector<SampleEntry> sample_entries.
std::vector<VideoSampleEntry> video_entries;
std::vector<AudioSampleEntry> audio_entries;
std::vector<WVTTSampleEntry> wvtt_entries;
std::vector<TextSampleEntry> text_entries;
};
struct DecodingTime {

View File

@ -270,8 +270,7 @@ inline bool operator==(const WebVTTSourceLabelBox& lhs,
return lhs.source_label == rhs.source_label;
}
inline bool operator==(const WVTTSampleEntry& lhs,
const WVTTSampleEntry& rhs) {
inline bool operator==(const TextSampleEntry& lhs, const TextSampleEntry& rhs) {
return lhs.config == rhs.config && lhs.label == rhs.label;
}

View File

@ -54,7 +54,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
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) {
scoped_ptr<BoxReader> reader(CreateReader());
std::vector<VideoSampleEntry> video_entries;
@ -64,7 +64,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
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) {
scoped_ptr<BoxReader> reader(CreateReader());
std::vector<AudioSampleEntry> audio_entries;
@ -74,6 +74,16 @@ class BoxDefinitionsTestGeneral : public testing::Test {
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
// be preset before scanning the box.
bool ReadBack(SampleDescription* stsd) {
@ -429,12 +439,13 @@ class BoxDefinitionsTestGeneral : public testing::Test {
vlab->source_label = "another_label";
}
void Fill(WVTTSampleEntry* wvtt) {
void Fill(TextSampleEntry* wvtt) {
wvtt->format = FOURCC_wvtt;
Fill(&wvtt->config);
Fill(&wvtt->label);
}
void Modify(WVTTSampleEntry* wvtt) {
void Modify(TextSampleEntry* wvtt) {
Modify(&wvtt->config);
Modify(&wvtt->label);
}
@ -953,7 +964,7 @@ typedef testing::Types<FileType,
AudioSampleEntry,
WebVTTConfigurationBox,
WebVTTSourceLabelBox,
WVTTSampleEntry,
TextSampleEntry,
SampleDescription,
DecodingTimeToSample,
CompositionTimeToSample,