12ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Copyright (c) 2012 The WebM project authors. All Rights Reserved. 22ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 32ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Use of this source code is governed by a BSD-style license 42ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// that can be found in the LICENSE file in the root of the source 52ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// tree. An additional intellectual property rights grant can be found 62ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// in the file PATENTS. All contributing project authors may 72ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// be found in the AUTHORS file in the root of the source tree. 82ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 92ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "mkvmuxer.hpp" 102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <climits> 122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cstdio> 132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cstdlib> 142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cstring> 152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <ctime> 162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <new> 172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "mkvmuxerutil.hpp" 192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "mkvparser.hpp" 202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "mkvwriter.hpp" 212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "webmids.hpp" 222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Disable MSVC warnings that suggest making code non-portable. 25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#pragma warning(disable : 4996) 262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramaniannamespace mkvmuxer { 292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramaniannamespace { 312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Deallocate the string designated by |dst|, and then copy the |src| 322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// string to |dst|. The caller owns both the |src| string and the 332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// |dst| copy (hence the caller is responsible for eventually 342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// deallocating the strings, either directly, or indirectly via 352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// StrCpy). Returns true if the source string was successfully copied 362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// to the destination. 372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool StrCpy(const char* src, char** dst_ptr) { 382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (dst_ptr == NULL) 392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char*& dst = *dst_ptr; 422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] dst; 442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst = NULL; 452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (src == NULL) 472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t size = strlen(src) + 1; 502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst = new (std::nothrow) char[size]; // NOLINT 522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (dst == NULL) 532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(dst, src); // NOLINT 562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} // namespace 592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// IMkvWriter Class 632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianIMkvWriter::IMkvWriter() {} 652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 66ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianIMkvWriter::~IMkvWriter() {} 672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool WriteEbmlHeader(IMkvWriter* writer) { 692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Level 0 702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = EbmlElementSize(kMkvEBMLVersion, 1ULL); 712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvEBMLReadVersion, 1ULL); 722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvEBMLMaxIDLength, 4ULL); 732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvEBMLMaxSizeLength, 8ULL); 742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvDocType, "webm"); 752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvDocTypeVersion, 2ULL); 762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvDocTypeReadVersion, 2ULL); 772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvEBML, size)) 792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvEBMLVersion, 1ULL)) 812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvEBMLReadVersion, 1ULL)) 832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvEBMLMaxIDLength, 4ULL)) 852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvEBMLMaxSizeLength, 8ULL)) 872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvDocType, "webm")) 892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvDocTypeVersion, 2ULL)) 912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvDocTypeReadVersion, 2ULL)) 932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool ChunkedCopy(mkvparser::IMkvReader* source, mkvmuxer::IMkvWriter* dst, 992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian mkvmuxer::int64 start, int64 size) { 1002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(vigneshv): Check if this is a reasonable value. 1012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint32 kBufSize = 2048; 1022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint8* buf = new uint8[kBufSize]; 1032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int64 offset = start; 1042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (size > 0) { 1052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 read_len = (size > kBufSize) ? kBufSize : size; 1062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (source->Read(offset, static_cast<long>(read_len), buf)) 1072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->Write(buf, static_cast<uint32>(read_len)); 1092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian offset += read_len; 1102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size -= read_len; 1112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete[] buf; 1132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 1142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 1172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 1182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Frame Class 1192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianFrame::Frame() 1212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : add_id_(0), 1222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian additional_(NULL), 1232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian additional_length_(0), 1242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian duration_(0), 1252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame_(NULL), 1262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian is_key_(false), 1272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian length_(0), 1282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_number_(0), 1292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian timestamp_(0), 130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian discard_padding_(0) {} 1312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianFrame::~Frame() { 133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] frame_; 134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] additional_; 1352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Frame::Init(const uint8* frame, uint64 length) { 1382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint8* const data = 1392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new (std::nothrow) uint8[static_cast<size_t>(length)]; // NOLINT 1402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!data) 1412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] frame_; 1442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame_ = data; 1452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian length_ = length; 1462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy(frame_, frame, static_cast<size_t>(length_)); 1482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 1492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Frame::AddAdditionalData(const uint8* additional, uint64 length, 1522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 add_id) { 1532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint8* const data = 1542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new (std::nothrow) uint8[static_cast<size_t>(length)]; // NOLINT 1552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!data) 1562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] additional_; 1592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian additional_ = data; 1602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian additional_length_ = length; 1612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian add_id_ = add_id; 1622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy(additional_, additional, static_cast<size_t>(additional_length_)); 1642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 1652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 1682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 1692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// CuePoint Class 1702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianCuePoint::CuePoint() 1722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : time_(0), 1732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_(0), 1742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_pos_(0), 1752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian block_number_(1), 176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian output_block_number_(true) {} 1772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCuePoint::~CuePoint() {} 1792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool CuePoint::Write(IMkvWriter* writer) const { 1812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer || track_ < 1 || cluster_pos_ < 1) 1822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = EbmlElementSize(kMkvCueClusterPosition, cluster_pos_); 1852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCueTrack, track_); 1862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_block_number_ && block_number_ > 1) 1872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCueBlockNumber, block_number_); 188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 track_pos_size = 189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvCueTrackPositions, size) + size; 190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 payload_size = 191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvCueTime, time_) + track_pos_size; 1922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvCuePoint, payload_size)) 1942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 1972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 1982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvCueTime, time_)) 2012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvCueTrackPositions, size)) 2042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvCueTrack, track_)) 2062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvCueClusterPosition, cluster_pos_)) 2082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_block_number_ && block_number_ > 1) 2102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvCueBlockNumber, block_number_)) 2112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop_position = writer->Position(); 2142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0) 2152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position - payload_position != static_cast<int64>(payload_size)) 2182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 2212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 CuePoint::PayloadSize() const { 2242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = EbmlElementSize(kMkvCueClusterPosition, cluster_pos_); 2252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCueTrack, track_); 2262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_block_number_ && block_number_ > 1) 2272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCueBlockNumber, block_number_); 228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 track_pos_size = 229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvCueTrackPositions, size) + size; 230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 payload_size = 231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvCueTime, time_) + track_pos_size; 2322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return payload_size; 2342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 CuePoint::Size() const { 2372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 payload_size = PayloadSize(); 2382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return EbmlMasterElementSize(kMkvCuePoint, payload_size) + payload_size; 2392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 2422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 2432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Cues Class 2442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianCues::Cues() 2462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : cue_entries_capacity_(0), 2472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_size_(0), 2482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_(NULL), 249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian output_block_number_(true) {} 2502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianCues::~Cues() { 2522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cue_entries_) { 2532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cue_entries_size_; ++i) { 2542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian CuePoint* const cue = cue_entries_[i]; 2552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete cue; 2562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] cue_entries_; 2582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cues::AddCue(CuePoint* cue) { 2622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cue) 2632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if ((cue_entries_size_ + 1) > cue_entries_capacity_) { 2662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Add more CuePoints. 2672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int32 new_capacity = 2682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian (!cue_entries_capacity_) ? 2 : cue_entries_capacity_ * 2; 2692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_capacity < 1) 2712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian CuePoint** const cues = 274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new (std::nothrow) CuePoint* [new_capacity]; // NOLINT 2752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues) 2762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cue_entries_size_; ++i) { 2792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues[i] = cue_entries_[i]; 2802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] cue_entries_; 2832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_ = cues; 2852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_capacity_ = new_capacity; 2862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_output_block_number(output_block_number_); 2892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_[cue_entries_size_++] = cue; 2902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 2912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianCuePoint* Cues::GetCueByIndex(int32 index) const { 2942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cue_entries_ == NULL) 2952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 2962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index >= cue_entries_size_) 2982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 2992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return cue_entries_[index]; 3012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 Cues::Size() { 3042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = 0; 3052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cue_entries_size_; ++i) 3062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += GetCueByIndex(i)->Size(); 3072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlMasterElementSize(kMkvCues, size); 3082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 3092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cues::Write(IMkvWriter* writer) const { 3122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer) 3132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = 0; 3162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cue_entries_size_; ++i) { 3172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const CuePoint* const cue = GetCueByIndex(i); 3182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cue) 3202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += cue->Size(); 3232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 3242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvCues, size)) 3262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 3292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 3302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cue_entries_size_; ++i) { 3332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const CuePoint* const cue = GetCueByIndex(i); 3342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cue->Write(writer)) 3362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 3382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop_position = writer->Position(); 3402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0) 3412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position - payload_position != static_cast<int64>(size)) 3442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 3472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 3502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 3512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ContentEncAESSettings Class 3522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncAESSettings::ContentEncAESSettings() : cipher_mode_(kCTR) {} 3542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 ContentEncAESSettings::Size() const { 3562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 payload = PayloadSize(); 3572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 size = 3582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvContentEncAESSettings, payload) + payload; 3592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 3602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool ContentEncAESSettings::Write(IMkvWriter* writer) const { 3632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 payload = PayloadSize(); 3642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvContentEncAESSettings, payload)) 3662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 3692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 3702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvAESSettingsCipherMode, cipher_mode_)) 3732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop_position = writer->Position(); 3762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 3772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position - payload_position != static_cast<int64>(payload)) 3782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 3812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 ContentEncAESSettings::PayloadSize() const { 3842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = EbmlElementSize(kMkvAESSettingsCipherMode, cipher_mode_); 3852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 3862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 3892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 3902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ContentEncoding Class 3912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding::ContentEncoding() 3932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : enc_algo_(5), 3942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enc_key_id_(NULL), 3952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_order_(0), 3962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_scope_(1), 3972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_type_(1), 398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enc_key_id_length_(0) {} 3992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianContentEncoding::~ContentEncoding() { delete[] enc_key_id_; } 4012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool ContentEncoding::SetEncryptionID(const uint8* id, uint64 length) { 4032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!id || length < 1) 4042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] enc_key_id_; 4072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enc_key_id_ = 4092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new (std::nothrow) uint8[static_cast<size_t>(length)]; // NOLINT 4102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!enc_key_id_) 4112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy(enc_key_id_, id, static_cast<size_t>(length)); 4142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enc_key_id_length_ = length; 4152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 4172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 ContentEncoding::Size() const { 4202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 encryption_size = EncryptionSize(); 4212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 encoding_size = EncodingSize(0, encryption_size); 422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 encodings_size = 423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvContentEncoding, encoding_size) + encoding_size; 4242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return encodings_size; 4262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool ContentEncoding::Write(IMkvWriter* writer) const { 4292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 encryption_size = EncryptionSize(); 4302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 encoding_size = EncodingSize(0, encryption_size); 431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 size = 432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvContentEncoding, encoding_size) + encoding_size; 4332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 4352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 4362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvContentEncoding, encoding_size)) 4392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvContentEncodingOrder, encoding_order_)) 4412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvContentEncodingScope, encoding_scope_)) 4432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvContentEncodingType, encoding_type_)) 4452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvContentEncryption, encryption_size)) 4482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvContentEncAlgo, enc_algo_)) 4502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvContentEncKeyID, enc_key_id_, 4522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enc_key_id_length_)) 4532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!enc_aes_settings_.Write(writer)) 4562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop_position = writer->Position(); 4592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 4602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position - payload_position != static_cast<int64>(size)) 4612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 4642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 ContentEncoding::EncodingSize(uint64 compresion_size, 4672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 encryption_size) const { 4682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(fgalligan): Add support for compression settings. 4692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (compresion_size != 0) 4702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 4712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 encoding_size = 0; 4732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (encryption_size > 0) { 475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian encoding_size += 476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvContentEncryption, encryption_size) + 477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian encryption_size; 4782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 4792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_size += EbmlElementSize(kMkvContentEncodingType, encoding_type_); 4802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_size += EbmlElementSize(kMkvContentEncodingScope, encoding_scope_); 4812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_size += EbmlElementSize(kMkvContentEncodingOrder, encoding_order_); 4822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return encoding_size; 4842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 ContentEncoding::EncryptionSize() const { 4872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 aes_size = enc_aes_settings_.Size(); 4882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 encryption_size = 490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvContentEncKeyID, enc_key_id_, enc_key_id_length_); 4912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption_size += EbmlElementSize(kMkvContentEncAlgo, enc_algo_); 4922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return encryption_size + aes_size; 4942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 4972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 4982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Track Class 4992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTrack::Track(unsigned int* seed) 5012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : codec_id_(NULL), 5022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_(NULL), 5032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian language_(NULL), 5042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_block_additional_id_(0), 5052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian name_(NULL), 5062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian number_(0), 5072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian type_(0), 5082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uid_(MakeUID(seed)), 5092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_delay_(0), 5102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_pre_roll_(0), 511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian default_duration_(0), 5122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_length_(0), 5132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_(NULL), 514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian content_encoding_entries_size_(0) {} 5152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTrack::~Track() { 517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codec_id_; 518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codec_private_; 519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] language_; 520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] name_; 5212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (content_encoding_entries_) { 5232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < content_encoding_entries_size_; ++i) { 5242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const encoding = content_encoding_entries_[i]; 5252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete encoding; 5262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] content_encoding_entries_; 5282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 5292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 5302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Track::AddContentEncoding() { 5322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint32 count = content_encoding_entries_size_ + 1; 5332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding** const content_encoding_entries = 535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new (std::nothrow) ContentEncoding* [count]; // NOLINT 5362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!content_encoding_entries) 5372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const content_encoding = 5402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new (std::nothrow) ContentEncoding(); // NOLINT 5412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!content_encoding) { 542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] content_encoding_entries; 5432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 5452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < content_encoding_entries_size_; ++i) { 5472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries[i] = content_encoding_entries_[i]; 5482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 5492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] content_encoding_entries_; 5512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_ = content_encoding_entries; 5532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_[content_encoding_entries_size_] = content_encoding; 5542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_size_ = count; 5552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 5562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 5572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding* Track::GetContentEncodingByIndex(uint32 index) const { 5592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (content_encoding_entries_ == NULL) 5602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 5612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index >= content_encoding_entries_size_) 5632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 5642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return content_encoding_entries_[index]; 5662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 5672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 Track::PayloadSize() const { 5692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = EbmlElementSize(kMkvTrackNumber, number_); 5702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvTrackUID, uid_); 5712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvTrackType, type_); 5722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id_) 5732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCodecID, codec_id_); 5742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_private_) 575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCodecPrivate, codec_private_, 5762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_length_); 5772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) 5782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvLanguage, language_); 5792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name_) 5802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvName, name_); 5812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_block_additional_id_) 5822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvMaxBlockAdditionID, max_block_additional_id_); 5832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_delay_) 5842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCodecDelay, codec_delay_); 5852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_pre_roll_) 5862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvSeekPreRoll, seek_pre_roll_); 587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (default_duration_) 588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += EbmlElementSize(kMkvDefaultDuration, default_duration_); 5892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (content_encoding_entries_size_ > 0) { 5912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 content_encodings_size = 0; 5922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < content_encoding_entries_size_; ++i) { 5932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const encoding = content_encoding_entries_[i]; 5942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encodings_size += encoding->Size(); 5952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 5962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += 598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvContentEncodings, content_encodings_size) + 599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian content_encodings_size; 6002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 6032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 6042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 Track::Size() const { 6062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = PayloadSize(); 6072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlMasterElementSize(kMkvTrackEntry, size); 6082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 6092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 6102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Track::Write(IMkvWriter* writer) const { 6122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer) 6132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // |size| may be bigger than what is written out in this function because 6162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // derived classes may write out more data in the Track element. 6172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 payload_size = PayloadSize(); 6182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvTrackEntry, payload_size)) 6202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // |type_| has to be specified before the Track can be written. 623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!type_) 624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 6262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = EbmlElementSize(kMkvTrackNumber, number_); 6272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvTrackUID, uid_); 6282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvTrackType, type_); 6292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id_) 6302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCodecID, codec_id_); 6312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_private_) 632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCodecPrivate, codec_private_, 6332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_length_); 6342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) 6352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvLanguage, language_); 6362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name_) 6372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvName, name_); 6382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_block_additional_id_) 6392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvMaxBlockAdditionID, max_block_additional_id_); 6402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_delay_) 6412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvCodecDelay, codec_delay_); 6422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_pre_roll_) 6432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvSeekPreRoll, seek_pre_roll_); 644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (default_duration_) 645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += EbmlElementSize(kMkvDefaultDuration, default_duration_); 6462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 6482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 6492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvTrackNumber, number_)) 6522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvTrackUID, uid_)) 6542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvTrackType, type_)) 6562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_block_additional_id_) { 658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvMaxBlockAdditionID, 6592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_block_additional_id_)) { 6602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_delay_) { 6642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvCodecDelay, codec_delay_)) 6652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_pre_roll_) { 6682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvSeekPreRoll, seek_pre_roll_)) 6692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (default_duration_) { 672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvDefaultDuration, default_duration_)) 673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 6752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id_) { 6762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvCodecID, codec_id_)) 6772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_private_) { 680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvCodecPrivate, codec_private_, 6812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_length_)) 6822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) { 6852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvLanguage, language_)) 6862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name_) { 6892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvName, name_)) 6902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int64 stop_position = writer->Position(); 6942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 6952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position - payload_position != static_cast<int64>(size)) 6962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (content_encoding_entries_size_ > 0) { 6992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 content_encodings_size = 0; 7002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < content_encoding_entries_size_; ++i) { 7012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const encoding = content_encoding_entries_[i]; 7022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encodings_size += encoding->Size(); 7032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvContentEncodings, 7062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encodings_size)) 7072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 7082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < content_encoding_entries_size_; ++i) { 7102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const encoding = content_encoding_entries_[i]; 7112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!encoding->Write(writer)) 7122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 7132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position = writer->Position(); 7172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0) 7182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 7192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 7202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Track::SetCodecPrivate(const uint8* codec_private, uint64 length) { 7232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!codec_private || length < 1) 7242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 7252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codec_private_; 7272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_ = 7292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new (std::nothrow) uint8[static_cast<size_t>(length)]; // NOLINT 7302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!codec_private_) 7312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 7322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy(codec_private_, codec_private, static_cast<size_t>(length)); 7342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_length_ = length; 7352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 7372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Track::set_codec_id(const char* codec_id) { 7402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id) { 741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codec_id_; 7422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(codec_id) + 1; 7442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_id_ = new (std::nothrow) char[length]; // NOLINT 7452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id_) { 7462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 7472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(codec_id_, length, codec_id); 7482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 7492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(codec_id_, codec_id); 7502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 7512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// TODO(fgalligan): Vet the language parameter. 7562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Track::set_language(const char* language) { 7572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language) { 758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] language_; 7592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(language) + 1; 7612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian language_ = new (std::nothrow) char[length]; // NOLINT 7622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) { 7632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 7642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(language_, length, language); 7652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 7662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(language_, language); 7672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 7682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Track::set_name(const char* name) { 7732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name) { 774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] name_; 7752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(name) + 1; 7772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian name_ = new (std::nothrow) char[length]; // NOLINT 7782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name_) { 7792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 7802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(name_, length, name); 7812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 7822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(name_, name); 7832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 7842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 7892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 7902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// VideoTrack Class 7912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianVideoTrack::VideoTrack(unsigned int* seed) 7932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : Track(seed), 7942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian display_height_(0), 7952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian display_width_(0), 7962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame_rate_(0.0), 7972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian height_(0), 7982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode_(0), 7992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian alpha_mode_(0), 800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width_(0) {} 8012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianVideoTrack::~VideoTrack() {} 8032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool VideoTrack::SetStereoMode(uint64 stereo_mode) { 805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (stereo_mode != kMono && stereo_mode != kSideBySideLeftIsFirst && 8062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode != kTopBottomRightIsFirst && 8072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode != kTopBottomLeftIsFirst && 8082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode != kSideBySideRightIsFirst) 8092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode_ = stereo_mode; 8122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 8132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 8142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool VideoTrack::SetAlphaMode(uint64 alpha_mode) { 816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (alpha_mode != kNoAlpha && alpha_mode != kAlpha) 8172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian alpha_mode_ = alpha_mode; 8202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 8212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 8222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 VideoTrack::PayloadSize() const { 8242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 parent_size = Track::PayloadSize(); 8252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = VideoPayloadSize(); 8272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlMasterElementSize(kMkvVideo, size); 8282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return parent_size + size; 8302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 8312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool VideoTrack::Write(IMkvWriter* writer) const { 8332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!Track::Write(writer)) 8342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 size = VideoPayloadSize(); 8372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvVideo, size)) 8392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 8422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 8432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvPixelWidth, width_)) 8462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvPixelHeight, height_)) 8482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (display_width_ > 0) 8502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvDisplayWidth, display_width_)) 8512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (display_height_ > 0) 8532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvDisplayHeight, display_height_)) 8542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stereo_mode_ > kMono) 8562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvStereoMode, stereo_mode_)) 8572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (alpha_mode_ > kNoAlpha) 8592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvAlphaMode, alpha_mode_)) 8602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_rate_ > 0.0) 862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvFrameRate, 8632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian static_cast<float>(frame_rate_))) 8642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop_position = writer->Position(); 8672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 8682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position - payload_position != static_cast<int64>(size)) 8692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 8722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 8732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 VideoTrack::VideoPayloadSize() const { 8752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = EbmlElementSize(kMkvPixelWidth, width_); 8762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvPixelHeight, height_); 8772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (display_width_ > 0) 8782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvDisplayWidth, display_width_); 8792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (display_height_ > 0) 8802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvDisplayHeight, display_height_); 8812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stereo_mode_ > kMono) 8822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvStereoMode, stereo_mode_); 8832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (alpha_mode_ > kNoAlpha) 8842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvAlphaMode, alpha_mode_); 8852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_rate_ > 0.0) 8862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvFrameRate, static_cast<float>(frame_rate_)); 8872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 8892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 8902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 8922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 8932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// AudioTrack Class 8942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianAudioTrack::AudioTrack(unsigned int* seed) 896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : Track(seed), bit_depth_(0), channels_(1), sample_rate_(0.0) {} 8972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 898ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianAudioTrack::~AudioTrack() {} 8992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 AudioTrack::PayloadSize() const { 9012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 parent_size = Track::PayloadSize(); 9022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 size = 904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvSamplingFrequency, static_cast<float>(sample_rate_)); 9052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvChannels, channels_); 9062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (bit_depth_ > 0) 9072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvBitDepth, bit_depth_); 9082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlMasterElementSize(kMkvAudio, size); 9092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return parent_size + size; 9112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 9122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool AudioTrack::Write(IMkvWriter* writer) const { 9142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!Track::Write(writer)) 9152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Calculate AudioSettings size. 918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 size = 919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvSamplingFrequency, static_cast<float>(sample_rate_)); 9202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvChannels, channels_); 9212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (bit_depth_ > 0) 9222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvBitDepth, bit_depth_); 9232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvAudio, size)) 9252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 9282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 9292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvSamplingFrequency, 9322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian static_cast<float>(sample_rate_))) 9332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvChannels, channels_)) 9352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (bit_depth_ > 0) 9372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvBitDepth, bit_depth_)) 9382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop_position = writer->Position(); 9412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 9422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position - payload_position != static_cast<int64>(size)) 9432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 9462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 9472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 9492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 9502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Tracks Class 9512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst char Tracks::kOpusCodecId[] = "A_OPUS"; 9532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst char Tracks::kVorbisCodecId[] = "A_VORBIS"; 9542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst char Tracks::kVp8CodecId[] = "V_VP8"; 9552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst char Tracks::kVp9CodecId[] = "V_VP9"; 9562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianTracks::Tracks() : track_entries_(NULL), track_entries_size_(0) {} 9582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTracks::~Tracks() { 9602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries_) { 9612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < track_entries_size_; ++i) { 9622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Track* const track = track_entries_[i]; 9632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete track; 9642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] track_entries_; 9662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 9682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Tracks::AddTrack(Track* track, int32 number) { 9702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (number < 0) 9712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // This muxer only supports track numbers in the range [1, 126], in 9742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // order to be able (to use Matroska integer representation) to 9752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // serialize the block header (of which the track number is a part) 9762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // for a frame using exactly 4 bytes. 9772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (number > 0x7E) 9792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint32 track_num = number; 9822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_num > 0) { 9842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check to make sure a track does not already have |track_num|. 9852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < track_entries_size_; ++i) { 9862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries_[i]->number() == track_num) 9872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint32 count = track_entries_size_ + 1; 9922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track** const track_entries = new (std::nothrow) Track* [count]; // NOLINT 9942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track_entries) 9952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < track_entries_size_; ++i) { 9982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_entries[i] = track_entries_[i]; 9992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 10002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] track_entries_; 10022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Find the lowest availible track number > 0. 10042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_num == 0) { 10052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_num = count; 10062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check to make sure a track does not already have |track_num|. 10082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian bool exit = false; 10092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian do { 10102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exit = true; 10112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < track_entries_size_; ++i) { 10122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries[i]->number() == track_num) { 10132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_num++; 10142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exit = false; 10152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian break; 10162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 10172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 10182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } while (!exit); 10192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 10202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_number(track_num); 10212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_entries_ = track_entries; 10232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_entries_[track_entries_size_] = track; 10242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_entries_size_ = count; 10252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 10262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 10272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst Track* Tracks::GetTrackByIndex(uint32 index) const { 10292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries_ == NULL) 10302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 10312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index >= track_entries_size_) 10332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 10342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track_entries_[index]; 10362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 10372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTrack* Tracks::GetTrackByNumber(uint64 track_number) const { 10392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int32 count = track_entries_size(); 10402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < count; ++i) { 10412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries_[i]->number() == track_number) 10422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track_entries_[i]; 10432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 10442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 10462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 10472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Tracks::TrackIsAudio(uint64 track_number) const { 10492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByNumber(track_number); 10502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track->type() == kAudio) 10522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 10532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 10552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 10562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Tracks::TrackIsVideo(uint64 track_number) const { 10582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByNumber(track_number); 10592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track->type() == kVideo) 10612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 10622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 10642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 10652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Tracks::Write(IMkvWriter* writer) const { 10672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = 0; 10682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int32 count = track_entries_size(); 10692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < count; ++i) { 10702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByIndex(i); 10712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 10732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 10742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += track->Size(); 10762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 10772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvTracks, size)) 10792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 10802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 10822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 10832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 10842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < count; ++i) { 10862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByIndex(i); 10872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track->Write(writer)) 10882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 10892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 10902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop_position = writer->Position(); 10922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 10932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position - payload_position != static_cast<int64>(size)) 10942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 10952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 10972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 10982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 10992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 11002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 11012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Chapter Class 11022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Chapter::set_id(const char* id) { return StrCpy(id, &id_); } 11042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Chapter::set_time(const Segment& segment, uint64 start_ns, uint64 end_ns) { 11062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const SegmentInfo* const info = segment.GetSegmentInfo(); 11072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = info->timecode_scale(); 11082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian start_timecode_ = start_ns / timecode_scale; 11092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian end_timecode_ = end_ns / timecode_scale; 11102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 11112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Chapter::add_string(const char* title, const char* language, 11132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const char* country) { 11142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ExpandDisplaysArray()) 11152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 11162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Display& d = displays_[displays_count_++]; 11182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian d.Init(); 11192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!d.set_title(title)) 11212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 11222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!d.set_language(language)) 11242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 11252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!d.set_country(country)) 11272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 11282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 11302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 11312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianChapter::Chapter() { 11332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // This ctor only constructs the object. Proper initialization is 11342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // done in Init() (called in Chapters::AddChapter()). The only 11352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // reason we bother implementing this ctor is because we had to 11362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // declare it as private (along with the dtor), in order to prevent 11372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // clients from creating Chapter instances (a privelege we grant 11382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // only to the Chapters class). Doing no initialization here also 11392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // means that creating arrays of chapter objects is more efficient, 11402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // because we only initialize each new chapter object as it becomes 11412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // active on the array. 11422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 11432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapter::~Chapter() {} 11452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::Init(unsigned int* seed) { 11472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian id_ = NULL; 11482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_ = NULL; 11492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_size_ = 0; 11502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_count_ = 0; 11512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uid_ = MakeUID(seed); 11522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 11532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::ShallowCopy(Chapter* dst) const { 11552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->id_ = id_; 11562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->start_timecode_ = start_timecode_; 11572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->end_timecode_ = end_timecode_; 11582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->uid_ = uid_; 11592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->displays_ = displays_; 11602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->displays_size_ = displays_size_; 11612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->displays_count_ = displays_count_; 11622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 11632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::Clear() { 11652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian StrCpy(NULL, &id_); 11662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (displays_count_ > 0) { 11682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Display& d = displays_[--displays_count_]; 11692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian d.Clear(); 11702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 11712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] displays_; 11732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_ = NULL; 11742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_size_ = 0; 11762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 11772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapter::ExpandDisplaysArray() { 11792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (displays_size_ > displays_count_) 11802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; // nothing to do yet 11812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int size = (displays_size_ == 0) ? 1 : 2 * displays_size_; 11832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Display* const displays = new (std::nothrow) Display[size]; // NOLINT 11852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (displays == NULL) 11862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 11872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < displays_count_; ++idx) { 11892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays[idx] = displays_[idx]; // shallow copy 11902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 11912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] displays_; 11932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_ = displays; 11952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_size_ = size; 11962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 11982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 11992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 Chapter::WriteAtom(IMkvWriter* writer) const { 1201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 payload_size = EbmlElementSize(kMkvChapterStringUID, id_) + 1202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvChapterUID, uid_) + 1203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvChapterTimeStart, start_timecode_) + 1204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvChapterTimeEnd, end_timecode_); 12052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < displays_count_; ++idx) { 12072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Display& d = displays_[idx]; 12082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_size += d.WriteDisplay(NULL); 12092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 12102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 atom_size = 1212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvChapterAtom, payload_size) + payload_size; 12132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer == NULL) 12152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return atom_size; 12162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 start = writer->Position(); 12182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvChapterAtom, payload_size)) 12202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvChapterStringUID, id_)) 12232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvChapterUID, uid_)) 12262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvChapterTimeStart, start_timecode_)) 12292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvChapterTimeEnd, end_timecode_)) 12322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < displays_count_; ++idx) { 12352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Display& d = displays_[idx]; 12362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!d.WriteDisplay(writer)) 12382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 12402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop = writer->Position(); 12422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop >= start && uint64(stop - start) != atom_size) 12442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return atom_size; 12472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 12482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::Display::Init() { 12502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian title_ = NULL; 12512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian language_ = NULL; 12522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian country_ = NULL; 12532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 12542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::Display::Clear() { 12562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian StrCpy(NULL, &title_); 12572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian StrCpy(NULL, &language_); 12582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian StrCpy(NULL, &country_); 12592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 12602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapter::Display::set_title(const char* title) { 12622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return StrCpy(title, &title_); 12632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 12642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapter::Display::set_language(const char* language) { 12662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return StrCpy(language, &language_); 12672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 12682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapter::Display::set_country(const char* country) { 12702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return StrCpy(country, &country_); 12712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 12722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 Chapter::Display::WriteDisplay(IMkvWriter* writer) const { 12742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 payload_size = EbmlElementSize(kMkvChapString, title_); 12752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) 12772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_size += EbmlElementSize(kMkvChapLanguage, language_); 12782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (country_) 12802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_size += EbmlElementSize(kMkvChapCountry, country_); 12812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 display_size = 1283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvChapterDisplay, payload_size) + payload_size; 12842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer == NULL) 12862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return display_size; 12872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 start = writer->Position(); 12892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvChapterDisplay, payload_size)) 12912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvChapString, title_)) 12942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 12962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) { 12972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvChapLanguage, language_)) 12982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 12992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 13002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (country_) { 13022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvChapCountry, country_)) 13032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 13042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 13052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop = writer->Position(); 13072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop >= start && uint64(stop - start) != display_size) 13092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 13102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return display_size; 13122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 13132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 13152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 13162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Chapters Class 13172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapters::Chapters() : chapters_size_(0), chapters_count_(0), chapters_(NULL) {} 13192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianChapters::~Chapters() { 13212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (chapters_count_ > 0) { 13222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Chapter& chapter = chapters_[--chapters_count_]; 13232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapter.Clear(); 13242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 13252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chapters_; 13272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapters_ = NULL; 13282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 13292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Chapters::Count() const { return chapters_count_; } 13312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianChapter* Chapters::AddChapter(unsigned int* seed) { 13332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ExpandChaptersArray()) 13342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 13352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Chapter& chapter = chapters_[chapters_count_++]; 13372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapter.Init(seed); 13382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return &chapter; 13402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 13412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapters::Write(IMkvWriter* writer) const { 13432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer == NULL) 13442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 13452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 payload_size = WriteEdition(NULL); // return size only 13472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvChapters, payload_size)) 13492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 13502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 start = writer->Position(); 13522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteEdition(writer) == 0) // error 13542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 13552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop = writer->Position(); 13572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop >= start && uint64(stop - start) != payload_size) 13592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 13602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 13622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 13632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapters::ExpandChaptersArray() { 13652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chapters_size_ > chapters_count_) 13662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; // nothing to do yet 13672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int size = (chapters_size_ == 0) ? 1 : 2 * chapters_size_; 13692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Chapter* const chapters = new (std::nothrow) Chapter[size]; // NOLINT 13712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chapters == NULL) 13722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 13732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < chapters_count_; ++idx) { 13752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Chapter& src = chapters_[idx]; 13762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Chapter* const dst = chapters + idx; 13772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian src.ShallowCopy(dst); 13782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 13792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1380ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chapters_; 13812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapters_ = chapters; 13832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapters_size_ = size; 13842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 13862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 13872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 Chapters::WriteEdition(IMkvWriter* writer) const { 13892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 payload_size = 0; 13902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < chapters_count_; ++idx) { 13922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Chapter& chapter = chapters_[idx]; 13932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_size += chapter.WriteAtom(NULL); 13942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 13952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 edition_size = 1397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvEditionEntry, payload_size) + payload_size; 13982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer == NULL) // return size only 14002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return edition_size; 14012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 start = writer->Position(); 14032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvEditionEntry, payload_size)) 14052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; // error 14062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < chapters_count_; ++idx) { 14082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Chapter& chapter = chapters_[idx]; 14092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 chapter_size = chapter.WriteAtom(writer); 14112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chapter_size == 0) // error 14122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 14132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 14142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop = writer->Position(); 14162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop >= start && uint64(stop - start) != edition_size) 14182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 14192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return edition_size; 14212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 14242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 14252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Cluster class 14262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianCluster::Cluster(uint64 timecode, int64 cues_pos) 14282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : blocks_added_(0), 14292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian finalized_(false), 14302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian header_written_(false), 14312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_size_(0), 14322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian position_for_cues_(cues_pos), 14332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_position_(-1), 14342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian timecode_(timecode), 1435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian writer_(NULL) {} 14362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCluster::~Cluster() {} 14382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::Init(IMkvWriter* ptr_writer) { 14402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ptr_writer) { 14412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 14432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_ = ptr_writer; 14442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 14452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cluster::AddFrame(const uint8* frame, uint64 length, uint64 track_number, 1448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 abs_timecode, bool is_key) { 1449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return DoWriteBlock(frame, length, track_number, abs_timecode, is_key ? 1 : 0, 14502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian &WriteSimpleBlock); 14512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cluster::AddFrameWithAdditional(const uint8* frame, uint64 length, 14542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint8* additional, 1455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 additional_length, uint64 add_id, 1456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 track_number, uint64 abs_timecode, 14572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian bool is_key) { 1458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return DoWriteBlockWithAdditional( 1459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame, length, additional, additional_length, add_id, track_number, 1460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian abs_timecode, is_key ? 1 : 0, &WriteBlockWithAdditional); 1461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cluster::AddFrameWithDiscardPadding(const uint8* frame, uint64 length, 14642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int64 discard_padding, 14652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 track_number, 1466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 abs_timecode, bool is_key) { 1467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return DoWriteBlockWithDiscardPadding( 1468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame, length, discard_padding, track_number, abs_timecode, 1469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian is_key ? 1 : 0, &WriteBlockWithDiscardPadding); 14702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cluster::AddMetadata(const uint8* frame, uint64 length, 1473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 track_number, uint64 abs_timecode, 1474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 duration_timecode) { 1475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return DoWriteBlock(frame, length, track_number, abs_timecode, 1476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian duration_timecode, &WriteMetadataBlock); 14772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Cluster::AddPayloadSize(uint64 size) { payload_size_ += size; } 1480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 14812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::Finalize() { 14822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer_ || finalized_ || size_position_ == -1) 14832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_->Seekable()) { 14862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 pos = writer_->Position(); 14872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_->Position(size_position_)) 14892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteUIntSize(writer_, payload_size(), 8)) 14922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_->Position(pos)) 14952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 14972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian finalized_ = true; 14992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 15012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 Cluster::Size() const { 15042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 element_size = 1505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvCluster, 0xFFFFFFFFFFFFFFFFULL) + payload_size_; 15062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return element_size; 15072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramaniantemplate <typename Type> 15102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::PreWriteBlock(Type* write_function) { 15112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (write_function == NULL) 15122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (finalized_) 15152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!header_written_) { 15182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteClusterHeader()) 15192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 15212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 15232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Cluster::PostWriteBlock(uint64 element_size) { 15262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian AddPayloadSize(element_size); 15272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++blocks_added_; 15282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::IsValidTrackNumber(uint64 track_number) const { 15312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return (track_number > 0 && track_number <= 0x7E); 15322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianint64 Cluster::GetRelativeTimecode(int64 abs_timecode) const { 15352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 cluster_timecode = this->Cluster::timecode(); 15362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 rel_timecode = 15372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian static_cast<int64>(abs_timecode) - cluster_timecode; 15382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (rel_timecode < 0 || rel_timecode > kMaxBlockTimecode) 15402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 15412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return rel_timecode; 15432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cluster::DoWriteBlock(const uint8* frame, uint64 length, 1546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 track_number, uint64 abs_timecode, 1547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 generic_arg, WriteBlock write_block) { 15482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame == NULL || length == 0) 15492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!IsValidTrackNumber(track_number)) 15522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 rel_timecode = GetRelativeTimecode(abs_timecode); 15552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (rel_timecode < 0) 15562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!PreWriteBlock(write_block)) 15592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 element_size = (*write_block)( 1562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian writer_, frame, length, track_number, rel_timecode, generic_arg); 15632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (element_size == 0) 15642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian PostWriteBlock(element_size); 15672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 15682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::DoWriteBlockWithAdditional( 1571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* frame, uint64 length, const uint8* additional, 1572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 additional_length, uint64 add_id, uint64 track_number, 1573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 abs_timecode, uint64 generic_arg, WriteBlockAdditional write_block) { 1574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (frame == NULL || length == 0 || additional == NULL || 1575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian additional_length == 0) 15762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!IsValidTrackNumber(track_number)) 15792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 rel_timecode = GetRelativeTimecode(abs_timecode); 15822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (rel_timecode < 0) 15832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!PreWriteBlock(write_block)) 15862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 element_size = 1589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (*write_block)(writer_, frame, length, additional, additional_length, 1590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian add_id, track_number, rel_timecode, generic_arg); 15912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (element_size == 0) 15922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian PostWriteBlock(element_size); 15952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 15962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::DoWriteBlockWithDiscardPadding( 1599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* frame, uint64 length, int64 discard_padding, 1600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 track_number, uint64 abs_timecode, uint64 generic_arg, 16012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian WriteBlockDiscardPadding write_block) { 16022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame == NULL || length == 0 || discard_padding <= 0) 16032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!IsValidTrackNumber(track_number)) 16062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 rel_timecode = GetRelativeTimecode(abs_timecode); 16092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (rel_timecode < 0) 16102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!PreWriteBlock(write_block)) 16132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 element_size = 1616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (*write_block)(writer_, frame, length, discard_padding, track_number, 1617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rel_timecode, generic_arg); 16182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (element_size == 0) 16192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian PostWriteBlock(element_size); 16222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 16232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 16242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::WriteClusterHeader() { 16262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (finalized_) 16272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteID(writer_, kMkvCluster)) 16302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Save for later. 16332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_position_ = writer_->Position(); 16342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write "unknown" (EBML coded -1) as cluster size value. We need to write 8 16362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // bytes because we do not know how big our cluster will be. 16372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (SerializeInt(writer_, kEbmlUnknownValue, 8)) 16382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer_, kMkvTimecode, timecode())) 16412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian AddPayloadSize(EbmlElementSize(kMkvTimecode, timecode())); 16432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian header_written_ = true; 16442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 16462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 16472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 16492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 16502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// SeekHead Class 16512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSeekHead::SeekHead() : start_pos_(0ULL) { 16532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < kSeekEntryCount; ++i) { 16542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_id_[i] = 0; 16552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_pos_[i] = 0; 16562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 16572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 16582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSeekHead::~SeekHead() {} 16602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SeekHead::Finalize(IMkvWriter* writer) const { 16622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Seekable()) { 16632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (start_pos_ == -1) 16642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 payload_size = 0; 16672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 entry_size[kSeekEntryCount]; 16682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < kSeekEntryCount; ++i) { 16702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_entry_id_[i] != 0) { 1671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian entry_size[i] = 1672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlElementSize(kMkvSeekID, static_cast<uint64>(seek_entry_id_[i])); 16732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian entry_size[i] += EbmlElementSize(kMkvSeekPosition, seek_entry_pos_[i]); 16742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian payload_size += 1676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvSeek, entry_size[i]) + entry_size[i]; 16772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 16782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 16792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // No SeekHead elements 16812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_size == 0) 16822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 16832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 pos = writer->Position(); 16852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(start_pos_)) 16862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvSeekHead, payload_size)) 16892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < kSeekEntryCount; ++i) { 16922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_entry_id_[i] != 0) { 16932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvSeek, entry_size[i])) 16942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvSeekID, 16972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian static_cast<uint64>(seek_entry_id_[i]))) 16982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvSeekPosition, seek_entry_pos_[i])) 17012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 total_entry_size = kSeekEntryCount * MaxEntrySize(); 17062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 total_size = 1707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvSeekHead, total_entry_size) + 1708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian total_entry_size; 17092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 size_left = total_size - (writer->Position() - start_pos_); 17102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 bytes_written = WriteVoidElement(writer, size_left); 17122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!bytes_written) 17132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(pos)) 17162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 17202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SeekHead::Write(IMkvWriter* writer) { 17232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 entry_size = kSeekEntryCount * MaxEntrySize(); 17242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 size = EbmlMasterElementSize(kMkvSeekHead, entry_size); 17252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian start_pos_ = writer->Position(); 17272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 bytes_written = WriteVoidElement(writer, size + entry_size); 17292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!bytes_written) 17302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 17332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SeekHead::AddSeekEntry(uint32 id, uint64 pos) { 17362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < kSeekEntryCount; ++i) { 17372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_entry_id_[i] == 0) { 17382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_id_[i] = id; 17392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_pos_[i] = pos; 17402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 17412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint32 SeekHead::GetId(int index) const { 17472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index < 0 || index >= kSeekEntryCount) 17482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return UINT_MAX; 17492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return seek_entry_id_[index]; 17502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 SeekHead::GetPosition(int index) const { 17532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index < 0 || index >= kSeekEntryCount) 17542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return ULLONG_MAX; 17552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return seek_entry_pos_[index]; 17562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SeekHead::SetSeekEntry(int index, uint32 id, uint64 position) { 17592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index < 0 || index >= kSeekEntryCount) 17602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_id_[index] = id; 17622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_pos_[index] = position; 17632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 17642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 SeekHead::MaxEntrySize() const { 17672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 max_entry_payload_size = 17682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian EbmlElementSize(kMkvSeekID, 0xffffffffULL) + 17692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian EbmlElementSize(kMkvSeekPosition, 0xffffffffffffffffULL); 17702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 max_entry_size = 17712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian EbmlMasterElementSize(kMkvSeek, max_entry_payload_size) + 17722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_entry_payload_size; 17732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return max_entry_size; 17752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 17782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 17792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// SegmentInfo Class 17802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSegmentInfo::SegmentInfo() 17822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : duration_(-1.0), 17832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian muxing_app_(NULL), 17842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian timecode_scale_(1000000ULL), 17852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writing_app_(NULL), 1786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian date_utc_(LLONG_MIN), 1787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian duration_pos_(-1) {} 17882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSegmentInfo::~SegmentInfo() { 1790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] muxing_app_; 1791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] writing_app_; 17922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SegmentInfo::Init() { 17952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int32 major; 17962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int32 minor; 17972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int32 build; 17982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int32 revision; 17992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian GetVersion(&major, &minor, &build, &revision); 18002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char temp[256]; 18012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 1802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian sprintf_s(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major, 1803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian minor, build, revision); 18042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 1805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian snprintf(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major, 1806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian minor, build, revision); 18072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 18082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t app_len = strlen(temp) + 1; 18102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] muxing_app_; 18122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian muxing_app_ = new (std::nothrow) char[app_len]; // NOLINT 18142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!muxing_app_) 18152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 18182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(muxing_app_, app_len, temp); 18192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 18202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(muxing_app_, temp); 18212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 18222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian set_writing_app(temp); 18242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writing_app_) 18252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 18272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SegmentInfo::Finalize(IMkvWriter* writer) const { 18302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer) 18312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (duration_ > 0.0) { 18342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Seekable()) { 18352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (duration_pos_ == -1) 18362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 pos = writer->Position(); 18392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(duration_pos_)) 18412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvDuration, 18442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian static_cast<float>(duration_))) 18452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(pos)) 18482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 18502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 18512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 18532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SegmentInfo::Write(IMkvWriter* writer) { 18562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer || !muxing_app_ || !writing_app_) 18572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 size = EbmlElementSize(kMkvTimecodeScale, timecode_scale_); 18602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (duration_ > 0.0) 18612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvDuration, static_cast<float>(duration_)); 1862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (date_utc_ != LLONG_MIN) 1863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += EbmlDateElementSize(kMkvDateUTC, date_utc_); 18642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvMuxingApp, muxing_app_); 18652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += EbmlElementSize(kMkvWritingApp, writing_app_); 18662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlMasterElement(writer, kMkvInfo, size)) 18682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 payload_position = writer->Position(); 18712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 18722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvTimecodeScale, timecode_scale_)) 18752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (duration_ > 0.0) { 18782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Save for later 18792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian duration_pos_ = writer->Position(); 18802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvDuration, static_cast<float>(duration_))) 18822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 18842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (date_utc_ != LLONG_MIN) 1886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian WriteEbmlDateElement(writer, kMkvDateUTC, date_utc_); 1887ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 18882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvMuxingApp, muxing_app_)) 18892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlElement(writer, kMkvWritingApp, writing_app_)) 18912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 stop_position = writer->Position(); 18942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 18952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position - payload_position != static_cast<int64>(size)) 18962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 18992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid SegmentInfo::set_muxing_app(const char* app) { 19022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (app) { 19032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(app) + 1; 19042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* temp_str = new (std::nothrow) char[length]; // NOLINT 19052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!temp_str) 19062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return; 19072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 19092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(temp_str, length, app); 19102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 19112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(temp_str, app); 19122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 19132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] muxing_app_; 19152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian muxing_app_ = temp_str; 19162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 19172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid SegmentInfo::set_writing_app(const char* app) { 19202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (app) { 19212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(app) + 1; 19222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* temp_str = new (std::nothrow) char[length]; // NOLINT 19232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!temp_str) 19242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return; 19252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 19272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(temp_str, length, app); 19282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 19292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(temp_str, app); 19302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 19312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] writing_app_; 19332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writing_app_ = temp_str; 19342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 19352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 19382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 19392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Segment Class 19402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSegment::Segment() 19422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : chunk_count_(0), 19432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_name_(NULL), 19442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_(NULL), 19452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cues_(NULL), 19462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_(NULL), 19472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunking_(false), 19482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunking_base_name_(NULL), 19492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_(NULL), 19502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_capacity_(0), 19512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_size_(0), 19522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_position_(kAfterClusters), 19532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_track_(0), 19542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian force_new_cluster_(false), 19552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_(NULL), 19562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_capacity_(0), 19572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_size_(0), 19582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian has_video_(false), 19592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian header_written_(false), 19602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_block_duration_(0), 19612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_timestamp_(0), 19622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_cluster_duration_(kDefaultMaxClusterDuration), 19632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_cluster_size_(0), 19642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian mode_(kFile), 19652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_cuepoint_(false), 19662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian output_cues_(true), 19672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_pos_(0), 19682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_position_(0), 19692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cluster_(NULL), 19702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cues_(NULL), 19712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_header_(NULL) { 19722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const time_t curr_time = time(NULL); 19732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seed_ = static_cast<unsigned int>(curr_time); 19742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _WIN32 19752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian srand(seed_); 19762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 19772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSegment::~Segment() { 19802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_) { 19812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cluster_list_size_; ++i) { 19822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[i]; 19832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete cluster; 19842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] cluster_list_; 19862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 19872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frames_) { 19892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < frames_size_; ++i) { 19902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Frame* const frame = frames_[i]; 19912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete frame; 19922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] frames_; 19942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 19952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1996ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chunk_name_; 1997ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chunking_base_name_; 19982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunk_writer_cluster_) { 20002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_->Close(); 20012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete chunk_writer_cluster_; 20022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunk_writer_cues_) { 20042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cues_->Close(); 20052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete chunk_writer_cues_; 20062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunk_writer_header_) { 20082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_->Close(); 20092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete chunk_writer_header_; 20102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2013ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Segment::MoveCuesBeforeClustersHelper(uint64 diff, int32 index, 20142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64* cues_size) { 20152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 old_cues_size = *cues_size; 20162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian CuePoint* const cue_point = cues_.GetCueByIndex(index); 20172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cue_point == NULL) 20182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return; 20192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 old_cue_point_size = cue_point->Size(); 20202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 cluster_pos = cue_point->cluster_pos() + diff; 20212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_point->set_cluster_pos(cluster_pos); // update the new cluster position 20222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // New size of the cue is computed as follows 20232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Let a = current size of Cues Element 20242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Let b = Difference in Cue Point's size after this pass 20252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Let c = Difference in length of Cues Element's size 20262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // (This is computed as CodedSize(a + b) - CodedSize(a) 20272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Let d = a + b + c. Now d is the new size of the Cues element which is 20282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // passed on to the next recursive call. 20292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 cue_point_size_diff = cue_point->Size() - old_cue_point_size; 2030ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint64 cue_size_diff = 2031ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian GetCodedUIntSize(*cues_size + cue_point_size_diff) - 2032ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian GetCodedUIntSize(*cues_size); 20332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *cues_size += cue_point_size_diff + cue_size_diff; 20342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian diff = *cues_size - old_cues_size; 20352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (diff > 0) { 20362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cues_.cue_entries_size(); ++i) { 20372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian MoveCuesBeforeClustersHelper(diff, i, cues_size); 20382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Segment::MoveCuesBeforeClusters() { 20432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 current_cue_size = cues_.Size(); 20442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 cue_size = current_cue_size; 20452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cues_.cue_entries_size(); i++) 20462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian MoveCuesBeforeClustersHelper(current_cue_size, i, &cue_size); 20472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Adjust the Seek Entry to reflect the change in position 20492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // of Cluster and Cues 20502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int32 cluster_index = 0; 20512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int32 cues_index = 0; 20522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < SeekHead::kSeekEntryCount; ++i) { 20532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_head_.GetId(i) == kMkvCluster) 20542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_index = i; 20552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_head_.GetId(i) == kMkvCues) 20562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_index = i; 20572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_head_.SetSeekEntry(cues_index, kMkvCues, 20592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_head_.GetPosition(cluster_index)); 20602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_head_.SetSeekEntry(cluster_index, kMkvCluster, 20612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_.Size() + seek_head_.GetPosition(cues_index)); 20622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::Init(IMkvWriter* ptr_writer) { 20652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ptr_writer) { 20662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 20672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cluster_ = ptr_writer; 20692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cues_ = ptr_writer; 20702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_header_ = ptr_writer; 20712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return segment_info_.Init(); 20722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader, 20752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian IMkvWriter* writer) { 20762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer->Seekable() || chunking_) 20772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int64 cluster_offset = 2079ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cluster_list_[0]->size_position() - GetUIntSize(kMkvCluster); 20802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Copy the headers. 20822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ChunkedCopy(reader, writer, 0, cluster_offset)) 20832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 20842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Recompute cue positions and seek entries. 20862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian MoveCuesBeforeClusters(); 20872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write cues and seek entries. 20892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(vigneshv): As of now, it's safe to call seek_head_.Finalize() for the 20902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // second time with a different writer object. But the name Finalize() doesn't 20912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // indicate something we want to call more than once. So consider renaming it 20922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // to write() or some such. 20932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues_.Write(writer) || !seek_head_.Finalize(writer)) 20942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 20952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Copy the Clusters. 20972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ChunkedCopy(reader, writer, cluster_offset, 20982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_end_offset_ - cluster_offset)) 20992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Update the Segment size in case the Cues size has changed. 21022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 pos = writer->Position(); 21032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 segment_size = writer->Position() - payload_pos_; 21042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(size_position_) || 2105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian WriteUIntSize(writer, segment_size, 8) || writer->Position(pos)) 21062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 21082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::Finalize() { 21112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteFramesAll() < 0) 21122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (mode_ == kFile) { 21152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ > 0) { 21162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Update last cluster's size 2117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1]; 21182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!old_cluster || !old_cluster->Finalize()) 21202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_ && chunk_writer_cluster_) { 21242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_->Close(); 21252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_count_++; 21262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const double duration = 21292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian (static_cast<double>(last_timestamp_) + last_block_duration_) / 21302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian segment_info_.timecode_scale(); 21312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian segment_info_.set_duration(duration); 21322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!segment_info_.Finalize(writer_header_)) 21332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_cues_) 21362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.AddSeekEntry(kMkvCues, MaxOffset())) 21372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_) { 21402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cues_) 21412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* name = NULL; 21442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!UpdateChunkName("cues", &name)) 21452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const bool cues_open = chunk_writer_cues_->Open(name); 2148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] name; 21492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues_open) 21502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_end_offset_ = writer_cluster_->Position(); 21542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write the seek headers and cues 21562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_cues_) 21572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues_.Write(writer_cues_)) 21582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.Finalize(writer_header_)) 21612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_header_->Seekable()) { 21642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (size_position_ == -1) 21652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 pos = writer_header_->Position(); 21682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 segment_size = MaxOffset(); 21692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (segment_size < 1) 21712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_header_->Position(size_position_)) 21742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteUIntSize(writer_header_, segment_size, 8)) 21772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_header_->Position(pos)) 21802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_) { 21842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Do not close any writers until the segment size has been written, 21852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // otherwise the size may be off. 21862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cues_ || !chunk_writer_header_) 21872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cues_->Close(); 21902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_->Close(); 21912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 21952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTrack* Segment::AddTrack(int32 number) { 21982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Track* const track = new (std::nothrow) Track(&seed_); // NOLINT 21992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 22012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 22022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!tracks_.AddTrack(track, number)) { 22042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete track; 22052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 22062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 22072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track; 22092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 22102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapter* Segment::AddChapter() { return chapters_.AddChapter(&seed_); } 22122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianuint64 Segment::AddVideoTrack(int32 width, int32 height, int32 number) { 22142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian VideoTrack* const track = new (std::nothrow) VideoTrack(&seed_); // NOLINT 22152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 22162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 22172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_type(Tracks::kVideo); 22192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_codec_id(Tracks::kVp8CodecId); 22202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_width(width); 22212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_height(height); 22222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian tracks_.AddTrack(track, number); 22242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian has_video_ = true; 22252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track->number(); 22272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 22282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::AddCuePoint(uint64 timestamp, uint64 track) { 2230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 22312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 22342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 22352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian CuePoint* const cue = new (std::nothrow) CuePoint(); // NOLINT 22382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cue) 22392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_time(timestamp / segment_info_.timecode_scale()); 22422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_block_number(cluster->blocks_added()); 22432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_cluster_pos(cluster->position_for_cues()); 22442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_track(track); 22452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues_.AddCue(cue)) 22462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_cuepoint_ = false; 22492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 22502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 22512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianuint64 Segment::AddAudioTrack(int32 sample_rate, int32 channels, int32 number) { 22532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian AudioTrack* const track = new (std::nothrow) AudioTrack(&seed_); // NOLINT 22542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 22552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 22562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_type(Tracks::kAudio); 22582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_codec_id(Tracks::kVorbisCodecId); 22592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_sample_rate(sample_rate); 22602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_channels(channels); 22612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian tracks_.AddTrack(track, number); 22632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track->number(); 22652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 22662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Segment::AddFrame(const uint8* frame, uint64 length, uint64 track_number, 2268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 timestamp, bool is_key) { 22692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!frame) 22702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!CheckHeaderInfo()) 22732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check for non-monotonically increasing timestamps. 22762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (timestamp < last_timestamp_) 22772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // If the segment has a video track hold onto audio frames to make sure the 22802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // audio that is associated with the start time of a video key-frame is 22812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // muxed into the same cluster. 22822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (has_video_ && tracks_.TrackIsAudio(track_number) && !force_new_cluster_) { 22832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Frame* const new_frame = new (std::nothrow) Frame(); 22842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_frame == NULL || !new_frame->Init(frame, length)) 22852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_track_number(track_number); 22872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_timestamp(timestamp); 22882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_is_key(is_key); 22892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!QueueFrame(new_frame)) 22912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 22942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 22952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!DoNewClusterProcessing(track_number, timestamp, is_key)) 22972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 22982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 23002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 23032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 23042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = segment_info_.timecode_scale(); 23072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 abs_timecode = timestamp / timecode_scale; 23082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!cluster->AddFrame(frame, length, track_number, abs_timecode, is_key)) 23102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_cuepoint_ && cues_track_ == track_number) { 23132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!AddCuePoint(timestamp, cues_track_)) 23142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 23162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (timestamp > last_timestamp_) 23182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_timestamp_ = timestamp; 23192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 23212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 23222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Segment::AddFrameWithAdditional(const uint8* frame, uint64 length, 23242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint8* additional, 2325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 additional_length, uint64 add_id, 2326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 track_number, uint64 timestamp, 23272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian bool is_key) { 23282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame == NULL || additional == NULL) 23292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!CheckHeaderInfo()) 23322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check for non-monotonically increasing timestamps. 23352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (timestamp < last_timestamp_) 23362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // If the segment has a video track hold onto audio frames to make sure the 23392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // audio that is associated with the start time of a video key-frame is 23402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // muxed into the same cluster. 23412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (has_video_ && tracks_.TrackIsAudio(track_number) && !force_new_cluster_) { 23422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Frame* const new_frame = new (std::nothrow) Frame(); 23432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_frame == NULL || !new_frame->Init(frame, length)) 23442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_track_number(track_number); 23462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_timestamp(timestamp); 23472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_is_key(is_key); 23482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!QueueFrame(new_frame)) 23502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 23532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 23542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!DoNewClusterProcessing(track_number, timestamp, is_key)) 23562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 23592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 23622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster == NULL) 23632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = segment_info_.timecode_scale(); 23662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 abs_timecode = timestamp / timecode_scale; 23672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!cluster->AddFrameWithAdditional(frame, length, additional, 2369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian additional_length, add_id, track_number, 2370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian abs_timecode, is_key)) 23712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_cuepoint_ && cues_track_ == track_number) { 23742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!AddCuePoint(timestamp, cues_track_)) 23752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 23772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (timestamp > last_timestamp_) 23792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_timestamp_ = timestamp; 23802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 23822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 23832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Segment::AddFrameWithDiscardPadding(const uint8* frame, uint64 length, 23852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int64 discard_padding, 2386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 track_number, uint64 timestamp, 23872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian bool is_key) { 23882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame == NULL || discard_padding <= 0) 23892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!CheckHeaderInfo()) 23922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check for non-monotonically increasing timestamps. 23952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (timestamp < last_timestamp_) 23962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 23972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // If the segment has a video track hold onto audio frames to make sure the 23992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // audio that is associated with the start time of a video key-frame is 24002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // muxed into the same cluster. 24012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (has_video_ && tracks_.TrackIsAudio(track_number) && !force_new_cluster_) { 24022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Frame* const new_frame = new (std::nothrow) Frame(); 24032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_frame == NULL || !new_frame->Init(frame, length)) 24042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_track_number(track_number); 24062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_timestamp(timestamp); 24072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_is_key(is_key); 24082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_frame->set_discard_padding(discard_padding); 24092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!QueueFrame(new_frame)) 24112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 24142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 24152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!DoNewClusterProcessing(track_number, timestamp, is_key)) 24172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 24202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 24232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 24242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = segment_info_.timecode_scale(); 24272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 abs_timecode = timestamp / timecode_scale; 24282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!cluster->AddFrameWithDiscardPadding( 2430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame, length, discard_padding, track_number, abs_timecode, is_key)) { 24312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 24332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_cuepoint_ && cues_track_ == track_number) { 24352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!AddCuePoint(timestamp, cues_track_)) 24362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 24382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (timestamp > last_timestamp_) 24402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_timestamp_ = timestamp; 24412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 24432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Segment::AddMetadata(const uint8* frame, uint64 length, 2446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 track_number, uint64 timestamp_ns, 24472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 duration_ns) { 24482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!frame) 24492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!CheckHeaderInfo()) 24522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check for non-monotonically increasing timestamps. 24552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (timestamp_ns < last_timestamp_) 24562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!DoNewClusterProcessing(track_number, timestamp_ns, true)) 24592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 24622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 24652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 24672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = segment_info_.timecode_scale(); 24702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 abs_timecode = timestamp_ns / timecode_scale; 24712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 duration_timecode = duration_ns / timecode_scale; 24722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!cluster->AddMetadata(frame, length, track_number, abs_timecode, 24742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian duration_timecode)) 24752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (timestamp_ns > last_timestamp_) 24782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_timestamp_ = timestamp_ns; 24792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 24812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::AddGenericFrame(const Frame* frame) { 24842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_block_duration_ = frame->duration(); 24852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!tracks_.TrackIsAudio(frame->track_number()) && 2486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !tracks_.TrackIsVideo(frame->track_number()) && frame->duration() > 0) { 2487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return AddMetadata(frame->frame(), frame->length(), frame->track_number(), 2488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->timestamp(), frame->duration()); 24892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else if (frame->additional() && frame->additional_length() > 0) { 2490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return AddFrameWithAdditional( 2491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->frame(), frame->length(), frame->additional(), 2492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->additional_length(), frame->add_id(), frame->track_number(), 2493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->timestamp(), frame->is_key()); 24942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else if (frame->discard_padding() > 0) { 2495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return AddFrameWithDiscardPadding( 2496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->frame(), frame->length(), frame->discard_padding(), 2497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->track_number(), frame->timestamp(), frame->is_key()); 24982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else { 2499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return AddFrame(frame->frame(), frame->length(), frame->track_number(), 2500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->timestamp(), frame->is_key()); 25012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 25022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 25032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Segment::OutputCues(bool output_cues) { output_cues_ = output_cues; } 25052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::SetChunking(bool chunking, const char* filename) { 25072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunk_count_ > 0) 25082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking) { 25112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!filename) 25122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check if we are being set to what is already set. 25152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_ && !strcmp(filename, chunking_base_name_)) 25162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 25172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t name_length = strlen(filename) + 1; 25192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* const temp = new (std::nothrow) char[name_length]; // NOLINT 25202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!temp) 25212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 25242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(temp, name_length, filename); 25252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 25262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(temp, filename); 25272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 25282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chunking_base_name_; 25302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunking_base_name_ = temp; 25312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!UpdateChunkName("chk", &chunk_name_)) 25332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cluster_) { 25362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_ = new (std::nothrow) MkvWriter(); // NOLINT 25372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cluster_) 25382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 25402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cues_) { 25422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cues_ = new (std::nothrow) MkvWriter(); // NOLINT 25432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cues_) 25442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 25462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_header_) { 25482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_ = new (std::nothrow) MkvWriter(); // NOLINT 25492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_header_) 25502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 25522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cluster_->Open(chunk_name_)) 25542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t header_length = strlen(filename) + strlen(".hdr") + 1; 25572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* const header = new (std::nothrow) char[header_length]; // NOLINT 25582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!header) 25592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 25622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(header, header_length - strlen(".hdr"), chunking_base_name_); 25632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcat_s(header, header_length, ".hdr"); 25642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 25652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(header, chunking_base_name_); 25662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcat(header, ".hdr"); 25672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 25682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_header_->Open(header)) { 2569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] header; 25702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 25722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cluster_ = chunk_writer_cluster_; 25742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cues_ = chunk_writer_cues_; 25752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_header_ = chunk_writer_header_; 25762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] header; 25782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 25792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunking_ = chunking; 25812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 25832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 25842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::CuesTrack(uint64 track_number) { 25862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByNumber(track_number); 25872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 25882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_track_ = track_number; 25912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 25922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 25932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Segment::ForceNewClusterOnNextFrame() { force_new_cluster_ = true; } 25952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTrack* Segment::GetTrackByNumber(uint64 track_number) const { 25972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return tracks_.GetTrackByNumber(track_number); 25982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 25992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::WriteSegmentHeader() { 26012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(fgalligan): Support more than one segment. 26022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteEbmlHeader(writer_header_)) 26032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write "unknown" (-1) as segment size value. If mode is kFile, Segment 26062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // will write over duration when the file is finalized. 26072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteID(writer_header_, kMkvSegment)) 26082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Save for later. 26112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_position_ = writer_header_->Position(); 26122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write "unknown" (EBML coded -1) as segment size value. We need to write 8 26142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // bytes because if we are going to overwrite the segment size later we do 26152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // not know how big our segment will be. 26162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (SerializeInt(writer_header_, kEbmlUnknownValue, 8)) 26172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian payload_pos_ = writer_header_->Position(); 26202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (mode_ == kFile && writer_header_->Seekable()) { 26222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Set the duration > 0.0 so SegmentInfo will write out the duration. When 26232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // the muxer is done writing we will set the correct duration and have 26242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // SegmentInfo upadte it. 26252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian segment_info_.set_duration(1.0); 26262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.Write(writer_header_)) 26282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 26302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.AddSeekEntry(kMkvInfo, MaxOffset())) 26322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!segment_info_.Write(writer_header_)) 26342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.AddSeekEntry(kMkvTracks, MaxOffset())) 26372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!tracks_.Write(writer_header_)) 26392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chapters_.Count() > 0) { 26422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.AddSeekEntry(kMkvChapters, MaxOffset())) 26432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chapters_.Write(writer_header_)) 26452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 26472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_ && (mode_ == kLive || !writer_header_->Seekable())) { 26492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_header_) 26502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_->Close(); 26532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 26542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian header_written_ = true; 26562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 26582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 26592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Here we are testing whether to create a new cluster, given a frame 26612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// having time frame_timestamp_ns. 26622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 2663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Segment::TestFrame(uint64 track_number, uint64 frame_timestamp_ns, 26642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian bool is_key) const { 26652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (force_new_cluster_) 26662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 26672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // If no clusters have been created yet, then create a new cluster 26692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // and write this frame immediately, in the new cluster. This path 26702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // should only be followed once, the first time we attempt to write 26712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // a frame. 26722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ <= 0) 26742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 26752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // There exists at least one cluster. We must compare the frame to 26772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // the last cluster, in order to determine whether the frame is 26782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // written to the existing cluster, or that a new cluster should be 26792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // created. 26802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = segment_info_.timecode_scale(); 26822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 frame_timecode = frame_timestamp_ns / timecode_scale; 26832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1]; 26852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 last_cluster_timecode = last_cluster->timecode(); 26862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // For completeness we test for the case when the frame's timecode 26882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // is less than the cluster's timecode. Although in principle that 26892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // is allowed, this muxer doesn't actually write clusters like that, 26902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // so this indicates a bug somewhere in our algorithm. 26912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_timecode < last_cluster_timecode) // should never happen 2693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 26942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // If the frame has a timestamp significantly larger than the last 26962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // cluster (in Matroska, cluster-relative timestamps are serialized 26972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // using a 16-bit signed integer), then we cannot write this frame 26982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // to that cluster, and so we must create a new cluster. 26992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 delta_timecode = frame_timecode - last_cluster_timecode; 27012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (delta_timecode > kMaxBlockTimecode) 27032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 2; 27042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // We decide to create a new cluster when we have a video keyframe. 27062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // This will flush queued (audio) frames, and write the keyframe 27072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // immediately, in the newly-created cluster. 27082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (is_key && tracks_.TrackIsVideo(track_number)) 27102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 27112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Create a new cluster if we have accumulated too many frames 27132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // already, where "too many" is defined as "the total time of frames 27142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // in the cluster exceeds a threshold". 27152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 delta_ns = delta_timecode * timecode_scale; 27172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_cluster_duration_ > 0 && delta_ns >= max_cluster_duration_) 27192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 27202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // This is similar to the case above, with the difference that a new 27222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // cluster is created when the size of the current cluster exceeds a 27232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // threshold. 27242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 cluster_size = last_cluster->payload_size(); 27262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_cluster_size_ > 0 && cluster_size >= max_cluster_size_) 27282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 27292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // There's no need to create a new cluster, so emit this frame now. 27312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 27332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 27342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::MakeNewCluster(uint64 frame_timestamp_ns) { 27362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int32 new_size = cluster_list_size_ + 1; 27372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_size > cluster_list_capacity_) { 27392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Add more clusters. 27402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int32 new_capacity = 27412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian (cluster_list_capacity_ <= 0) ? 1 : cluster_list_capacity_ * 2; 27422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster** const clusters = 2743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new (std::nothrow) Cluster* [new_capacity]; // NOLINT 27442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!clusters) 27452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cluster_list_size_; ++i) { 27482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian clusters[i] = cluster_list_[i]; 27492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] cluster_list_; 27522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_ = clusters; 27542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_capacity_ = new_capacity; 27552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteFramesLessThan(frame_timestamp_ns)) 27582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (mode_ == kFile) { 27612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ > 0) { 27622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Update old cluster's size 27632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1]; 27642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!old_cluster || !old_cluster->Finalize()) 27662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_cues_) 27702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_cuepoint_ = true; 27712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_ && cluster_list_size_ > 0) { 27742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_->Close(); 27752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_count_++; 27762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!UpdateChunkName("chk", &chunk_name_)) 27782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cluster_->Open(chunk_name_)) 27802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = segment_info_.timecode_scale(); 27842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 frame_timecode = frame_timestamp_ns / timecode_scale; 27852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uint64 cluster_timecode = frame_timecode; 27872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frames_size_ > 0) { 27892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Frame* const f = frames_[0]; // earliest queued frame 27902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 ns = f->timestamp(); 27912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 tc = ns / timecode_scale; 27922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (tc < cluster_timecode) 27942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_timecode = tc; 27952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster*& cluster = cluster_list_[cluster_list_size_]; 27982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 offset = MaxOffset(); 27992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster = new (std::nothrow) Cluster(cluster_timecode, offset); // NOLINT 28002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 28012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster->Init(writer_cluster_)) 28042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_size_ = new_size; 28072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 28082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::DoNewClusterProcessing(uint64 track_number, 2811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint64 frame_timestamp_ns, bool is_key) { 28122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (;;) { 28132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Based on the characteristics of the current frame and current 28142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // cluster, decide whether to create a new cluster. 28152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int result = TestFrame(track_number, frame_timestamp_ns, is_key); 28162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (result < 0) // error 28172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Always set force_new_cluster_ to false after TestFrame. 2820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian force_new_cluster_ = false; 28212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // A non-zero result means create a new cluster. 2823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0 && !MakeNewCluster(frame_timestamp_ns)) 2824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 28252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write queued (audio) frames. 28272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int frame_count = WriteFramesAll(); 28282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_count < 0) // error 28292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write the current frame to the current cluster (if TestFrame 28322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // returns 0) or to a newly created cluster (TestFrame returns 1). 28332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (result <= 1) 28342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 28352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TestFrame returned 2, which means there was a large time 28372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // difference between the cluster and the frame itself. Do the 28382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // test again, comparing the frame to the new cluster. 28392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::CheckHeaderInfo() { 28432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!header_written_) { 28442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteSegmentHeader()) 28452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.AddSeekEntry(kMkvCluster, MaxOffset())) 28482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_cues_ && cues_track_ == 0) { 28512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check for a video track 28522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (uint32 i = 0; i < tracks_.track_entries_size(); ++i) { 28532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = tracks_.GetTrackByIndex(i); 28542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 28552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (tracks_.TrackIsVideo(track->number())) { 28582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_track_ = track->number(); 28592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian break; 28602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Set first track found 28642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cues_track_ == 0) { 28652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = tracks_.GetTrackByIndex(0); 28662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 28672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_track_ = track->number(); 28702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 28742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::UpdateChunkName(const char* ext, char** name) const { 28772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!name || !ext) 28782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char ext_chk[64]; 28812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 28822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian sprintf_s(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext); 28832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 28842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian snprintf(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext); 28852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 28862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(chunking_base_name_) + strlen(ext_chk) + 1; 28882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* const str = new (std::nothrow) char[length]; // NOLINT 28892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!str) 28902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 2893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian strcpy_s(str, length - strlen(ext_chk), chunking_base_name_); 28942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcat_s(str, length, ext_chk); 28952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 28962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(str, chunking_base_name_); 28972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcat(str, ext_chk); 28982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 28992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] * name; 29012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *name = str; 29022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 29042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 29052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianint64 Segment::MaxOffset() { 29072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer_header_) 29082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 29092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int64 offset = writer_header_->Position() - payload_pos_; 29112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_) { 29132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < cluster_list_size_; ++i) { 29142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[i]; 29152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian offset += cluster->Size(); 29162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_cues_) 29192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian offset += writer_cues_->Position(); 29202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return offset; 29232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 29242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::QueueFrame(Frame* frame) { 29262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int32 new_size = frames_size_ + 1; 29272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_size > frames_capacity_) { 29292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Add more frames. 29302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int32 new_capacity = (!frames_capacity_) ? 2 : frames_capacity_ * 2; 29312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_capacity < 1) 29332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame** const frames = new (std::nothrow) Frame* [new_capacity]; // NOLINT 29362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!frames) 29372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < frames_size_; ++i) { 29402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames[i] = frames_[i]; 29412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2943ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] frames_; 29442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_ = frames; 29452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_capacity_ = new_capacity; 29462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_[frames_size_++] = frame; 29492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 29512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 29522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianint Segment::WriteFramesAll() { 29542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frames_ == NULL) 29552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 29562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 29582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 29592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 29612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 29632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 29642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = segment_info_.timecode_scale(); 29662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < frames_size_; ++i) { 29682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Frame*& frame = frames_[i]; 29692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 frame_timestamp = frame->timestamp(); // ns 29702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 frame_timecode = frame_timestamp / timecode_scale; 29712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame->discard_padding() > 0) { 2973ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!cluster->AddFrameWithDiscardPadding( 2974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->frame(), frame->length(), frame->discard_padding(), 2975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->track_number(), frame_timecode, frame->is_key())) { 29762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 29772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else { 2979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!cluster->AddFrame(frame->frame(), frame->length(), 2980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame->track_number(), frame_timecode, 29812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame->is_key())) { 29822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 29832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_cuepoint_ && cues_track_ == frame->track_number()) { 29872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!AddCuePoint(frame_timestamp, cues_track_)) 29882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 29892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_timestamp > last_timestamp_) 29922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_timestamp_ = frame_timestamp; 29932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete frame; 29952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame = NULL; 29962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int result = frames_size_; 29992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_size_ = 0; 30002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return result; 30022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 30032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::WriteFramesLessThan(uint64 timestamp) { 30052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check |cluster_list_size_| to see if this is the first cluster. If it is 30062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // the first cluster the audio frames that are less than the first video 30072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // timesatmp will be written in a later step. 30082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frames_size_ > 0 && cluster_list_size_ > 0) { 30092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!frames_) 30102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 30112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 30132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 30142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 30152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 timecode_scale = segment_info_.timecode_scale(); 30172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int32 shift_left = 0; 30182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(fgalligan): Change this to use the durations of frames instead of 30202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // the next frame's start time if the duration is accurate. 30212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 1; i < frames_size_; ++i) { 30222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Frame* const frame_curr = frames_[i]; 30232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_curr->timestamp() > timestamp) 30252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian break; 30262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Frame* const frame_prev = frames_[i - 1]; 30282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 frame_timestamp = frame_prev->timestamp(); 30292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const uint64 frame_timecode = frame_timestamp / timecode_scale; 30302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int64 discard_padding = frame_prev->discard_padding(); 30312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (discard_padding > 0) { 3033ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!cluster->AddFrameWithDiscardPadding( 3034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame_prev->frame(), frame_prev->length(), discard_padding, 3035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame_prev->track_number(), frame_timecode, 3036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame_prev->is_key())) { 30372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 30382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else { 3040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!cluster->AddFrame(frame_prev->frame(), frame_prev->length(), 3041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame_prev->track_number(), frame_timecode, 30422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame_prev->is_key())) { 30432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 30442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_cuepoint_ && cues_track_ == frame_prev->track_number()) { 30482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!AddCuePoint(frame_timestamp, cues_track_)) 30492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 30502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++shift_left; 30532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_timestamp > last_timestamp_) 30542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_timestamp_ = frame_timestamp; 30552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete frame_prev; 30572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (shift_left > 0) { 30602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (shift_left >= frames_size_) 30612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 30622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int32 new_frames_size = frames_size_ - shift_left; 30642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int32 i = 0; i < new_frames_size; ++i) { 3065ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frames_[i] = frames_[i + shift_left]; 30662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_size_ = new_frames_size; 30692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 30732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 30742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} // namespace mkvmuxer 3076