diff --git a/packager/media/formats/mp4/box_definitions.cc b/packager/media/formats/mp4/box_definitions.cc index e9304b03f2..2d9fc41354 100644 --- a/packager/media/formats/mp4/box_definitions.cc +++ b/packager/media/formats/mp4/box_definitions.cc @@ -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(); diff --git a/packager/media/formats/mp4/box_definitions.h b/packager/media/formats/mp4/box_definitions.h index 026ea162a8..a92b058529 100644 --- a/packager/media/formats/mp4/box_definitions.h +++ b/packager/media/formats/mp4/box_definitions.h @@ -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 sample_entries. std::vector video_entries; std::vector audio_entries; - std::vector wvtt_entries; + std::vector text_entries; }; struct DecodingTime { diff --git a/packager/media/formats/mp4/box_definitions_comparison.h b/packager/media/formats/mp4/box_definitions_comparison.h index 6f98ce4b5d..ab4c45dbd8 100644 --- a/packager/media/formats/mp4/box_definitions_comparison.h +++ b/packager/media/formats/mp4/box_definitions_comparison.h @@ -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; } diff --git a/packager/media/formats/mp4/box_definitions_unittest.cc b/packager/media/formats/mp4/box_definitions_unittest.cc index fb9bf615e7..5cce1e8dba 100644 --- a/packager/media/formats/mp4/box_definitions_unittest.cc +++ b/packager/media/formats/mp4/box_definitions_unittest.cc @@ -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 reader(CreateReader()); std::vector 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 reader(CreateReader()); std::vector 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 reader(CreateReader()); + std::vector 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