15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/tracks_builder.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/logging.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/webm_constants.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace media { 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Returns size of an integer, formatted using Matroska serialization. 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static int GetUIntMkvSize(uint64 value) { 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x07FULL) 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 1; 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x03FFFULL) 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 2; 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x01FFFFFULL) 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 3; 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x0FFFFFFFULL) 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 4; 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x07FFFFFFFFULL) 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 5; 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x03FFFFFFFFFFULL) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 6; 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x01FFFFFFFFFFFFULL) 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 7; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 8; 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Returns the minimium size required to serialize an integer value. 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static int GetUIntSize(uint64 value) { 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x0100ULL) 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 1; 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x010000ULL) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 2; 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x01000000ULL) 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 3; 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x0100000000ULL) 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 4; 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x010000000000ULL) 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 5; 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x01000000000000ULL) 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 6; 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value < 0x0100000000000000ULL) 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 7; 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 8; 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static int MasterElementSize(int element_id, int payload_size) { 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return GetUIntSize(element_id) + GetUIntMkvSize(payload_size) + payload_size; 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static int UIntElementSize(int element_id, uint64 value) { 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return GetUIntSize(element_id) + 1 + GetUIntSize(value); 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstatic int DoubleElementSize(int element_id) { 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return GetUIntSize(element_id) + 1 + 8; 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static int StringElementSize(int element_id, const std::string& value) { 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return GetUIntSize(element_id) + 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetUIntMkvSize(value.length()) + 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) value.length(); 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void SerializeInt(uint8** buf_ptr, int* buf_size_ptr, 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 value, int size) { 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint8*& buf = *buf_ptr; 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int& buf_size = *buf_size_ptr; 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int idx = 1; idx <= size; ++idx) { 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *buf++ = static_cast<uint8>(value >> ((size - idx) * 8)); 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) --buf_size; 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstatic void SerializeDouble(uint8** buf_ptr, int* buf_size_ptr, 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch double value) { 81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Use a union to convert |value| to native endian integer bit pattern. 82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch union { 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch double src; 84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int64 dst; 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } tmp; 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch tmp.src = value; 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Write the bytes from native endian |tmp.dst| to big-endian form in |buf|. 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SerializeInt(buf_ptr, buf_size_ptr, tmp.dst, 8); 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void WriteElementId(uint8** buf, int* buf_size, int element_id) { 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SerializeInt(buf, buf_size, element_id, GetUIntSize(element_id)); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void WriteUInt(uint8** buf, int* buf_size, uint64 value) { 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int size = GetUIntMkvSize(value); 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) value |= (1ULL << (size * 7)); // Matroska formatting 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SerializeInt(buf, buf_size, value, size); 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void WriteMasterElement(uint8** buf, int* buf_size, 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int element_id, int payload_size) { 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteElementId(buf, buf_size, element_id); 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteUInt(buf, buf_size, payload_size); 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static void WriteUIntElement(uint8** buf, 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int* buf_size, 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int element_id, 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint64 value) { 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteElementId(buf, buf_size, element_id); 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int size = GetUIntSize(value); 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteUInt(buf, buf_size, size); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SerializeInt(buf, buf_size, value, size); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstatic void WriteDoubleElement(uint8** buf, int* buf_size, 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int element_id, double value) { 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WriteElementId(buf, buf_size, element_id); 123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WriteUInt(buf, buf_size, 8); 124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SerializeDouble(buf, buf_size, value); 125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void WriteStringElement(uint8** buf_ptr, int* buf_size_ptr, 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int element_id, const std::string& value) { 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint8*& buf = *buf_ptr; 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int& buf_size = *buf_size_ptr; 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteElementId(&buf, &buf_size, element_id); 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const uint64 size = value.length(); 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteUInt(&buf, &buf_size, size); 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memcpy(buf, value.data(), size); 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) buf += size; 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) buf_size -= size; 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 142effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTracksBuilder::TracksBuilder(bool allow_invalid_values) 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : allow_invalid_values_(allow_invalid_values) {} 144effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTracksBuilder::TracksBuilder() 145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : allow_invalid_values_(false) {} 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TracksBuilder::~TracksBuilder() {} 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TracksBuilder::AddVideoTrack(int track_num, 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint64 track_uid, 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& codec_id, 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& name, 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& language, 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int default_duration, 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int video_pixel_width, 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int video_pixel_height) { 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddTrackInternal(track_num, kWebMTrackTypeVideo, track_uid, codec_id, name, 157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch language, default_duration, video_pixel_width, 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch video_pixel_height, -1, -1); 159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TracksBuilder::AddAudioTrack(int track_num, 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint64 track_uid, 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& codec_id, 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& name, 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& language, 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int default_duration, 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int audio_channels, 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) double audio_sampling_frequency) { 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddTrackInternal(track_num, kWebMTrackTypeAudio, track_uid, codec_id, name, 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch language, default_duration, -1, -1, audio_channels, 171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch audio_sampling_frequency); 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TracksBuilder::AddTextTrack(int track_num, 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint64 track_uid, 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& codec_id, 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& name, 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& language) { 179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddTrackInternal(track_num, kWebMTrackTypeSubtitlesOrCaptions, track_uid, 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch codec_id, name, language, -1, -1, -1, -1, -1); 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::vector<uint8> TracksBuilder::Finish() { 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Allocate the storage 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<uint8> buffer; 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) buffer.resize(GetTracksSize()); 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Populate the storage with a tracks header 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteTracks(&buffer[0], buffer.size()); 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return buffer; 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void TracksBuilder::AddTrackInternal(int track_num, 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int track_type, 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint64 track_uid, 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& codec_id, 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& name, 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& language, 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int default_duration, 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int video_pixel_width, 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int video_pixel_height, 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int audio_channels, 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) double audio_sampling_frequency) { 205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch tracks_.push_back(Track(track_num, track_type, track_uid, codec_id, name, 206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch language, default_duration, video_pixel_width, 207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch video_pixel_height, audio_channels, 208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch audio_sampling_frequency, allow_invalid_values_)); 209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int TracksBuilder::GetTracksSize() const { 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return MasterElementSize(kWebMIdTracks, GetTracksPayloadSize()); 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int TracksBuilder::GetTracksPayloadSize() const { 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int payload_size = 0; 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (TrackList::const_iterator itr = tracks_.begin(); 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) itr != tracks_.end(); ++itr) { 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) payload_size += itr->GetSize(); 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return payload_size; 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TracksBuilder::WriteTracks(uint8* buf, int buf_size) const { 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteMasterElement(&buf, &buf_size, kWebMIdTracks, GetTracksPayloadSize()); 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (TrackList::const_iterator itr = tracks_.begin(); 23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) itr != tracks_.end(); ++itr) { 23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) itr->Write(&buf, &buf_size); 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TracksBuilder::Track::Track(int track_num, 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int track_type, 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint64 track_uid, 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& codec_id, 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& name, 240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& language, 241effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int default_duration, 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int video_pixel_width, 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int video_pixel_height, 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int audio_channels, 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) double audio_sampling_frequency, 246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool allow_invalid_values) 24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : track_num_(track_num), 24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) track_type_(track_type), 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) track_uid_(track_uid), 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) codec_id_(codec_id), 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) name_(name), 252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch language_(language), 253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch default_duration_(default_duration), 254effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch video_pixel_width_(video_pixel_width), 255effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch video_pixel_height_(video_pixel_height), 256effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch audio_channels_(audio_channels), 257effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch audio_sampling_frequency_(audio_sampling_frequency) { 258effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!allow_invalid_values) { 259effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(track_num_, 0); 260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(track_type_, 0); 261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_LT(track_type_, 255); 262effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(track_uid_, 0); 263effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (track_type != kWebMTrackTypeVideo && 264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch track_type != kWebMTrackTypeAudio) { 265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_EQ(default_duration_, -1); 266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK(default_duration_ == -1 || default_duration_ > 0); 268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (track_type == kWebMTrackTypeVideo) { 271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(video_pixel_width_, 0); 272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(video_pixel_height_, 0); 273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_EQ(video_pixel_width_, -1); 275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_EQ(video_pixel_height_, -1); 276effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 277effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 278effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (track_type == kWebMTrackTypeAudio) { 279effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(audio_channels_, 0); 280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_GT(audio_sampling_frequency_, 0.0); 281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_EQ(audio_channels_, -1); 283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CHECK_EQ(audio_sampling_frequency_, -1.0); 284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int TracksBuilder::Track::GetSize() const { 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return MasterElementSize(kWebMIdTrackEntry, GetPayloadSize()); 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochint TracksBuilder::Track::GetVideoPayloadSize() const { 293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int payload_size = 0; 294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (video_pixel_width_ >= 0) 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) payload_size += UIntElementSize(kWebMIdPixelWidth, video_pixel_width_); 297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (video_pixel_height_ >= 0) 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) payload_size += UIntElementSize(kWebMIdPixelHeight, video_pixel_height_); 299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 300effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return payload_size; 301effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 302effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 303effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochint TracksBuilder::Track::GetAudioPayloadSize() const { 304effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int payload_size = 0; 305effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 306effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (audio_channels_ >= 0) 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) payload_size += UIntElementSize(kWebMIdChannels, audio_channels_); 308effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (audio_sampling_frequency_ >= 0) 309effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch payload_size += DoubleElementSize(kWebMIdSamplingFrequency); 310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 311effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return payload_size; 312effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 313effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int TracksBuilder::Track::GetPayloadSize() const { 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int size = 0; 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size += UIntElementSize(kWebMIdTrackNumber, track_num_); 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size += UIntElementSize(kWebMIdTrackType, track_type_); 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size += UIntElementSize(kWebMIdTrackUID, track_uid_); 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 321effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (default_duration_ >= 0) 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size += UIntElementSize(kWebMIdDefaultDuration, default_duration_); 323effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!codec_id_.empty()) 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size += StringElementSize(kWebMIdCodecID, codec_id_); 32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!name_.empty()) 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size += StringElementSize(kWebMIdName, name_); 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!language_.empty()) 33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size += StringElementSize(kWebMIdLanguage, language_); 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 333effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (GetVideoPayloadSize() > 0) { 334effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size += MasterElementSize(kWebMIdVideo, GetVideoPayloadSize()); 335effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 336effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (GetAudioPayloadSize() > 0) { 338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size += MasterElementSize(kWebMIdAudio, GetAudioPayloadSize()); 339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 340effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return size; 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TracksBuilder::Track::Write(uint8** buf, int* buf_size) const { 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteMasterElement(buf, buf_size, kWebMIdTrackEntry, GetPayloadSize()); 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WriteUIntElement(buf, buf_size, kWebMIdTrackNumber, track_num_); 3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WriteUIntElement(buf, buf_size, kWebMIdTrackType, track_type_); 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WriteUIntElement(buf, buf_size, kWebMIdTrackUID, track_uid_); 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 351effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (default_duration_ >= 0) 3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WriteUIntElement(buf, buf_size, kWebMIdDefaultDuration, default_duration_); 353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!codec_id_.empty()) 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteStringElement(buf, buf_size, kWebMIdCodecID, codec_id_); 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!name_.empty()) 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteStringElement(buf, buf_size, kWebMIdName, name_); 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!language_.empty()) 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteStringElement(buf, buf_size, kWebMIdLanguage, language_); 362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (GetVideoPayloadSize() > 0) { 364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WriteMasterElement(buf, buf_size, kWebMIdVideo, GetVideoPayloadSize()); 365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (video_pixel_width_ >= 0) 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WriteUIntElement(buf, buf_size, kWebMIdPixelWidth, video_pixel_width_); 368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (video_pixel_height_ >= 0) 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WriteUIntElement(buf, buf_size, kWebMIdPixelHeight, video_pixel_height_); 371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (GetAudioPayloadSize() > 0) { 374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WriteMasterElement(buf, buf_size, kWebMIdAudio, GetAudioPayloadSize()); 375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (audio_channels_ >= 0) 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WriteUIntElement(buf, buf_size, kWebMIdChannels, audio_channels_); 378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (audio_sampling_frequency_ >= 0) { 380effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WriteDoubleElement(buf, buf_size, kWebMIdSamplingFrequency, 381effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch audio_sampling_frequency_); 382effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 383effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace media 387