1343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih/*
2343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * Copyright (C) 2014 The Android Open Source Project
3343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih *
4343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * Licensed under the Apache License, Version 2.0 (the "License");
5343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * you may not use this file except in compliance with the License.
6343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * You may obtain a copy of the License at
7343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih *
8343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih *      http://www.apache.org/licenses/LICENSE-2.0
9343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih *
10343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * Unless required by applicable law or agreed to in writing, software
11343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * distributed under the License is distributed on an "AS IS" BASIS,
12343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * See the License for the specific language governing permissions and
14343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * limitations under the License.
15343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih */
16343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
17343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih// #define LOG_NDEBUG 0
18343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#define LOG_TAG "WebmElement"
19343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
20343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include "EbmlUtil.h"
21343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include "WebmElement.h"
22343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include "WebmConstants.h"
23343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
24343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <media/stagefright/foundation/ADebug.h>
25d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar#include <media/stagefright/foundation/ColorUtils.h>
26d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar#include <media/stagefright/MetaData.h>
27343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <utils/Log.h>
28343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
29343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <string.h>
30343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <unistd.h>
31343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <errno.h>
32343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <fcntl.h>
33343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <sys/mman.h>
34343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
35343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihusing namespace android;
36343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihusing namespace webm;
37343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
38343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihnamespace {
39343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
40343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihint64_t voidSize(int64_t totalSize) {
41343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    if (totalSize < 2) {
42343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        return -1;
43343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
44343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    if (totalSize < 9) {
45343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        return totalSize - 2;
46343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
47343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return totalSize - 9;
48343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
49343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
50343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihuint64_t childrenSum(const List<sp<WebmElement> >& children) {
51343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t total = 0;
52343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    for (List<sp<WebmElement> >::const_iterator it = children.begin();
53343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            it != children.end(); ++it) {
54343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        total += (*it)->totalSize();
55343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
56343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return total;
57343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
58343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
59343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihvoid populateCommonTrackEntries(
60343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int num,
61343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        uint64_t uid,
62343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        bool lacing,
63343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        const char *lang,
64343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        const char *codec,
65343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        TrackTypes type,
66343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        List<sp<WebmElement> > &ls) {
67343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ls.push_back(new WebmUnsigned(kMkvTrackNumber, num));
68343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ls.push_back(new WebmUnsigned(kMkvTrackUid, uid));
69343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ls.push_back(new WebmUnsigned(kMkvFlagLacing, lacing));
70343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ls.push_back(new WebmString(kMkvLanguage, lang));
71343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ls.push_back(new WebmString(kMkvCodecId, codec));
72343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ls.push_back(new WebmUnsigned(kMkvTrackType, type));
73343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
74343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
75343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
76343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihnamespace android {
77343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
78343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmElement::WebmElement(uint64_t id, uint64_t size)
79343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : mId(id), mSize(size) {
80343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
81343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
82343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmElement::~WebmElement() {
83343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
84343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
85343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihint WebmElement::serializePayloadSize(uint8_t *buf) {
86343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return serializeCodedUnsigned(encodeUnsigned(mSize), buf);
87343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
88343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
89343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihuint64_t WebmElement::serializeInto(uint8_t *buf) {
90343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint8_t *cur = buf;
91343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    int head = serializeCodedUnsigned(mId, cur);
92343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    cur += head;
93343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    int neck = serializePayloadSize(cur);
94343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    cur += neck;
95343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    serializePayload(cur);
96343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    cur += mSize;
97343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return cur - buf;
98343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
99343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
100343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihuint64_t WebmElement::totalSize() {
101343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint8_t buf[8];
102343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    //............... + sizeOf(encodeUnsigned(size))
103343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return sizeOf(mId) + serializePayloadSize(buf) + mSize;
104343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
105343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
106343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihuint8_t *WebmElement::serialize(uint64_t& size) {
107343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    size = totalSize();
108343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint8_t *buf = new uint8_t[size];
109343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    serializeInto(buf);
110343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return buf;
111343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
112343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
113343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihint WebmElement::write(int fd, uint64_t& size) {
114343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint8_t buf[8];
115343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    size = totalSize();
116343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    off64_t off = ::lseek64(fd, (size - 1), SEEK_CUR) - (size - 1);
117343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ::write(fd, buf, 1); // extend file
118343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
119343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    off64_t curOff = off + size;
120343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    off64_t alignedOff = off & ~(::sysconf(_SC_PAGE_SIZE) - 1);
121343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    off64_t mapSize = curOff - alignedOff;
122343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    off64_t pageOff = off - alignedOff;
123343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    void *dst = ::mmap64(NULL, mapSize, PROT_WRITE, MAP_SHARED, fd, alignedOff);
124b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    if (dst == MAP_FAILED) {
125343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        ALOGE("mmap64 failed; errno = %d", errno);
126343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        ALOGE("fd %d; flags: %o", fd, ::fcntl(fd, F_GETFL, 0));
127343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        return errno;
128343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    } else {
129343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        serializeInto((uint8_t*) dst + pageOff);
130343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        ::msync(dst, mapSize, MS_SYNC);
131343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        return ::munmap(dst, mapSize);
132343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
133343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
134343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
135343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih//=================================================================================================
136343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
137343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmUnsigned::WebmUnsigned(uint64_t id, uint64_t value)
138343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(id, sizeOf(value)), mValue(value) {
139343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
140343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
141343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihvoid WebmUnsigned::serializePayload(uint8_t *buf) {
142343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    serializeCodedUnsigned(mValue, buf);
143343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
144343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
145343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih//=================================================================================================
146343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
147343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmFloat::WebmFloat(uint64_t id, double value)
148343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(id, sizeof(double)), mValue(value) {
149343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
150343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
151343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmFloat::WebmFloat(uint64_t id, float value)
152343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(id, sizeof(float)), mValue(value) {
153343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
154343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
155343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihvoid WebmFloat::serializePayload(uint8_t *buf) {
156343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t data;
157343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    if (mSize == sizeof(float)) {
158343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        float f = mValue;
159343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        data = *reinterpret_cast<const uint32_t*>(&f);
160343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    } else {
161343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        data = *reinterpret_cast<const uint64_t*>(&mValue);
162343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
163343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    for (int i = mSize - 1; i >= 0; --i) {
164343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        buf[i] = data & 0xff;
165343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        data >>= 8;
166343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
167343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
168343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
169343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih//=================================================================================================
170343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
171343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmBinary::WebmBinary(uint64_t id, const sp<ABuffer> &ref)
172343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(id, ref->size()), mRef(ref) {
173343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
174343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
175343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihvoid WebmBinary::serializePayload(uint8_t *buf) {
176343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    memcpy(buf, mRef->data(), mRef->size());
177343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
178343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
179343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih//=================================================================================================
180343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
181343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmString::WebmString(uint64_t id, const char *str)
182343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(id, strlen(str)), mStr(str) {
183343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
184343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
185343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihvoid WebmString::serializePayload(uint8_t *buf) {
186343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    memcpy(buf, mStr, strlen(mStr));
187343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
188343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
189343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih//=================================================================================================
190343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
191343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmSimpleBlock::WebmSimpleBlock(
192343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int trackNum,
193343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int16_t relTimecode,
194343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        bool key,
195343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        const sp<ABuffer>& orig)
196343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    // ............................ trackNum*1 + timecode*2 + flags*1
197343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    //                                ^^^
198343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    // Only the least significant byte of trackNum is encoded
199343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(kMkvSimpleBlock, orig->size() + 4),
200343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih      mTrackNum(trackNum),
201343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih      mRelTimecode(relTimecode),
202343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih      mKey(key),
203343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih      mRef(orig) {
204343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
205343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
206343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihvoid WebmSimpleBlock::serializePayload(uint8_t *buf) {
207343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    serializeCodedUnsigned(encodeUnsigned(mTrackNum), buf);
208343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    buf[1] = (mRelTimecode & 0xff00) >> 8;
209343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    buf[2] = mRelTimecode & 0xff;
210343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    buf[3] = mKey ? 0x80 : 0;
211343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    memcpy(buf + 4, mRef->data(), mSize - 4);
212343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
213343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
214343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih//=================================================================================================
215343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
216343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihEbmlVoid::EbmlVoid(uint64_t totalSize)
217343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(kMkvVoid, voidSize(totalSize)),
218343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih      mSizeWidth(totalSize - sizeOf(kMkvVoid) - voidSize(totalSize)) {
219343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    CHECK_GE(voidSize(totalSize), 0);
220343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
221343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
222343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihint EbmlVoid::serializePayloadSize(uint8_t *buf) {
223343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return serializeCodedUnsigned(encodeUnsigned(mSize, mSizeWidth), buf);
224343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
225343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
226343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihvoid EbmlVoid::serializePayload(uint8_t *buf) {
227343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ::memset(buf, 0, mSize);
228343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return;
229343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
230343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
231343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih//=================================================================================================
232343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
233343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmMaster::WebmMaster(uint64_t id, const List<sp<WebmElement> >& children)
234343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(id, childrenSum(children)), mChildren(children) {
235343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
236343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
237343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert ShihWebmMaster::WebmMaster(uint64_t id)
238343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    : WebmElement(id, 0) {
239343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
240343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
241343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihint WebmMaster::serializePayloadSize(uint8_t *buf) {
242343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    if (mSize == 0){
243343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        return serializeCodedUnsigned(kMkvUnknownLength, buf);
244343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
245343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return WebmElement::serializePayloadSize(buf);
246343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
247343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
248343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihvoid WebmMaster::serializePayload(uint8_t *buf) {
249343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t off = 0;
250343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    for (List<sp<WebmElement> >::const_iterator it = mChildren.begin(); it != mChildren.end();
251343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            ++it) {
252343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        sp<WebmElement> child = (*it);
253343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        child->serializeInto(buf + off);
254343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        off += child->totalSize();
255343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
256343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
257343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
258343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih//=================================================================================================
259343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
260343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihsp<WebmElement> WebmElement::CuePointEntry(uint64_t time, int track, uint64_t off) {
261343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > cuePointEntryFields;
262343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    cuePointEntryFields.push_back(new WebmUnsigned(kMkvCueTrack, track));
263343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    cuePointEntryFields.push_back(new WebmUnsigned(kMkvCueClusterPosition, off));
264343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    WebmElement *cueTrackPositions = new WebmMaster(kMkvCueTrackPositions, cuePointEntryFields);
265343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
266343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    cuePointEntryFields.clear();
267343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    cuePointEntryFields.push_back(new WebmUnsigned(kMkvCueTime, time));
268343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    cuePointEntryFields.push_back(cueTrackPositions);
269343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return new WebmMaster(kMkvCuePoint, cuePointEntryFields);
270343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
271343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
272343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihsp<WebmElement> WebmElement::SeekEntry(uint64_t id, uint64_t off) {
273343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > seekEntryFields;
274343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    seekEntryFields.push_back(new WebmUnsigned(kMkvSeekId, id));
275343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    seekEntryFields.push_back(new WebmUnsigned(kMkvSeekPosition, off));
276343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return new WebmMaster(kMkvSeek, seekEntryFields);
277343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
278343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
279343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihsp<WebmElement> WebmElement::EbmlHeader(
280343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int ver,
281343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int readVer,
282343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int maxIdLen,
283343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int maxSizeLen,
284343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int docVer,
285343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int docReadVer) {
286343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > headerFields;
287343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    headerFields.push_back(new WebmUnsigned(kMkvEbmlVersion, ver));
288343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    headerFields.push_back(new WebmUnsigned(kMkvEbmlReadVersion, readVer));
289343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    headerFields.push_back(new WebmUnsigned(kMkvEbmlMaxIdlength, maxIdLen));
290343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    headerFields.push_back(new WebmUnsigned(kMkvEbmlMaxSizeLength, maxSizeLen));
291343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    headerFields.push_back(new WebmString(kMkvDocType, "webm"));
292343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    headerFields.push_back(new WebmUnsigned(kMkvDocTypeVersion, docVer));
293343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    headerFields.push_back(new WebmUnsigned(kMkvDocTypeReadVersion, docReadVer));
294343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return new WebmMaster(kMkvEbml, headerFields);
295343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
296343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
297343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihsp<WebmElement> WebmElement::SegmentInfo(uint64_t scale, double dur) {
298343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > segmentInfo;
299343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    // place duration first; easier to patch
300343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    segmentInfo.push_back(new WebmFloat(kMkvSegmentDuration, dur));
301343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    segmentInfo.push_back(new WebmUnsigned(kMkvTimecodeScale, scale));
302343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    segmentInfo.push_back(new WebmString(kMkvMuxingApp, "android"));
303343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    segmentInfo.push_back(new WebmString(kMkvWritingApp, "android"));
304343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return new WebmMaster(kMkvInfo, segmentInfo);
305343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
306343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
307343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihsp<WebmElement> WebmElement::AudioTrackEntry(
308343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int chans,
309343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        double rate,
310343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        const sp<ABuffer> &buf,
311343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int bps,
312343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        uint64_t uid,
313343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        bool lacing,
314343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        const char *lang) {
315343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    if (uid == 0) {
316343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        uid = kAudioTrackNum;
317343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
318343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
319343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > trackEntryFields;
320343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    populateCommonTrackEntries(
321343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            kAudioTrackNum,
322343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            uid,
323343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            lacing,
324343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            lang,
325343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            "A_VORBIS",
326343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            kAudioType,
327343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            trackEntryFields);
328343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
329343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > audioInfo;
330343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    audioInfo.push_back(new WebmUnsigned(kMkvChannels, chans));
331343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    audioInfo.push_back(new WebmFloat(kMkvSamplingFrequency, rate));
332343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    if (bps) {
333343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        WebmElement *bitDepth = new WebmUnsigned(kMkvBitDepth, bps);
334343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        audioInfo.push_back(bitDepth);
335343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
336343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
337343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    trackEntryFields.push_back(new WebmMaster(kMkvAudio, audioInfo));
338343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    trackEntryFields.push_back(new WebmBinary(kMkvCodecPrivate, buf));
339343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return new WebmMaster(kMkvTrackEntry, trackEntryFields);
340343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
341343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
342343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihsp<WebmElement> WebmElement::VideoTrackEntry(
34370b22a024d75bce04575c16ed49fc7991c8544a6Vignesh Venkatasubramanian        const char *codec,
344343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        uint64_t width,
345343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        uint64_t height,
346d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        const sp<MetaData> &meta,
347343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        uint64_t uid,
348343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        bool lacing,
349343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        const char *lang) {
350343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    if (uid == 0) {
351343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        uid = kVideoTrackNum;
352343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    }
353343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
354343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > trackEntryFields;
355343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    populateCommonTrackEntries(
356343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            kVideoTrackNum,
357343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            uid,
358343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            lacing,
359343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            lang,
36070b22a024d75bce04575c16ed49fc7991c8544a6Vignesh Venkatasubramanian            codec,
361343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            kVideoType,
362343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            trackEntryFields);
363343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
364d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar    // CSD
365d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar    uint32_t type;
366d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar    const void *data;
367d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar    size_t size;
368d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar    if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
369d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar        sp<ABuffer> buf = new ABuffer((void *)data, size); // note: buf does not own data
370d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar        trackEntryFields.push_back(new WebmBinary(kMkvCodecPrivate, buf));
371d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar    }
372d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar
373343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > videoInfo;
374343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    videoInfo.push_back(new WebmUnsigned(kMkvPixelWidth, width));
375343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    videoInfo.push_back(new WebmUnsigned(kMkvPixelHeight, height));
376343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
377d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar    // Color aspects
378d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar    {
379d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        List<sp<WebmElement> > colorInfo;
380d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar
381d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        ColorAspects aspects;
382d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
383d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        aspects.mTransfer = ColorAspects::TransferUnspecified;
384d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
385d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        aspects.mRange = ColorAspects::RangeUnspecified;
386d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        bool havePrimaries = meta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries);
387d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        bool haveTransfer = meta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer);
388d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        bool haveCoeffs = meta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs);
389d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        bool haveRange = meta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange);
390d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar
391d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        int32_t primaries, transfer, coeffs;
392d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        bool fullRange;
393d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        ColorUtils::convertCodecColorAspectsToIsoAspects(
394d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                aspects, &primaries, &transfer, &coeffs, &fullRange);
395d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        if (havePrimaries) {
39612c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar            colorInfo.push_back(new WebmUnsigned(kMkvPrimaries, primaries));
397d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        }
398d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        if (haveTransfer) {
39912c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar            colorInfo.push_back(new WebmUnsigned(kMkvTransferCharacteristics, transfer));
400d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        }
401d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        if (haveCoeffs) {
40212c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar            colorInfo.push_back(new WebmUnsigned(kMkvMatrixCoefficients, coeffs));
403d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        }
404d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        if (haveRange) {
40512c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar            colorInfo.push_back(new WebmUnsigned(kMkvRange, fullRange ? 2 : 1));
406d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        }
407d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar
408d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        // Also add HDR static info, some of which goes to MasteringMetadata element
409d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar
410d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        const HDRStaticInfo *info;
411d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        uint32_t type;
412d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        const void *data;
413d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        size_t size;
414d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
415d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                && type == 'hdrS' && size == sizeof(*info)) {
416d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar            info = (const HDRStaticInfo*)data;
417d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar            if (info->mID == HDRStaticInfo::kType1) {
418d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                List<sp<WebmElement> > masteringInfo;
419d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar
420d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                // convert HDRStaticInfo values to matroska equivalent values for each non-0 group
421d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                if (info->sType1.mMaxFrameAverageLightLevel) {
422d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    colorInfo.push_back(new WebmUnsigned(
42312c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvMaxFALL, info->sType1.mMaxFrameAverageLightLevel));
424d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                }
425d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                if (info->sType1.mMaxContentLightLevel) {
426d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    colorInfo.push_back(new WebmUnsigned(
42712c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvMaxCLL, info->sType1.mMaxContentLightLevel));
428d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                }
429d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                if (info->sType1.mMinDisplayLuminance) {
43012c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                    // HDRStaticInfo Type1 stores min luminance scaled 10000:1
431d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
43212c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvLuminanceMin, info->sType1.mMinDisplayLuminance * 0.0001));
433d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                }
434d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                if (info->sType1.mMaxDisplayLuminance) {
435d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
43612c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvLuminanceMax, (float)info->sType1.mMaxDisplayLuminance));
437d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                }
43812c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                // HDRStaticInfo Type1 stores primaries scaled 50000:1
439d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                if (info->sType1.mW.x || info->sType1.mW.y) {
440d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
44112c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvWhitePointChromaticityX, info->sType1.mW.x * 0.00002));
442d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
44312c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvWhitePointChromaticityY, info->sType1.mW.y * 0.00002));
444d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                }
44512c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                if (info->sType1.mR.x || info->sType1.mR.y || info->sType1.mG.x
446d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                        || info->sType1.mG.y || info->sType1.mB.x || info->sType1.mB.y) {
447d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
44812c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvPrimaryRChromaticityX, info->sType1.mR.x * 0.00002));
449d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
45012c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvPrimaryRChromaticityY, info->sType1.mR.y * 0.00002));
451d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
45212c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvPrimaryGChromaticityX, info->sType1.mG.x * 0.00002));
453d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
45412c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvPrimaryGChromaticityY, info->sType1.mG.y * 0.00002));
455d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
45612c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvPrimaryBChromaticityX, info->sType1.mB.x * 0.00002));
457d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    masteringInfo.push_back(new WebmFloat(
45812c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar                            kMkvPrimaryBChromaticityY, info->sType1.mB.y * 0.00002));
459d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                }
460d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                if (masteringInfo.size()) {
461d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                    colorInfo.push_back(new WebmMaster(kMkvMasteringMetadata, masteringInfo));
462d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                }
463d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar            }
464d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        }
465d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        if (colorInfo.size()) {
466d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar            videoInfo.push_back(new WebmMaster(kMkvColour, colorInfo));
467d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        }
468d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar    }
469d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar
470343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    trackEntryFields.push_back(new WebmMaster(kMkvVideo, videoInfo));
471343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    return new WebmMaster(kMkvTrackEntry, trackEntryFields);
472343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih}
473343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih} /* namespace android */
474