Box definitions for WebVTT
Change-Id: I94d38bef918eed18df7cd312126e2d589aadf9c7
This commit is contained in:
parent
c8e3345959
commit
09d1c2ce9f
|
@ -53,6 +53,15 @@ bool BufferReader::ReadToVector(std::vector<uint8_t>* vec, size_t count) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BufferReader::ReadToString(std::string* str, size_t size) {
|
||||
DCHECK(str);
|
||||
if (!HasBytes(size))
|
||||
return false;
|
||||
str->assign(buf_ + pos_, buf_ + pos_ + size);
|
||||
pos_ += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BufferReader::SkipBytes(size_t num_bytes) {
|
||||
if (!HasBytes(num_bytes))
|
||||
return false;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "packager/base/compiler_specific.h"
|
||||
|
@ -53,6 +54,7 @@ class BufferReader {
|
|||
/// @}
|
||||
|
||||
bool ReadToVector(std::vector<uint8_t>* t, size_t count) WARN_UNUSED_RESULT;
|
||||
bool ReadToString(std::string* str, size_t size) WARN_UNUSED_RESULT;
|
||||
|
||||
/// Advance the stream by this many bytes.
|
||||
/// @return false if there are not enough bytes in the buffer, true otherwise.
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef MEDIA_FORMATS_MP4_BOX_BUFFER_H_
|
||||
#define MEDIA_FORMATS_MP4_BOX_BUFFER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "packager/base/compiler_specific.h"
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/formats/mp4/box.h"
|
||||
|
@ -55,6 +57,14 @@ class BoxBuffer {
|
|||
return writer_->Size();
|
||||
}
|
||||
|
||||
/// @return In read mode, return the number of bytes left in the box.
|
||||
/// In write mode, return 0.
|
||||
size_t BytesLeft() const {
|
||||
if (reader_)
|
||||
return reader_->size() - reader_->pos();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @name Read/write integers of various sizes and signedness.
|
||||
/// @{
|
||||
bool ReadWriteUInt8(uint8_t* v) {
|
||||
|
@ -120,9 +130,21 @@ class BoxBuffer {
|
|||
if (reader_)
|
||||
return reader_->ReadToVector(vector, count);
|
||||
DCHECK_EQ(vector->size(), count);
|
||||
writer_->AppendVector(*vector);
|
||||
writer_->AppendArray(vector_as_array(vector), count);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Reads @a size characters from the buffer and sets it to str.
|
||||
/// Writes @a str to the buffer. Write mode ignores @a size.
|
||||
bool ReadWriteString(std::string* str, size_t size) {
|
||||
if (reader_)
|
||||
return reader_->ReadToString(str, size);
|
||||
DCHECK_EQ(str->size(), size);
|
||||
writer_->AppendArray(reinterpret_cast<const uint8_t*>(str->data()),
|
||||
str->size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadWriteFourCC(FourCC* fourcc) {
|
||||
if (reader_)
|
||||
return reader_->ReadFourCC(fourcc);
|
||||
|
|
|
@ -25,6 +25,7 @@ const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|||
// Default entries for HandlerReference box.
|
||||
const char kVideoHandlerName[] = "VideoHandler";
|
||||
const char kAudioHandlerName[] = "SoundHandler";
|
||||
const char kTextHandlerName[] = "TextHandler";
|
||||
|
||||
// Default values for VideoSampleEntry box.
|
||||
const uint32_t kVideoResolution = 0x00480000; // 72 dpi.
|
||||
|
@ -36,6 +37,10 @@ const char kAvcCompressorName[] = "\012AVC Coding";
|
|||
const char kHevcCompressorName[] = "\013HEVC Coding";
|
||||
const char kVpcCompressorName[] = "\012VPC Coding";
|
||||
|
||||
// Using negative value as "not set". It is very unlikely that 2^31 cues happen
|
||||
// at once.
|
||||
const int kCueSourceIdNotSet = -1;
|
||||
|
||||
// Utility functions to check if the 64bit integers can fit in 32bit integer.
|
||||
bool IsFitIn32Bits(uint64_t a) {
|
||||
return a <= std::numeric_limits<uint32_t>::max();
|
||||
|
@ -377,10 +382,20 @@ FourCC SampleDescription::BoxType() const { return FOURCC_STSD; }
|
|||
|
||||
bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
uint32_t count = 0;
|
||||
if (type == kVideo)
|
||||
count = video_entries.size();
|
||||
else
|
||||
count = audio_entries.size();
|
||||
switch (type) {
|
||||
case kVideo:
|
||||
count = video_entries.size();
|
||||
break;
|
||||
case kAudio:
|
||||
count = audio_entries.size();
|
||||
break;
|
||||
case kText:
|
||||
count = wvtt_entries.size();
|
||||
break;
|
||||
default:
|
||||
NOTIMPLEMENTED() << "SampleDecryption type " << type
|
||||
<< " is not handled. Skipping.";
|
||||
}
|
||||
RCHECK(ReadWriteHeaderInternal(buffer) &&
|
||||
buffer->ReadWriteUInt32(&count));
|
||||
|
||||
|
@ -397,6 +412,9 @@ bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
} else if (type == kAudio) {
|
||||
RCHECK(reader->ReadAllChildren(&audio_entries));
|
||||
RCHECK(audio_entries.size() == count);
|
||||
} else if (type == kText) {
|
||||
RCHECK(reader->ReadAllChildren(&wvtt_entries));
|
||||
RCHECK(wvtt_entries.size() == count);
|
||||
}
|
||||
} else {
|
||||
DCHECK_LT(0u, count);
|
||||
|
@ -406,6 +424,9 @@ bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
} else if (type == kAudio) {
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
RCHECK(buffer->ReadWriteChild(&audio_entries[i]));
|
||||
} else if (type == kText) {
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
RCHECK(buffer->ReadWriteChild(&wvtt_entries[i]));
|
||||
} else {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
@ -803,6 +824,10 @@ bool HandlerReference::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
hdlr_type = FOURCC_SOUN;
|
||||
handler_name.assign(kAudioHandlerName,
|
||||
kAudioHandlerName + arraysize(kAudioHandlerName));
|
||||
} else if (type == kText) {
|
||||
hdlr_type = FOURCC_TEXT;
|
||||
handler_name.assign(kTextHandlerName,
|
||||
kTextHandlerName + arraysize(kTextHandlerName));
|
||||
} else {
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
|
@ -828,9 +853,15 @@ bool HandlerReference::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
}
|
||||
|
||||
uint32_t HandlerReference::ComputeSizeInternal() {
|
||||
return HeaderSize() + kFourCCSize + 16 + // 16 bytes Reserved
|
||||
(type == kVideo ? sizeof(kVideoHandlerName)
|
||||
: sizeof(kAudioHandlerName));
|
||||
uint32_t box_size = HeaderSize() + kFourCCSize + 16; // 16 bytes Reserved
|
||||
if (type == kVideo) {
|
||||
box_size += sizeof(kVideoHandlerName);
|
||||
} else if (type == kAudio) {
|
||||
box_size += sizeof(kAudioHandlerName);
|
||||
} else {
|
||||
box_size += sizeof(kTextHandlerName);
|
||||
}
|
||||
return box_size;
|
||||
}
|
||||
|
||||
CodecConfigurationRecord::CodecConfigurationRecord() : box_type(FOURCC_NULL) {}
|
||||
|
@ -844,7 +875,7 @@ FourCC CodecConfigurationRecord::BoxType() const {
|
|||
bool CodecConfigurationRecord::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
if (buffer->Reading()) {
|
||||
RCHECK(buffer->ReadWriteVector(&data, buffer->Size() - buffer->Pos()));
|
||||
RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
|
||||
} else {
|
||||
RCHECK(buffer->ReadWriteVector(&data, data.size()));
|
||||
}
|
||||
|
@ -996,7 +1027,7 @@ bool ElementaryStreamDescriptor::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
if (buffer->Reading()) {
|
||||
std::vector<uint8_t> data;
|
||||
RCHECK(buffer->ReadWriteVector(&data, buffer->Size() - buffer->Pos()));
|
||||
RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
|
||||
RCHECK(es_descriptor.Parse(data));
|
||||
if (es_descriptor.IsAAC()) {
|
||||
RCHECK(aac_audio_specific_config.Parse(
|
||||
|
@ -1104,6 +1135,68 @@ uint32_t AudioSampleEntry::ComputeSizeInternal() {
|
|||
4; // 4 bytes predefined.
|
||||
}
|
||||
|
||||
WebVTTConfigurationBox::WebVTTConfigurationBox() {}
|
||||
WebVTTConfigurationBox::~WebVTTConfigurationBox() {}
|
||||
|
||||
FourCC WebVTTConfigurationBox::BoxType() const {
|
||||
return FOURCC_vttC;
|
||||
}
|
||||
|
||||
bool WebVTTConfigurationBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
return buffer->ReadWriteString(
|
||||
&config,
|
||||
buffer->Reading() ? buffer->BytesLeft() : config.size());
|
||||
}
|
||||
|
||||
uint32_t WebVTTConfigurationBox::ComputeSizeInternal() {
|
||||
return HeaderSize() + config.size();
|
||||
}
|
||||
|
||||
WebVTTSourceLabelBox::WebVTTSourceLabelBox() {}
|
||||
WebVTTSourceLabelBox::~WebVTTSourceLabelBox() {}
|
||||
|
||||
FourCC WebVTTSourceLabelBox::BoxType() const {
|
||||
return FOURCC_vlab;
|
||||
}
|
||||
|
||||
bool WebVTTSourceLabelBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
return buffer->ReadWriteString(&source_label, buffer->Reading()
|
||||
? buffer->BytesLeft()
|
||||
: source_label.size());
|
||||
}
|
||||
|
||||
uint32_t WebVTTSourceLabelBox::ComputeSizeInternal() {
|
||||
if (source_label.empty())
|
||||
return 0;
|
||||
return HeaderSize() + source_label.size();
|
||||
}
|
||||
|
||||
WVTTSampleEntry::WVTTSampleEntry() {}
|
||||
WVTTSampleEntry::~WVTTSampleEntry() {}
|
||||
|
||||
FourCC WVTTSampleEntry::BoxType() const {
|
||||
return FOURCC_wvtt;
|
||||
}
|
||||
|
||||
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));
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t WVTTSampleEntry::ComputeSizeInternal() {
|
||||
// 6 for the (anonymous) reserved bytes for SampleEntry class.
|
||||
return HeaderSize() + 6 + sizeof(data_reference_index) +
|
||||
config.ComputeSize() + label.ComputeSize();
|
||||
}
|
||||
|
||||
MediaHeader::MediaHeader()
|
||||
: creation_time(0), modification_time(0), timescale(0), duration(0) {
|
||||
language[0] = 0;
|
||||
|
@ -1192,6 +1285,19 @@ uint32_t SoundMediaHeader::ComputeSizeInternal() {
|
|||
return HeaderSize() + sizeof(balance) + sizeof(uint16_t);
|
||||
}
|
||||
|
||||
SubtitleMediaHeader::SubtitleMediaHeader() {}
|
||||
SubtitleMediaHeader::~SubtitleMediaHeader() {}
|
||||
|
||||
FourCC SubtitleMediaHeader::BoxType() const { return FOURCC_sthd; }
|
||||
|
||||
bool SubtitleMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
return ReadWriteHeaderInternal(buffer);
|
||||
}
|
||||
|
||||
uint32_t SubtitleMediaHeader::ComputeSizeInternal() {
|
||||
return HeaderSize();
|
||||
}
|
||||
|
||||
DataEntryUrl::DataEntryUrl() {
|
||||
const uint32_t kDataEntryUrlFlags = 1;
|
||||
flags = kDataEntryUrlFlags;
|
||||
|
@ -1260,12 +1366,19 @@ bool MediaInformation::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
buffer->PrepareChildren() &&
|
||||
buffer->ReadWriteChild(&dinf) &&
|
||||
buffer->ReadWriteChild(&sample_table));
|
||||
if (sample_table.description.type == kVideo)
|
||||
RCHECK(buffer->ReadWriteChild(&vmhd));
|
||||
else if (sample_table.description.type == kAudio)
|
||||
RCHECK(buffer->ReadWriteChild(&smhd));
|
||||
else
|
||||
NOTIMPLEMENTED();
|
||||
switch (sample_table.description.type) {
|
||||
case kVideo:
|
||||
RCHECK(buffer->ReadWriteChild(&vmhd));
|
||||
break;
|
||||
case kAudio:
|
||||
RCHECK(buffer->ReadWriteChild(&smhd));
|
||||
break;
|
||||
case kText:
|
||||
RCHECK(buffer->ReadWriteChild(&sthd));
|
||||
break;
|
||||
default:
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
// Hint is not supported for now.
|
||||
return true;
|
||||
}
|
||||
|
@ -1273,10 +1386,19 @@ bool MediaInformation::ReadWriteInternal(BoxBuffer* buffer) {
|
|||
uint32_t MediaInformation::ComputeSizeInternal() {
|
||||
uint32_t box_size =
|
||||
HeaderSize() + dinf.ComputeSize() + sample_table.ComputeSize();
|
||||
if (sample_table.description.type == kVideo)
|
||||
box_size += vmhd.ComputeSize();
|
||||
else if (sample_table.description.type == kAudio)
|
||||
box_size += smhd.ComputeSize();
|
||||
switch (sample_table.description.type) {
|
||||
case kVideo:
|
||||
box_size += vmhd.ComputeSize();
|
||||
break;
|
||||
case kAudio:
|
||||
box_size += smhd.ComputeSize();
|
||||
break;
|
||||
case kText:
|
||||
box_size += sthd.ComputeSize();
|
||||
break;
|
||||
default:
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
return box_size;
|
||||
}
|
||||
|
||||
|
@ -1912,6 +2034,154 @@ uint32_t MediaData::ComputeSizeInternal() {
|
|||
return HeaderSize() + data_size;
|
||||
}
|
||||
|
||||
CueSourceIDBox::CueSourceIDBox() : source_id(kCueSourceIdNotSet) {}
|
||||
CueSourceIDBox::~CueSourceIDBox() {}
|
||||
|
||||
FourCC CueSourceIDBox::BoxType() const { return FOURCC_vsid; }
|
||||
|
||||
bool CueSourceIDBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteInt32(&source_id));
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t CueSourceIDBox::ComputeSizeInternal() {
|
||||
if (source_id == kCueSourceIdNotSet)
|
||||
return 0;
|
||||
return HeaderSize() + sizeof(source_id);
|
||||
}
|
||||
|
||||
CueTimeBox::CueTimeBox() {}
|
||||
CueTimeBox::~CueTimeBox() {}
|
||||
|
||||
FourCC CueTimeBox::BoxType() const {
|
||||
return FOURCC_ctim;
|
||||
}
|
||||
|
||||
bool CueTimeBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
return buffer->ReadWriteString(
|
||||
&cue_current_time,
|
||||
buffer->Reading() ? buffer->BytesLeft() : cue_current_time.size());
|
||||
}
|
||||
|
||||
uint32_t CueTimeBox::ComputeSizeInternal() {
|
||||
if (cue_current_time.empty())
|
||||
return 0;
|
||||
return HeaderSize() + cue_current_time.size();
|
||||
}
|
||||
|
||||
CueIDBox::CueIDBox() {}
|
||||
CueIDBox::~CueIDBox() {}
|
||||
|
||||
FourCC CueIDBox::BoxType() const {
|
||||
return FOURCC_iden;
|
||||
}
|
||||
|
||||
bool CueIDBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
return buffer->ReadWriteString(
|
||||
&cue_id, buffer->Reading() ? buffer->BytesLeft() : cue_id.size());
|
||||
}
|
||||
|
||||
uint32_t CueIDBox::ComputeSizeInternal() {
|
||||
if (cue_id.empty())
|
||||
return 0;
|
||||
return HeaderSize() + cue_id.size();
|
||||
}
|
||||
|
||||
CueSettingsBox::CueSettingsBox() {}
|
||||
CueSettingsBox::~CueSettingsBox() {}
|
||||
|
||||
FourCC CueSettingsBox::BoxType() const {
|
||||
return FOURCC_sttg;
|
||||
}
|
||||
|
||||
bool CueSettingsBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
return buffer->ReadWriteString(
|
||||
&settings, buffer->Reading() ? buffer->BytesLeft() : settings.size());
|
||||
}
|
||||
|
||||
uint32_t CueSettingsBox::ComputeSizeInternal() {
|
||||
if (settings.empty())
|
||||
return 0;
|
||||
return HeaderSize() + settings.size();
|
||||
}
|
||||
|
||||
CuePayloadBox::CuePayloadBox() {}
|
||||
CuePayloadBox::~CuePayloadBox() {}
|
||||
|
||||
FourCC CuePayloadBox::BoxType() const {
|
||||
return FOURCC_payl;
|
||||
}
|
||||
|
||||
bool CuePayloadBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
return buffer->ReadWriteString(
|
||||
&cue_text, buffer->Reading() ? buffer->BytesLeft() : cue_text.size());
|
||||
}
|
||||
|
||||
uint32_t CuePayloadBox::ComputeSizeInternal() {
|
||||
return HeaderSize() + cue_text.size();
|
||||
}
|
||||
|
||||
VTTEmptyCueBox::VTTEmptyCueBox() {}
|
||||
VTTEmptyCueBox::~VTTEmptyCueBox() {}
|
||||
|
||||
FourCC VTTEmptyCueBox::BoxType() const {
|
||||
return FOURCC_vtte;
|
||||
}
|
||||
|
||||
bool VTTEmptyCueBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
return ReadWriteHeaderInternal(buffer);
|
||||
}
|
||||
|
||||
uint32_t VTTEmptyCueBox::ComputeSizeInternal() {
|
||||
return HeaderSize();
|
||||
}
|
||||
|
||||
VTTAdditionalTextBox::VTTAdditionalTextBox() {}
|
||||
VTTAdditionalTextBox::~VTTAdditionalTextBox() {}
|
||||
|
||||
FourCC VTTAdditionalTextBox::BoxType() const {
|
||||
return FOURCC_vtta;
|
||||
}
|
||||
|
||||
bool VTTAdditionalTextBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer));
|
||||
return buffer->ReadWriteString(
|
||||
&cue_additional_text,
|
||||
buffer->Reading() ? buffer->BytesLeft() : cue_additional_text.size());
|
||||
}
|
||||
|
||||
uint32_t VTTAdditionalTextBox::ComputeSizeInternal() {
|
||||
return HeaderSize() + cue_additional_text.size();
|
||||
}
|
||||
|
||||
VTTCueBox::VTTCueBox() {}
|
||||
VTTCueBox::~VTTCueBox() {}
|
||||
|
||||
FourCC VTTCueBox::BoxType() const {
|
||||
return FOURCC_vttc;
|
||||
}
|
||||
|
||||
bool VTTCueBox::ReadWriteInternal(BoxBuffer* buffer) {
|
||||
RCHECK(ReadWriteHeaderInternal(buffer) &&
|
||||
buffer->PrepareChildren() &&
|
||||
buffer->ReadWriteChild(&cue_source_id) &&
|
||||
buffer->ReadWriteChild(&cue_id) &&
|
||||
buffer->ReadWriteChild(&cue_time) &&
|
||||
buffer->ReadWriteChild(&cue_settings) &&
|
||||
buffer->ReadWriteChild(&cue_payload));
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t VTTCueBox::ComputeSizeInternal() {
|
||||
return HeaderSize() + cue_source_id.ComputeSize() + cue_id.ComputeSize() +
|
||||
cue_time.ComputeSize() + cue_settings.ComputeSize() +
|
||||
cue_payload.ComputeSize();
|
||||
}
|
||||
|
||||
} // namespace mp4
|
||||
} // namespace media
|
||||
} // namespace edash_packager
|
||||
|
|
|
@ -23,7 +23,8 @@ enum TrackType {
|
|||
kInvalid = 0,
|
||||
kVideo,
|
||||
kAudio,
|
||||
kHint
|
||||
kHint,
|
||||
kText,
|
||||
};
|
||||
|
||||
class BoxBuffer;
|
||||
|
@ -233,12 +234,33 @@ struct AudioSampleEntry : Box {
|
|||
DTSSpecific ddts;
|
||||
};
|
||||
|
||||
struct WebVTTConfigurationBox : Box {
|
||||
DECLARE_BOX_METHODS(WebVTTConfigurationBox);
|
||||
std::string config;
|
||||
};
|
||||
|
||||
struct WebVTTSourceLabelBox : Box {
|
||||
DECLARE_BOX_METHODS(WebVTTSourceLabelBox);
|
||||
std::string source_label;
|
||||
};
|
||||
|
||||
struct WVTTSampleEntry : Box {
|
||||
DECLARE_BOX_METHODS(WVTTSampleEntry);
|
||||
|
||||
uint16_t data_reference_index;
|
||||
|
||||
WebVTTConfigurationBox config;
|
||||
WebVTTSourceLabelBox label;
|
||||
// Optional MPEG4BitRateBox.
|
||||
};
|
||||
|
||||
struct SampleDescription : FullBox {
|
||||
DECLARE_BOX_METHODS(SampleDescription);
|
||||
|
||||
TrackType type;
|
||||
std::vector<VideoSampleEntry> video_entries;
|
||||
std::vector<AudioSampleEntry> audio_entries;
|
||||
std::vector<WVTTSampleEntry> wvtt_entries;
|
||||
};
|
||||
|
||||
struct DecodingTime {
|
||||
|
@ -358,6 +380,10 @@ struct SoundMediaHeader : FullBox {
|
|||
uint16_t balance;
|
||||
};
|
||||
|
||||
struct SubtitleMediaHeader : FullBox {
|
||||
DECLARE_BOX_METHODS(SubtitleMediaHeader);
|
||||
};
|
||||
|
||||
struct DataEntryUrl : FullBox {
|
||||
DECLARE_BOX_METHODS(DataEntryUrl);
|
||||
|
||||
|
@ -385,6 +411,7 @@ struct MediaInformation : Box {
|
|||
// Exactly one specific meida header shall be present, vmhd, smhd, hmhd, nmhd.
|
||||
VideoMediaHeader vmhd;
|
||||
SoundMediaHeader smhd;
|
||||
SubtitleMediaHeader sthd;
|
||||
};
|
||||
|
||||
struct Media : Box {
|
||||
|
@ -591,6 +618,50 @@ struct MediaData : Box {
|
|||
uint32_t data_size;
|
||||
};
|
||||
|
||||
struct CueSourceIDBox : Box {
|
||||
DECLARE_BOX_METHODS(CueSourceIDBox);
|
||||
int32_t source_id;
|
||||
};
|
||||
|
||||
struct CueTimeBox : Box {
|
||||
DECLARE_BOX_METHODS(CueTimeBox);
|
||||
std::string cue_current_time;
|
||||
};
|
||||
|
||||
struct CueIDBox : Box {
|
||||
DECLARE_BOX_METHODS(CueIDBox);
|
||||
std::string cue_id;
|
||||
};
|
||||
|
||||
struct CueSettingsBox : Box {
|
||||
DECLARE_BOX_METHODS(CueSettingsBox);
|
||||
std::string settings;
|
||||
};
|
||||
|
||||
struct CuePayloadBox : Box {
|
||||
DECLARE_BOX_METHODS(CuePayloadBox);
|
||||
std::string cue_text;
|
||||
};
|
||||
|
||||
struct VTTEmptyCueBox : Box {
|
||||
DECLARE_BOX_METHODS(VTTEmptyCueBox);
|
||||
};
|
||||
|
||||
struct VTTAdditionalTextBox : Box {
|
||||
DECLARE_BOX_METHODS(VTTAdditionalTextBox);
|
||||
std::string cue_additional_text;
|
||||
};
|
||||
|
||||
struct VTTCueBox : Box {
|
||||
DECLARE_BOX_METHODS(VTTCueBox);
|
||||
|
||||
CueSourceIDBox cue_source_id;
|
||||
CueIDBox cue_id;
|
||||
CueTimeBox cue_time;
|
||||
CueSettingsBox cue_settings;
|
||||
CuePayloadBox cue_payload;
|
||||
};
|
||||
|
||||
#undef DECLARE_BOX
|
||||
|
||||
} // namespace mp4
|
||||
|
|
|
@ -209,6 +209,21 @@ inline bool operator==(const AudioSampleEntry& lhs,
|
|||
lhs.ddts == rhs.ddts;
|
||||
}
|
||||
|
||||
inline bool operator==(const WebVTTConfigurationBox& lhs,
|
||||
const WebVTTConfigurationBox& rhs) {
|
||||
return lhs.config == rhs.config;
|
||||
}
|
||||
|
||||
inline bool operator==(const WebVTTSourceLabelBox& lhs,
|
||||
const WebVTTSourceLabelBox& rhs) {
|
||||
return lhs.source_label == rhs.source_label;
|
||||
}
|
||||
|
||||
inline bool operator==(const WVTTSampleEntry& lhs,
|
||||
const WVTTSampleEntry& rhs) {
|
||||
return lhs.config == rhs.config && lhs.label == rhs.label;
|
||||
}
|
||||
|
||||
inline bool operator==(const MediaHeader& lhs, const MediaHeader& rhs) {
|
||||
return lhs.creation_time == rhs.creation_time &&
|
||||
lhs.modification_time == rhs.modification_time &&
|
||||
|
@ -229,6 +244,11 @@ inline bool operator==(const SoundMediaHeader& lhs,
|
|||
return lhs.balance == rhs.balance;
|
||||
}
|
||||
|
||||
inline bool operator==(const SubtitleMediaHeader& lhs,
|
||||
const SubtitleMediaHeader& rhs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator==(const DataEntryUrl& lhs, const DataEntryUrl& rhs) {
|
||||
return lhs.flags == rhs.flags && lhs.location == rhs.location;
|
||||
}
|
||||
|
@ -366,6 +386,47 @@ inline bool operator==(const SegmentIndex& lhs, const SegmentIndex& rhs) {
|
|||
lhs.references == rhs.references;
|
||||
}
|
||||
|
||||
inline bool operator==(const CueSourceIDBox& lhs,
|
||||
const CueSourceIDBox& rhs) {
|
||||
return lhs.source_id == rhs.source_id;
|
||||
}
|
||||
|
||||
inline bool operator==(const CueTimeBox& lhs,
|
||||
const CueTimeBox& rhs) {
|
||||
return lhs.cue_current_time == rhs.cue_current_time;
|
||||
}
|
||||
|
||||
inline bool operator==(const CueIDBox& lhs,
|
||||
const CueIDBox& rhs) {
|
||||
return lhs.cue_id == rhs.cue_id;
|
||||
}
|
||||
|
||||
inline bool operator==(const CueSettingsBox& lhs,
|
||||
const CueSettingsBox& rhs) {
|
||||
return lhs.settings == rhs.settings;
|
||||
}
|
||||
|
||||
inline bool operator==(const CuePayloadBox& lhs,
|
||||
const CuePayloadBox& rhs) {
|
||||
return lhs.cue_text == rhs.cue_text;
|
||||
}
|
||||
|
||||
inline bool operator==(const VTTEmptyCueBox& lhs, const VTTEmptyCueBox& rhs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator==(const VTTAdditionalTextBox& lhs,
|
||||
const VTTAdditionalTextBox& rhs) {
|
||||
return lhs.cue_additional_text == rhs.cue_additional_text;
|
||||
}
|
||||
|
||||
inline bool operator==(const VTTCueBox& lhs,
|
||||
const VTTCueBox& rhs) {
|
||||
return lhs.cue_source_id == rhs.cue_source_id && lhs.cue_id == rhs.cue_id &&
|
||||
lhs.cue_time == rhs.cue_time && lhs.cue_settings == rhs.cue_settings &&
|
||||
lhs.cue_payload == rhs.cue_payload;
|
||||
}
|
||||
|
||||
} // namespace mp4
|
||||
} // namespace media
|
||||
} // namespace edash_packager
|
||||
|
|
|
@ -335,6 +335,33 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
|
||||
void Modify(AudioSampleEntry* enca) { enca->channelcount = 2; }
|
||||
|
||||
void Fill(WebVTTConfigurationBox* vttc) {
|
||||
vttc->config = "WEBVTT";
|
||||
}
|
||||
|
||||
void Modify(WebVTTConfigurationBox* vttc) {
|
||||
vttc->config = "WEBVTT\n"
|
||||
"Region: id=someting width=40\% lines=3";
|
||||
}
|
||||
|
||||
void Fill(WebVTTSourceLabelBox* vlab) {
|
||||
vlab->source_label = "some_label";
|
||||
}
|
||||
|
||||
void Modify(WebVTTSourceLabelBox* vlab) {
|
||||
vlab->source_label = "another_label";
|
||||
}
|
||||
|
||||
void Fill(WVTTSampleEntry* wvtt) {
|
||||
Fill(&wvtt->config);
|
||||
Fill(&wvtt->label);
|
||||
}
|
||||
|
||||
void Modify(WVTTSampleEntry* wvtt) {
|
||||
Modify(&wvtt->config);
|
||||
Modify(&wvtt->label);
|
||||
}
|
||||
|
||||
void Fill(SampleDescription* stsd) {
|
||||
stsd->type = kSampleDescriptionTrackType;
|
||||
stsd->video_entries.resize(1);
|
||||
|
@ -475,6 +502,9 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
|
||||
void Modify(SoundMediaHeader* smhd) { smhd->balance /= 2; }
|
||||
|
||||
void Fill(SubtitleMediaHeader* sthd) {}
|
||||
void Modify(SubtitleMediaHeader* sthd) {}
|
||||
|
||||
void Fill(DataEntryUrl* url) {
|
||||
url->flags = 2;
|
||||
url->location.assign(kData8, kData8 + arraysize(kData8));
|
||||
|
@ -718,6 +748,73 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
sidx->version = 1;
|
||||
}
|
||||
|
||||
void Fill(CueSourceIDBox* vsid) {
|
||||
vsid->source_id = 5;
|
||||
}
|
||||
|
||||
void Modify(CueSourceIDBox* vsid) {
|
||||
vsid->source_id = 100;
|
||||
}
|
||||
|
||||
void Fill(CueTimeBox* ctim) {
|
||||
ctim->cue_current_time = "00:19:00.000";
|
||||
}
|
||||
|
||||
void Modify(CueTimeBox* ctim) {
|
||||
ctim->cue_current_time = "00:20:01.291";
|
||||
}
|
||||
|
||||
void Fill(CueIDBox* iden) {
|
||||
iden->cue_id = "some_id";
|
||||
}
|
||||
|
||||
void Modify(CueIDBox* iden) {
|
||||
iden->cue_id = "another_id";
|
||||
}
|
||||
|
||||
void Fill(CueSettingsBox* sttg) {
|
||||
sttg->settings = "align:left";
|
||||
}
|
||||
|
||||
void Modify(CueSettingsBox* sttg) {
|
||||
sttg->settings = "align:right";
|
||||
}
|
||||
|
||||
void Fill(CuePayloadBox* payl) {
|
||||
payl->cue_text = "hello";
|
||||
}
|
||||
|
||||
void Modify(CuePayloadBox* payl) {
|
||||
payl->cue_text = "hi";
|
||||
}
|
||||
|
||||
void Fill(VTTEmptyCueBox* vtte) {}
|
||||
void Modify(VTTEmptyCueBox* vtte) {}
|
||||
|
||||
void Fill(VTTAdditionalTextBox* vtta) {
|
||||
vtta->cue_additional_text = "NOTE some comment";
|
||||
}
|
||||
|
||||
void Modify(VTTAdditionalTextBox* vtta) {
|
||||
vtta->cue_additional_text = "NOTE another comment";
|
||||
}
|
||||
|
||||
void Fill(VTTCueBox* vttc) {
|
||||
Fill(&vttc->cue_source_id);
|
||||
Fill(&vttc->cue_id);
|
||||
Fill(&vttc->cue_time);
|
||||
Fill(&vttc->cue_settings);
|
||||
Fill(&vttc->cue_payload);
|
||||
}
|
||||
|
||||
void Modify(VTTCueBox* vttc) {
|
||||
Modify(&vttc->cue_source_id);
|
||||
Modify(&vttc->cue_id);
|
||||
Modify(&vttc->cue_time);
|
||||
Modify(&vttc->cue_settings);
|
||||
Modify(&vttc->cue_payload);
|
||||
}
|
||||
|
||||
bool IsOptional(const SampleAuxiliaryInformationOffset* box) { return true; }
|
||||
bool IsOptional(const SampleAuxiliaryInformationSize* box) { return true; }
|
||||
bool IsOptional(const ProtectionSchemeInfo* box) { return true; }
|
||||
|
@ -726,12 +823,18 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
|||
bool IsOptional(const CodecConfigurationRecord* box) { return true; }
|
||||
bool IsOptional(const PixelAspectRatio* box) { return true; }
|
||||
bool IsOptional(const ElementaryStreamDescriptor* box) { return true; }
|
||||
// Recommended, but optional.
|
||||
bool IsOptional(const WebVTTSourceLabelBox* box) { return true; }
|
||||
bool IsOptional(const CompositionTimeToSample* box) { return true; }
|
||||
bool IsOptional(const SyncSample* box) { return true; }
|
||||
bool IsOptional(const MovieExtendsHeader* box) { return true; }
|
||||
bool IsOptional(const MovieExtends* box) { return true; }
|
||||
bool IsOptional(const SampleToGroup* box) { return true; }
|
||||
bool IsOptional(const SampleGroupDescription* box) { return true; }
|
||||
bool IsOptional(const CueSourceIDBox* box) { return true; }
|
||||
bool IsOptional(const CueIDBox* box) { return true; }
|
||||
bool IsOptional(const CueTimeBox* box) { return true; }
|
||||
bool IsOptional(const CueSettingsBox* box) { return true; }
|
||||
|
||||
protected:
|
||||
scoped_ptr<BufferWriter> buffer_;
|
||||
|
@ -758,6 +861,9 @@ typedef testing::Types<
|
|||
VideoSampleEntry,
|
||||
ElementaryStreamDescriptor,
|
||||
AudioSampleEntry,
|
||||
WebVTTConfigurationBox,
|
||||
WebVTTSourceLabelBox,
|
||||
WVTTSampleEntry,
|
||||
SampleDescription,
|
||||
DecodingTimeToSample,
|
||||
CompositionTimeToSample,
|
||||
|
@ -771,6 +877,7 @@ typedef testing::Types<
|
|||
MediaHeader,
|
||||
VideoMediaHeader,
|
||||
SoundMediaHeader,
|
||||
SubtitleMediaHeader,
|
||||
DataEntryUrl,
|
||||
DataReference,
|
||||
DataInformation,
|
||||
|
@ -783,17 +890,25 @@ typedef testing::Types<
|
|||
Movie,
|
||||
TrackFragmentDecodeTime,
|
||||
MovieFragmentHeader,
|
||||
TrackFragmentHeader,
|
||||
TrackFragmentRun,
|
||||
TrackFragment,
|
||||
MovieFragment,
|
||||
SegmentIndex> Boxes;
|
||||
TrackFragmentHeader> Boxes;
|
||||
|
||||
// GTEST support a maximum of 50 types in the template list, so we have to
|
||||
// break it into two groups.
|
||||
typedef testing::Types<
|
||||
TrackFragmentRun,
|
||||
TrackFragment,
|
||||
MovieFragment,
|
||||
SegmentIndex,
|
||||
SampleToGroup,
|
||||
SampleGroupDescription> Boxes2;
|
||||
SampleGroupDescription,
|
||||
CueSourceIDBox,
|
||||
CueTimeBox,
|
||||
CueIDBox,
|
||||
CueSettingsBox,
|
||||
CuePayloadBox,
|
||||
VTTEmptyCueBox,
|
||||
VTTAdditionalTextBox,
|
||||
VTTCueBox> Boxes2;
|
||||
|
||||
TYPED_TEST_CASE_P(BoxDefinitionsTestGeneral);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace edash_packager {
|
|||
namespace media {
|
||||
namespace mp4 {
|
||||
|
||||
// TODO(rkuroiwa): Make these case sensitive. e.g. FOURCC_avc1.
|
||||
enum FourCC {
|
||||
FOURCC_NULL = 0,
|
||||
FOURCC_AVC1 = 0x61766331,
|
||||
|
@ -88,7 +89,9 @@ enum FourCC {
|
|||
FOURCC_STTS = 0x73747473,
|
||||
FOURCC_STYP = 0x73747970,
|
||||
FOURCC_STZ2 = 0x73747a32,
|
||||
FOURCC_SUBT = 0x73756274,
|
||||
FOURCC_TENC = 0x74656e63,
|
||||
FOURCC_TEXT = 0x74657874,
|
||||
FOURCC_TFDT = 0x74666474,
|
||||
FOURCC_TFHD = 0x74666864,
|
||||
FOURCC_TKHD = 0x746b6864,
|
||||
|
@ -97,8 +100,8 @@ enum FourCC {
|
|||
FOURCC_TREX = 0x74726578,
|
||||
FOURCC_TRUN = 0x7472756e,
|
||||
FOURCC_UDTA = 0x75647461,
|
||||
FOURCC_URL = 0x75726c20,
|
||||
FOURCC_URN = 0x75726e20,
|
||||
FOURCC_URL = 0x75726c20,
|
||||
FOURCC_URN = 0x75726e20,
|
||||
FOURCC_UUID = 0x75756964,
|
||||
FOURCC_VIDE = 0x76696465,
|
||||
FOURCC_VMHD = 0x766d6864,
|
||||
|
@ -107,6 +110,18 @@ enum FourCC {
|
|||
FOURCC_VP10 = 0x76703130,
|
||||
FOURCC_VPCC = 0x76706343,
|
||||
FOURCC_WIDE = 0x77696465,
|
||||
FOURCC_ctim = 0x6374696d,
|
||||
FOURCC_iden = 0x6964656e,
|
||||
FOURCC_payl = 0x7061796c,
|
||||
FOURCC_sthd = 0x73746864,
|
||||
FOURCC_sttg = 0x73747467,
|
||||
FOURCC_vlab = 0x766c6162,
|
||||
FOURCC_vsid = 0x76736964,
|
||||
FOURCC_vttC = 0x76747443,
|
||||
FOURCC_vtta = 0x76747461,
|
||||
FOURCC_vttc = 0x76747463,
|
||||
FOURCC_vtte = 0x76747465,
|
||||
FOURCC_wvtt = 0x77767474,
|
||||
};
|
||||
|
||||
const inline std::string FourCCToString(FourCC fourcc) {
|
||||
|
|
Loading…
Reference in New Issue