944fbd8f4ad075407b7e27cf5244200547179d5f
[WebKit-https.git] / Source / WebCore / platform / graphics / ISOVTTCue.cpp
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "ISOVTTCue.h"
28
29 #include "Logging.h"
30 #include <runtime/ArrayBuffer.h>
31 #include <runtime/DataView.h>
32 #include <runtime/Int8Array.h>
33 #include <wtf/NeverDestroyed.h>
34 #include <wtf/text/CString.h>
35 #include <wtf/text/StringBuilder.h>
36
37 namespace JSC {
38 class ArrayBuffer;
39 }
40
41 namespace WebCore {
42
43 ISOBox::ISOBox(ArrayBuffer* data)
44 {
45     m_type = peekType(data);
46     m_length = peekLength(data);
47     ASSERT(m_length >= 8);
48 }
49
50 String ISOBox::peekType(ArrayBuffer* data)
51 {
52     ASSERT_WITH_SECURITY_IMPLICATION(data->byteLength() >= 2 * sizeof(uint32_t));
53     if (data->byteLength() < 2 * sizeof(uint32_t))
54         return emptyString();
55
56     StringBuilder builder;
57     RefPtr<Int8Array> array = JSC::Int8Array::create(data, 4, sizeof(uint32_t));
58     for (int i = 0; i < 4; ++i)
59         builder.append(array->item(i));
60     return builder.toString();
61 }
62
63 size_t ISOBox::peekLength(ArrayBuffer* data)
64 {
65     ASSERT_WITH_SECURITY_IMPLICATION(data->byteLength() >= sizeof(uint32_t));
66     if (data->byteLength() < sizeof(uint32_t))
67         return 0;
68
69     return JSC::DataView::create(data, 0, sizeof(uint32_t))->get<uint32_t>(0, false);
70 }
71
72 String ISOBox::peekString(ArrayBuffer* data, unsigned offset, unsigned length)
73 {
74     ASSERT_WITH_SECURITY_IMPLICATION(offset + length <= data->byteLength());
75     if (data->byteLength() < offset + length)
76         return emptyString();
77
78     return String(JSC::Uint8Array::create(data, offset, length)->data(), length);
79 }
80
81 static const AtomicString& vttCueBoxType()
82 {
83     static NeverDestroyed<AtomicString> vttc("vttc", AtomicString::ConstructFromLiteral);
84     return vttc;
85 }
86
87 static const AtomicString& vttIdBoxType()
88 {
89     static NeverDestroyed<AtomicString> iden("iden", AtomicString::ConstructFromLiteral);
90     return iden;
91 }
92
93 static const AtomicString& vttSettingsBoxType()
94 {
95     static NeverDestroyed<AtomicString> sttg("sttg", AtomicString::ConstructFromLiteral);
96     return sttg;
97 }
98
99 static const AtomicString& vttPayloadBoxType()
100 {
101     static NeverDestroyed<AtomicString> payl("payl", AtomicString::ConstructFromLiteral);
102     return payl;
103 }
104
105 static const AtomicString& vttCurrentTimeBoxType()
106 {
107     static NeverDestroyed<AtomicString> ctim("ctim", AtomicString::ConstructFromLiteral);
108     return ctim;
109 }
110
111 static const AtomicString& vttCueSourceIDBoxType()
112 {
113     static NeverDestroyed<AtomicString> vsid("vsid", AtomicString::ConstructFromLiteral);
114     return vsid;
115 }
116
117 const AtomicString& ISOWebVTTCue::boxType()
118 {
119     return vttCueBoxType();
120 }
121
122 ISOWebVTTCue::ISOWebVTTCue(const MediaTime& presentationTime, const MediaTime& duration, JSC::ArrayBuffer* buffer)
123     : ISOBox(buffer)
124     , m_presentationTime(presentationTime)
125     , m_duration(duration)
126 {
127     size_t offset = ISOBox::boxHeaderSize();
128     while (offset < length() && length() - offset > ISOBox::boxHeaderSize()) {
129         RefPtr<ArrayBuffer> subBuffer = buffer->slice(offset);
130         String boxType = ISOBox::peekType(subBuffer.get());
131         size_t boxSize = ISOBox::peekLength(subBuffer.get());
132         size_t boxDataSize = boxSize - ISOBox::boxHeaderSize();
133
134         if (boxType == vttCueSourceIDBoxType())
135             m_sourceID = peekString(subBuffer.get(), ISOBox::boxHeaderSize(), boxDataSize);
136         else if (boxType == vttIdBoxType())
137             m_identifer = peekString(subBuffer.get(), ISOBox::boxHeaderSize(), boxDataSize);
138         else if (boxType == vttCurrentTimeBoxType())
139             m_originalStartTime = peekString(subBuffer.get(), ISOBox::boxHeaderSize(), boxDataSize);
140         else if (boxType == vttSettingsBoxType())
141             m_settings = peekString(subBuffer.get(), ISOBox::boxHeaderSize(), boxDataSize);
142         else if (boxType == vttPayloadBoxType())
143             m_cueText = peekString(subBuffer.get(), ISOBox::boxHeaderSize(), boxDataSize);
144         else
145             LOG(Media, "ISOWebVTTCue::ISOWebVTTCue - skipping box id = \"%s\", size = %zu", boxType.utf8().data(), boxSize);
146
147         offset += boxSize;
148     }
149 }
150
151 } // namespace WebCore