Index: media/formats/webm/tracks_builder.cc |
diff --git a/media/formats/webm/tracks_builder.cc b/media/formats/webm/tracks_builder.cc |
index 5a49ce05f4f49b6a2b8fdd4dbd593a8ddd33057e..bc59d028a64082c9ab898297563438b6c80a5afa 100644 |
--- a/media/formats/webm/tracks_builder.cc |
+++ b/media/formats/webm/tracks_builder.cc |
@@ -54,6 +54,10 @@ static int IntElementSize(int element_id, int value) { |
return GetUIntSize(element_id) + 1 + GetUIntSize(value); |
} |
+static int DoubleElementSize(int element_id) { |
+ return GetUIntSize(element_id) + 1 + 8; |
+} |
+ |
static int StringElementSize(int element_id, const std::string& value) { |
return GetUIntSize(element_id) + |
GetUIntMkvSize(value.length()) + |
@@ -71,6 +75,26 @@ static void SerializeInt(uint8** buf_ptr, int* buf_size_ptr, |
} |
} |
+static void SerializeDouble(uint8** buf_ptr, int* buf_size_ptr, |
+ double value) { |
+ uint8*& buf = *buf_ptr; |
+ int& buf_size = *buf_size_ptr; |
+ |
+ // Use a union to convert |value| to native endian integer bit pattern. |
+ union { |
+ double src; |
+ int64 dst; |
+ } tmp; |
+ tmp.src = value; |
+ int64 pattern = tmp.dst; |
+ |
+ // Write the bytes from native endian |pattern| to big-endian form in buf. |
+ for (int idx = 1; idx <= 8; ++idx) { |
acolwell GONE FROM CHROMIUM
2014/03/26 22:25:32
nit: How about SerializeInt(buf_ptr, buf_size_ptr,
wolenetz
2014/03/27 01:21:43
Nice. Done.
|
+ *buf++ = static_cast<uint8>(pattern >> ((8 - idx) * 8)); |
+ --buf_size; |
+ } |
+} |
+ |
static void WriteElementId(uint8** buf, int* buf_size, int element_id) { |
SerializeInt(buf, buf_size, element_id, GetUIntSize(element_id)); |
} |
@@ -97,6 +121,13 @@ static void WriteIntElement(uint8** buf, int* buf_size, |
SerializeInt(buf, buf_size, value, size); |
} |
+static void WriteDoubleElement(uint8** buf, int* buf_size, |
+ int element_id, double value) { |
+ WriteElementId(buf, buf_size, element_id); |
+ WriteUInt(buf, buf_size, 8); |
+ SerializeDouble(buf, buf_size, value); |
+} |
+ |
static void WriteStringElement(uint8** buf_ptr, int* buf_size_ptr, |
int element_id, const std::string& value) { |
uint8*& buf = *buf_ptr; |
@@ -121,9 +152,16 @@ void TracksBuilder::AddTrack( |
int track_uid, |
const std::string& codec_id, |
const std::string& name, |
- const std::string& language) { |
+ const std::string& language, |
+ int default_duration, |
+ int video_pixel_width, |
+ int video_pixel_height, |
+ int audio_channels, |
+ double audio_sampling_frequency) { |
tracks_.push_back(Track(track_num, track_type, track_uid, codec_id, name, |
- language)); |
+ language, default_duration, video_pixel_width, |
+ video_pixel_height, audio_channels, |
+ audio_sampling_frequency)); |
} |
std::vector<uint8> TracksBuilder::Finish() { |
@@ -164,19 +202,49 @@ void TracksBuilder::WriteTracks(uint8* buf, int buf_size) const { |
TracksBuilder::Track::Track(int track_num, int track_type, int track_uid, |
const std::string& codec_id, |
const std::string& name, |
- const std::string& language) |
+ const std::string& language, |
+ int default_duration, |
+ int video_pixel_width, int video_pixel_height, |
+ int audio_channels, double audio_sampling_frequency) |
: track_num_(track_num), |
track_type_(track_type), |
track_uid_(track_uid), |
codec_id_(codec_id), |
name_(name), |
- language_(language) { |
+ language_(language), |
+ default_duration_(default_duration), |
+ video_pixel_width_(video_pixel_width), |
+ video_pixel_height_(video_pixel_height), |
+ audio_channels_(audio_channels), |
+ audio_sampling_frequency_(audio_sampling_frequency) { |
} |
int TracksBuilder::Track::GetSize() const { |
return MasterElementSize(kWebMIdTrackEntry, GetPayloadSize()); |
} |
+int TracksBuilder::Track::GetVideoPayloadSize() const { |
acolwell GONE FROM CHROMIUM
2014/03/26 22:25:32
nit: s/Payload/Element to match other naming here
wolenetz
2014/03/27 01:21:43
Hmm. I thought PayloadSize refers to the contents
|
+ int payload_size = 0; |
+ |
+ if (video_pixel_width_ >= 0) |
+ payload_size += IntElementSize(kWebMIdPixelWidth, video_pixel_width_); |
+ if (video_pixel_height_ >= 0) |
+ payload_size += IntElementSize(kWebMIdPixelHeight, video_pixel_height_); |
+ |
+ return payload_size; |
+} |
+ |
+int TracksBuilder::Track::GetAudioPayloadSize() const { |
acolwell GONE FROM CHROMIUM
2014/03/26 22:25:32
ditto
wolenetz
2014/03/27 01:21:43
ditto (confirmed offline that s/Payload/Element/ i
|
+ int payload_size = 0; |
+ |
+ if (audio_channels_ >= 0) |
+ payload_size += IntElementSize(kWebMIdChannels, audio_channels_); |
+ if (audio_sampling_frequency_ >= 0) |
+ payload_size += DoubleElementSize(kWebMIdSamplingFrequency); |
+ |
+ return payload_size; |
+} |
+ |
int TracksBuilder::Track::GetPayloadSize() const { |
int size = 0; |
@@ -184,6 +252,9 @@ int TracksBuilder::Track::GetPayloadSize() const { |
size += IntElementSize(kWebMIdTrackType, track_type_); |
size += IntElementSize(kWebMIdTrackUID, track_uid_); |
+ if (default_duration_ >= 0) |
+ size += IntElementSize(kWebMIdDefaultDuration, default_duration_); |
+ |
if (!codec_id_.empty()) |
size += StringElementSize(kWebMIdCodecID, codec_id_); |
@@ -193,6 +264,14 @@ int TracksBuilder::Track::GetPayloadSize() const { |
if (!language_.empty()) |
size += StringElementSize(kWebMIdLanguage, language_); |
+ if (GetVideoPayloadSize() > 0) { |
+ size += MasterElementSize(kWebMIdVideo, GetVideoPayloadSize()); |
+ } |
+ |
+ if (GetAudioPayloadSize() > 0) { |
+ size += MasterElementSize(kWebMIdAudio, GetAudioPayloadSize()); |
+ } |
+ |
return size; |
} |
@@ -203,6 +282,9 @@ void TracksBuilder::Track::Write(uint8** buf, int* buf_size) const { |
WriteIntElement(buf, buf_size, kWebMIdTrackType, track_type_); |
WriteIntElement(buf, buf_size, kWebMIdTrackUID, track_uid_); |
+ if (default_duration_ >= 0) |
acolwell GONE FROM CHROMIUM
2014/03/26 22:25:32
I wonder if we should have a "strict mode" that as
wolenetz
2014/03/27 01:21:43
Done (see new TracksBuilder |allow_invalid_values_
|
+ WriteIntElement(buf, buf_size, kWebMIdDefaultDuration, default_duration_); |
+ |
if (!codec_id_.empty()) |
WriteStringElement(buf, buf_size, kWebMIdCodecID, codec_id_); |
@@ -211,6 +293,28 @@ void TracksBuilder::Track::Write(uint8** buf, int* buf_size) const { |
if (!language_.empty()) |
WriteStringElement(buf, buf_size, kWebMIdLanguage, language_); |
+ |
+ if (GetVideoPayloadSize() > 0) { |
+ WriteMasterElement(buf, buf_size, kWebMIdVideo, GetVideoPayloadSize()); |
+ |
+ if (video_pixel_width_ >= 0) |
+ WriteIntElement(buf, buf_size, kWebMIdPixelWidth, video_pixel_width_); |
+ |
+ if (video_pixel_height_ >= 0) |
+ WriteIntElement(buf, buf_size, kWebMIdPixelHeight, video_pixel_height_); |
+ } |
+ |
+ if (GetAudioPayloadSize() > 0) { |
+ WriteMasterElement(buf, buf_size, kWebMIdAudio, GetAudioPayloadSize()); |
+ |
+ if (audio_channels_ >= 0) |
+ WriteIntElement(buf, buf_size, kWebMIdChannels, audio_channels_); |
+ |
+ if (audio_sampling_frequency_ >= 0) { |
+ WriteDoubleElement(buf, buf_size, kWebMIdSamplingFrequency, |
+ audio_sampling_frequency_); |
+ } |
+ } |
} |
} // namespace media |