Add support for DateUTC and DefaultDuration in MKV Muxer.

BUG=crbug.com/321825

Change-Id: I5ff8c5b9fd4e6be23ef2bc91a7a4ba021db6441f
This commit is contained in:
Sergey Ulanov 2014-04-08 21:44:14 -07:00
parent a7118d8ec5
commit 0fcec38045
4 changed files with 68 additions and 7 deletions

View File

@ -523,6 +523,7 @@ Track::Track(unsigned int* seed)
uid_(MakeUID(seed)),
codec_delay_(0),
seek_pre_roll_(0),
default_duration_(0),
codec_private_length_(0),
content_encoding_entries_(NULL),
content_encoding_entries_size_(0) {
@ -600,6 +601,8 @@ uint64 Track::PayloadSize() const {
size += EbmlElementSize(kMkvCodecDelay, codec_delay_);
if (seek_pre_roll_)
size += EbmlElementSize(kMkvSeekPreRoll, seek_pre_roll_);
if (default_duration_)
size += EbmlElementSize(kMkvDefaultDuration, default_duration_);
if (content_encoding_entries_size_ > 0) {
uint64 content_encodings_size = 0;
@ -652,7 +655,8 @@ bool Track::Write(IMkvWriter* writer) const {
size += EbmlElementSize(kMkvCodecDelay, codec_delay_);
if (seek_pre_roll_)
size += EbmlElementSize(kMkvSeekPreRoll, seek_pre_roll_);
if (default_duration_)
size += EbmlElementSize(kMkvDefaultDuration, default_duration_);
const int64 payload_position = writer->Position();
if (payload_position < 0)
@ -679,6 +683,10 @@ bool Track::Write(IMkvWriter* writer) const {
if (!WriteEbmlElement(writer, kMkvSeekPreRoll, seek_pre_roll_))
return false;
}
if (default_duration_) {
if (!WriteEbmlElement(writer, kMkvDefaultDuration, default_duration_))
return false;
}
if (codec_id_) {
if (!WriteEbmlElement(writer, kMkvCodecID, codec_id_))
return false;
@ -1888,6 +1896,7 @@ SegmentInfo::SegmentInfo()
muxing_app_(NULL),
timecode_scale_(1000000ULL),
writing_app_(NULL),
date_utc_(LLONG_MIN),
duration_pos_(-1) {
}
@ -1975,6 +1984,8 @@ bool SegmentInfo::Write(IMkvWriter* writer) {
uint64 size = EbmlElementSize(kMkvTimecodeScale, timecode_scale_);
if (duration_ > 0.0)
size += EbmlElementSize(kMkvDuration, static_cast<float>(duration_));
if (date_utc_ != LLONG_MIN)
size += EbmlDateElementSize(kMkvDateUTC, date_utc_);
size += EbmlElementSize(kMkvMuxingApp, muxing_app_);
size += EbmlElementSize(kMkvWritingApp, writing_app_);
@ -1996,6 +2007,9 @@ bool SegmentInfo::Write(IMkvWriter* writer) {
return false;
}
if (date_utc_ != LLONG_MIN)
WriteEbmlDateElement(writer, kMkvDateUTC, date_utc_);
if (!WriteEbmlElement(writer, kMkvMuxingApp, muxing_app_))
return false;
if (!WriteEbmlElement(writer, kMkvWritingApp, writing_app_))
@ -2977,12 +2991,12 @@ bool Segment::DoNewClusterProcessing(uint64 track_number,
if (result < 0) // error
return false;
// Always set force_new_cluster_ to false after TestFrame.
force_new_cluster_ = false;
// Always set force_new_cluster_ to false after TestFrame.
force_new_cluster_ = false;
// A non-zero result means create a new cluster.
if (result > 0 && !MakeNewCluster(frame_timestamp_ns))
return false;
// A non-zero result means create a new cluster.
if (result > 0 && !MakeNewCluster(frame_timestamp_ns))
return false;
// Write queued (audio) frames.
const int frame_count = WriteFramesAll();

View File

@ -353,6 +353,10 @@ class Track {
seek_pre_roll_ = seek_pre_roll;
}
uint64 seek_pre_roll() const { return seek_pre_roll_; }
void set_default_duration(uint64 default_duration) {
default_duration_ = default_duration;
}
uint64 default_duration() const { return default_duration_; }
uint64 codec_private_length() const { return codec_private_length_; }
uint32 content_encoding_entries_size() const {
@ -360,7 +364,7 @@ class Track {
}
private:
// Track element names
// Track element names.
char* codec_id_;
uint8* codec_private_;
char* language_;
@ -371,6 +375,7 @@ class Track {
uint64 uid_;
uint64 codec_delay_;
uint64 seek_pre_roll_;
uint64 default_duration_;
// Size of the CodecPrivate data in bytes.
uint64 codec_private_length_;
@ -993,6 +998,8 @@ class SegmentInfo {
uint64 timecode_scale() const { return timecode_scale_; }
void set_writing_app(const char* app);
const char* writing_app() const { return writing_app_; }
void set_date_utc(int64 date_utc) { date_utc_ = date_utc; }
int64 date_utc() const { return date_utc_; }
private:
// Segment Information element names.
@ -1004,6 +1011,8 @@ class SegmentInfo {
uint64 timecode_scale_;
// Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
char* writing_app_;
// LLONG_MIN when DateUTC is not set.
int64 date_utc_;
// The file position of the duration element.
int64 duration_pos_;

View File

@ -29,6 +29,13 @@
namespace mkvmuxer {
namespace {
// Date elements are always 8 octets in size.
const int kDateElementSize = 8;
} // namespace
int32 GetCodedUIntSize(uint64 value) {
if (value < 0x000000000000007FULL)
return 1;
@ -137,6 +144,19 @@ uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size) {
return ebml_size;
}
uint64 EbmlDateElementSize(uint64 type, int64 value) {
// Size of EBML ID
uint64 ebml_size = GetUIntSize(type);
// Datasize
ebml_size += kDateElementSize;
// Size of Datasize
ebml_size++;
return ebml_size;
}
int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size) {
if (!writer || size < 1 || size > 8)
return -1;
@ -321,6 +341,22 @@ bool WriteEbmlElement(IMkvWriter* writer,
return true;
}
bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value) {
if (!writer)
return false;
if (WriteID(writer, type))
return false;
if (WriteUInt(writer, kDateElementSize))
return false;
if (SerializeInt(writer, value, kDateElementSize))
return false;
return true;
}
uint64 WriteSimpleBlock(IMkvWriter* writer,
const uint8* data,
uint64 length,

View File

@ -30,6 +30,7 @@ uint64 EbmlElementSize(uint64 type, uint64 value);
uint64 EbmlElementSize(uint64 type, float value);
uint64 EbmlElementSize(uint64 type, const char* value);
uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size);
uint64 EbmlDateElementSize(uint64 type, int64 value);
// Creates an EBML coded number from |value| and writes it out. The size of
// the coded number is determined by the value of |value|. |value| must not
@ -56,6 +57,7 @@ bool WriteEbmlElement(IMkvWriter* writer,
uint64 type,
const uint8* value,
uint64 size);
bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value);
// Output an Mkv Simple Block.
// Inputs: