1a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// 3a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Use of this source code is governed by a BSD-style license 4a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// that can be found in the LICENSE file in the root of the source 5a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// tree. An additional intellectual property rights grant can be found 6a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// in the file PATENTS. All contributing project authors may 7a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// be found in the AUTHORS file in the root of the source tree. 8a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 9a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include "mkvmuxerutil.hpp" 10a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 11a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#ifdef __ANDROID__ 12a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include <fcntl.h> 13a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#endif 14a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 15a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include <cassert> 16a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include <cmath> 17a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include <cstdio> 18a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#ifdef _MSC_VER 19a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#define _CRT_RAND_S 20a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#endif 21a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include <cstdlib> 22a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include <cstring> 23a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include <ctime> 24a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 25a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include <new> 26a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 27a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include "mkvwriter.hpp" 28a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#include "webmids.hpp" 29a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 30a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramaniannamespace mkvmuxer { 31a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 32a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianint32 GetCodedUIntSize(uint64 value) { 33a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (value < 0x000000000000007FULL) 34a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 1; 35a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x0000000000003FFFULL) 36a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 2; 37a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x00000000001FFFFFULL) 38a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 3; 39a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x000000000FFFFFFFULL) 40a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 4; 41a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x00000007FFFFFFFFULL) 42a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 5; 43a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x000003FFFFFFFFFFULL) 44a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 6; 45a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x0001FFFFFFFFFFFFULL) 46a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 7; 47a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 8; 48a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 49a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 50a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianint32 GetUIntSize(uint64 value) { 51a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (value < 0x0000000000000100ULL) 52a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 1; 53a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x0000000000010000ULL) 54a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 2; 55a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x0000000001000000ULL) 56a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 3; 57a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x0000000100000000ULL) 58a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 4; 59a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x0000010000000000ULL) 60a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 5; 61a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x0001000000000000ULL) 62a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 6; 63a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian else if (value < 0x0100000000000000ULL) 64a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 7; 65a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 8; 66a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 67a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 68a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 EbmlMasterElementSize(uint64 type, uint64 value) { 69a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of EBML ID 70a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int32 ebml_size = GetUIntSize(type); 71a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 72a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Datasize 73a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size += GetCodedUIntSize(value); 74a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 75a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return ebml_size; 76a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 77a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 78a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 EbmlElementSize(uint64 type, int64 value) { 79a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return EbmlElementSize(type, static_cast<uint64>(value)); 80a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 81a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 82a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 EbmlElementSize(uint64 type, uint64 value) { 83a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of EBML ID 84a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int32 ebml_size = GetUIntSize(type); 85a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 86a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Datasize 87a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size += GetUIntSize(value); 88a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 89a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of Datasize 90a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size++; 91a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 92a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return ebml_size; 93a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 94a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 95a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 EbmlElementSize(uint64 type, float /* value */ ) { 96a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of EBML ID 97a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 ebml_size = GetUIntSize(type); 98a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 99a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Datasize 100a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size += sizeof(float); 101a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 102a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of Datasize 103a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size++; 104a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 105a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return ebml_size; 106a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 107a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 108a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 EbmlElementSize(uint64 type, const char* value) { 109a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!value) 110a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 111a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 112a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of EBML ID 113a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 ebml_size = GetUIntSize(type); 114a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 115a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Datasize 116a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size += strlen(value); 117a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 118a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of Datasize 119a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size++; 120a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 121a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return ebml_size; 122a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 123a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 124a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size) { 125a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!value) 126a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 127a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 128a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of EBML ID 129a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 ebml_size = GetUIntSize(type); 130a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 131a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Datasize 132a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size += size; 133a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 134a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Size of Datasize 135a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ebml_size += GetCodedUIntSize(size); 136a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 137a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return ebml_size; 138a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 139a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 140a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianint32 SerializeInt(IMkvWriter* writer, int64 value, int32 size) { 141a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer || size < 1 || size > 8) 142a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return -1; 143a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 144a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian for (int32 i = 1; i <= size; ++i) { 145a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 byte_count = size - i; 146a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 bit_count = byte_count * 8; 147a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 148a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int64 bb = value >> bit_count; 149a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8 b = static_cast<uint8>(bb); 150a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 151a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 status = writer->Write(&b, 1); 152a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 153a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (status < 0) 154a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return status; 155a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } 156a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 157a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 158a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 159a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 160a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianint32 SerializeFloat(IMkvWriter* writer, float f) { 161a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer) 162a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return -1; 163a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 164a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian assert(sizeof(uint32) == sizeof(float)); 165a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // This union is merely used to avoid a reinterpret_cast from float& to 166a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // uint32& which will result in violation of strict aliasing. 167a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian union U32 { 168a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint32 u32; 169a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian float f; 170a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } value; 171a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian value.f = f; 172a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 173a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian for (int32 i = 1; i <= 4; ++i) { 174a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 byte_count = 4 - i; 175a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 bit_count = byte_count * 8; 176a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 177a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8 byte = static_cast<uint8>(value.u32 >> bit_count); 178a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 179a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 status = writer->Write(&byte, 1); 180a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 181a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (status < 0) 182a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return status; 183a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } 184a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 185a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 186a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 187a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 188a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianint32 WriteUInt(IMkvWriter* writer, uint64 value) { 189a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer) 190a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return -1; 191a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 192a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int32 size = GetCodedUIntSize(value); 193a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 194a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return WriteUIntSize(writer, value, size); 195a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 196a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 197a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianint32 WriteUIntSize(IMkvWriter* writer, uint64 value, int32 size) { 198a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer || size < 0 || size > 8) 199a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return -1; 200a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 201a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (size > 0) { 202a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 bit = 1LL << (size * 7); 203a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 204a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (value > (bit - 2)) 205a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return -1; 206a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 207a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian value |= bit; 208a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } else { 209a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian size = 1; 210a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int64 bit; 211a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 212a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian for (;;) { 213a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian bit = 1LL << (size * 7); 214a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 max = bit - 2; 215a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 216a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (value <= max) 217a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian break; 218a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 219a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian ++size; 220a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } 221a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 222a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (size > 8) 223a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 224a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 225a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian value |= bit; 226a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } 227a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 228a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return SerializeInt(writer, value, size); 229a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 230a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 231a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianint32 WriteID(IMkvWriter* writer, uint64 type) { 232a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer) 233a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return -1; 234a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 235a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian writer->ElementStartNotify(type, writer->Position()); 236a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 237a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 size = GetUIntSize(type); 238a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 239a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return SerializeInt(writer, type, size); 240a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 241a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 242a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianbool WriteEbmlMasterElement(IMkvWriter* writer, uint64 type, uint64 size) { 243a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer) 244a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 245a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 246a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, type)) 247a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 248a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 249a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, size)) 250a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 251a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 252a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return true; 253a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 254a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 255a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianbool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value) { 256a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer) 257a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 258a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 259a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, type)) 260a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 261a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 262a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 size = GetUIntSize(value); 263a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, size)) 264a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 265a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 266a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, value, static_cast<int32>(size))) 267a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 268a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 269a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return true; 270a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 271a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 272a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianbool WriteEbmlElement(IMkvWriter* writer, uint64 type, float value) { 273a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer) 274a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 275a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 276a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, type)) 277a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 278a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 279a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, 4)) 280a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 281a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 282a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeFloat(writer, value)) 283a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 284a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 285a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return true; 286a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 287a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 288a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianbool WriteEbmlElement(IMkvWriter* writer, uint64 type, const char* value) { 289a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer || !value) 290a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 291a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 292a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, type)) 293a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 294a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 2956ac915abcdb404a00d927fe6308a47fcf09d9519hkuang const uint64 length = strlen(value); 296a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, length)) 297a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 298a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 2996ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if (writer->Write(value, static_cast<const uint32>(length))) 300a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 301a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 302a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return true; 303a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 304a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 305a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianbool WriteEbmlElement(IMkvWriter* writer, 306a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 type, 307a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8* value, 308a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 size) { 309a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer || !value || size < 1) 310a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 311a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 312a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, type)) 313a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 314a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 315a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, size)) 316a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 317a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 318a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (writer->Write(value, static_cast<uint32>(size))) 319a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 320a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 321a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return true; 322a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 323a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 324a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 WriteSimpleBlock(IMkvWriter* writer, 325a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8* data, 326a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 length, 327a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 track_number, 328a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int64 timecode, 329a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 is_key) { 330a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer) 331a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 332a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 333a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!data || length < 1) 334a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 335a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 336a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Here we only permit track number values to be no greater than 337a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // 126, which the largest value we can store having a Matroska 338a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // integer representation of only 1 byte. 339a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 340a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (track_number < 1 || track_number > 126) 341a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 342a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 343a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Technically the timestamp for a block can be less than the 344a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // timestamp for the cluster itself (remember that block timestamp 345a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // is a signed, 16-bit integer). However, as a simplification we 346a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // only permit non-negative cluster-relative timestamps for blocks. 347a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 348a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (timecode < 0 || timecode > kMaxBlockTimecode) 349a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 350a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 351a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, kMkvSimpleBlock)) 352a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 353a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 354a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 size = static_cast<int32>(length) + 4; 355a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, size)) 356a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 357a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 358a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, static_cast<uint64>(track_number))) 359a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 360a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 361a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, timecode, 2)) 362a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 363a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 364a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 flags = 0; 365a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (is_key) 366a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian flags |= 0x80; 367a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 368a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, flags, 1)) 369a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 370a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 371a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (writer->Write(data, static_cast<uint32>(length))) 372a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 373a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 374a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 element_size = 375a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian GetUIntSize(kMkvSimpleBlock) + GetCodedUIntSize(size) + 4 + length; 376a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 377a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return element_size; 378a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 379a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 380a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// We must write the metadata (key)frame as a BlockGroup element, 381a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// because we need to specify a duration for the frame. The 382a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockGroup element comprises the frame itself and its duration, 383a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// and is laid out as follows: 384a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// 385a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockGroup tag 386a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockGroup size 387a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Block tag 388a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Block size 389a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// (the frame is the block payload) 390a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Duration tag 391a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Duration size 392a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// (duration payload) 393a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// 394a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 WriteMetadataBlock(IMkvWriter* writer, 395a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8* data, 396a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 length, 397a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 track_number, 398a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int64 timecode, 399a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 duration) { 400a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // We don't backtrack when writing to the stream, so we must 401a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // pre-compute the BlockGroup size, by summing the sizes of each 402a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // sub-element (the block and the duration). 403a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 404a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // We use a single byte for the track number of the block, which 405a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // means the block header is exactly 4 bytes. 406a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 407a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // TODO(matthewjheaney): use EbmlMasterElementSize and WriteEbmlMasterElement 408a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 409a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_payload_size = 4 + length; 410a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 block_size = GetCodedUIntSize(block_payload_size); 411a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_elem_size = 1 + block_size + block_payload_size; 412a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 413a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 duration_payload_size = GetUIntSize(duration); 414a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 duration_size = GetCodedUIntSize(duration_payload_size); 415a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 duration_elem_size = 1 + duration_size + duration_payload_size; 416a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 417a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 blockg_payload_size = block_elem_size + duration_elem_size; 418a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 blockg_size = GetCodedUIntSize(blockg_payload_size); 419a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 blockg_elem_size = 1 + blockg_size + blockg_payload_size; 420a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 421a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, kMkvBlockGroup)) // 1-byte ID size 422a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 423a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 424a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, blockg_payload_size)) 425a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 426a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 427a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Write Block element 428a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 429a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, kMkvBlock)) // 1-byte ID size 430a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 431a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 432a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, block_payload_size)) 433a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 434a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 435a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Byte 1 of 4 436a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 437a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, track_number)) 438a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 439a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 440a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Bytes 2 & 3 of 4 441a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 442a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, timecode, 2)) 443a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 444a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 445a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Byte 4 of 4 446a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 447a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 flags = 0; 448a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 449a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, flags, 1)) 450a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 451a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 452a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Now write the actual frame (of metadata) 453a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 454a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (writer->Write(data, static_cast<uint32>(length))) 455a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 456a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 457a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Write Duration element 458a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 459a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, kMkvBlockDuration)) // 1-byte ID size 460a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 461a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 462a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, duration_payload_size)) 463a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 464a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 465a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, duration, duration_payload_size)) 466a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 467a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 468a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Note that we don't write a reference time as part of the block 469a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // group; no reference time(s) indicates that this block is a 470a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // keyframe. (Unlike the case for a SimpleBlock element, the header 471a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // bits of the Block sub-element of a BlockGroup element do not 472a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // indicate keyframe status. The keyframe status is inferred from 473a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // the absence of reference time sub-elements.) 474a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 475a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return blockg_elem_size; 476a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 477a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 478a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Writes a WebM BlockGroup with BlockAdditional data. The structure is as 479a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// follows: 480a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Indentation shows sub-levels 481a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockGroup 482a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Block 483a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Data 484a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockAdditions 485a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockMore 486a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockAddID 487a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// 1 (Denotes Alpha) 488a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockAdditional 489a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Data 490a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 WriteBlockWithAdditional(IMkvWriter* writer, 491a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8* data, 492a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 length, 493a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8* additional, 494a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 additional_length, 495a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 add_id, 496a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 track_number, 497a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int64 timecode, 498a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 is_key) { 499a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!data || !additional || length < 1 || additional_length < 1) 500a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 501a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 502a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_payload_size = 4 + length; 503a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_elem_size = EbmlMasterElementSize(kMkvBlock, 504a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_payload_size) + 505a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_payload_size; 506a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_additional_elem_size = EbmlElementSize(kMkvBlockAdditional, 507a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian additional, 508a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian additional_length); 509a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_addid_elem_size = EbmlElementSize(kMkvBlockAddID, add_id); 510a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 511a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_more_payload_size = block_addid_elem_size + 512a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_additional_elem_size; 513a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_more_elem_size = EbmlMasterElementSize( 514a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian kMkvBlockMore, 515a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_more_payload_size) + 516a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_more_payload_size; 517a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_additions_payload_size = block_more_elem_size; 518a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_additions_elem_size = EbmlMasterElementSize( 519a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian kMkvBlockAdditions, 520a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_additions_payload_size) + 521a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_additions_payload_size; 522a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_group_payload_size = block_elem_size + 523a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_additions_elem_size; 524a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_group_elem_size = EbmlMasterElementSize( 525a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian kMkvBlockGroup, 526a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_group_payload_size) + 527a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_group_payload_size; 528a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 529a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvBlockGroup, 530a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_group_payload_size)) 531a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 532a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 533a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvBlock, block_payload_size)) 534a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 535a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 536a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, track_number)) 537a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 538a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 539a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, timecode, 2)) 540a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 541a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 542a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 flags = 0; 543a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (is_key) 544a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian flags |= 0x80; 545a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, flags, 1)) 546a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 547a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 548a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (writer->Write(data, static_cast<uint32>(length))) 549a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 550a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 551a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvBlockAdditions, 552a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_additions_payload_size)) 553a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 554a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 555a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvBlockMore, block_more_payload_size)) 556a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 557a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 558a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvBlockAddID, add_id)) 559a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 560a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 561a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvBlockAdditional, 562a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian additional, additional_length)) 563a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 564a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 565a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return block_group_elem_size; 566a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 567a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 568a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Writes a WebM BlockGroup with DiscardPadding. The structure is as follows: 569a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Indentation shows sub-levels 570a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// BlockGroup 571a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Block 572a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// Data 573a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian// DiscardPadding 574a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 WriteBlockWithDiscardPadding(IMkvWriter* writer, 575a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8* data, 576a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 length, 577a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int64 discard_padding, 578a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 track_number, 579a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int64 timecode, 580a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 is_key) { 581a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!data || length < 1 || discard_padding <= 0) 582a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 583a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 584a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_payload_size = 4 + length; 585a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_elem_size = EbmlMasterElementSize(kMkvBlock, 586a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_payload_size) + 587a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_payload_size; 588a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 discard_padding_elem_size = EbmlElementSize(kMkvDiscardPadding, 589a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian discard_padding); 590a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_group_payload_size = block_elem_size + 591a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian discard_padding_elem_size; 592a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 block_group_elem_size = EbmlMasterElementSize( 593a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian kMkvBlockGroup, 594a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_group_payload_size) + 595a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_group_payload_size; 596a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 597a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvBlockGroup, 598a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian block_group_payload_size)) 599a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 600a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 601a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvBlock, block_payload_size)) 602a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 603a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 604a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, track_number)) 605a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 606a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 607a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, timecode, 2)) 608a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 609a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 610a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 flags = 0; 611a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (is_key) 612a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian flags |= 0x80; 613a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, flags, 1)) 614a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 615a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 616a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (writer->Write(data, static_cast<uint32>(length))) 617a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 618a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 619a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, kMkvDiscardPadding)) 620a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 621a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 622a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint64 size = GetUIntSize(discard_padding); 623a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, size)) 624a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 625a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 626a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (SerializeInt(writer, discard_padding, static_cast<int32>(size))) 627a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 628a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 629a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return block_group_elem_size; 630a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 631a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 632a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianuint64 WriteVoidElement(IMkvWriter* writer, uint64 size) { 633a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (!writer) 634a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return false; 635a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 636a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // Subtract one for the void ID and the coded size. 637a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 void_entry_size = size - 1 - GetCodedUIntSize(size-1); 638a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 void_size = EbmlMasterElementSize(kMkvVoid, void_entry_size) + 639a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian void_entry_size; 640a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 641a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (void_size != size) 642a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 643a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 644a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int64 payload_position = writer->Position(); 645a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (payload_position < 0) 646a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 647a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 648a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteID(writer, kMkvVoid)) 649a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 650a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 651a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (WriteUInt(writer, void_entry_size)) 652a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 653a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 654a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const uint8 value = 0; 655a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian for (int32 i = 0; i < static_cast<int32>(void_entry_size); ++i) { 656a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (writer->Write(&value, 1)) 657a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 658a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } 659a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 660a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int64 stop_position = writer->Position(); 661a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (stop_position < 0 || 662a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian stop_position - payload_position != static_cast<int64>(void_size)) 663a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return 0; 664a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 665a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return void_size; 666a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 667a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 668a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianvoid GetVersion(int32* major, int32* minor, int32* build, int32* revision) { 669a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian *major = 0; 670a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian *minor = 2; 671a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian *build = 1; 672a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian *revision = 0; 673a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 674a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 675a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} // namespace mkvmuxer 676a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 677a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianmkvmuxer::uint64 mkvmuxer::MakeUID(unsigned int* seed) { 678a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uint64 uid = 0; 679a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 680a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#ifdef __MINGW32__ 681a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian srand(*seed); 682a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#endif 683a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 684a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian for (int i = 0; i < 7; ++i) { // avoid problems with 8-byte values 685a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uid <<= 8; 686a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 687a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian // TODO(fgalligan): Move random number generation to platform specific code. 688a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#ifdef _MSC_VER 689a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian (void)seed; 690a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian unsigned int random_value; 691a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const errno_t e = rand_s(&random_value); 692a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian (void)e; 693a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 nn = random_value; 694a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#elif __ANDROID__ 695a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int32 temp_num = 1; 696a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian int fd = open("/dev/urandom", O_RDONLY); 697a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian if (fd != -1) { 698a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian read(fd, &temp_num, sizeof(int32)); 699a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian close(fd); 700a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } 701a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 nn = temp_num; 702a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#elif defined __MINGW32__ 703a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 nn = rand(); 704a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#else 705a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 nn = rand_r(seed); 706a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#endif 707a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian const int32 n = 0xFF & (nn >> 4); // throw away low-order bits 708a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 709a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian uid |= n; 710a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian } 711a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian 712a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian return uid; 713a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian} 714