1 /*
2 * Copyright (C) 2012 Google 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 are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "modules/mediasource/WebKitSourceBuffer.h"
33
34 #include "bindings/v8/ExceptionState.h"
35 #include "core/dom/ExceptionCode.h"
36 #include "core/html/TimeRanges.h"
37 #include "modules/mediasource/WebKitMediaSource.h"
38 #include "platform/TraceEvent.h"
39 #include "public/platform/WebSourceBuffer.h"
40 #include "wtf/Uint8Array.h"
41
42 using blink::WebSourceBuffer;
43
44 namespace WebCore {
45
create(PassOwnPtr<WebSourceBuffer> webSourceBuffer,PassRefPtr<WebKitMediaSource> source)46 PassRefPtr<WebKitSourceBuffer> WebKitSourceBuffer::create(PassOwnPtr<WebSourceBuffer> webSourceBuffer, PassRefPtr<WebKitMediaSource> source)
47 {
48 return adoptRef(new WebKitSourceBuffer(webSourceBuffer, source));
49 }
50
WebKitSourceBuffer(PassOwnPtr<WebSourceBuffer> webSourceBuffer,PassRefPtr<WebKitMediaSource> source)51 WebKitSourceBuffer::WebKitSourceBuffer(PassOwnPtr<WebSourceBuffer> webSourceBuffer, PassRefPtr<WebKitMediaSource> source)
52 : m_webSourceBuffer(webSourceBuffer)
53 , m_source(source)
54 , m_timestampOffset(0)
55 {
56 ASSERT(m_webSourceBuffer);
57 ASSERT(m_source);
58 ScriptWrappable::init(this);
59 }
60
~WebKitSourceBuffer()61 WebKitSourceBuffer::~WebKitSourceBuffer()
62 {
63 }
64
buffered(ExceptionState & exceptionState) const65 PassRefPtr<TimeRanges> WebKitSourceBuffer::buffered(ExceptionState& exceptionState) const
66 {
67 // Section 3.1 buffered attribute steps.
68 // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an
69 // InvalidStateError exception and abort these steps.
70 if (isRemoved()) {
71 exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
72 return 0;
73 }
74
75 // 2. Return a new static normalized TimeRanges object for the media segments buffered.
76 return TimeRanges::create(m_webSourceBuffer->buffered());
77 }
78
timestampOffset() const79 double WebKitSourceBuffer::timestampOffset() const
80 {
81 return m_timestampOffset;
82 }
83
setTimestampOffset(double offset,ExceptionState & exceptionState)84 void WebKitSourceBuffer::setTimestampOffset(double offset, ExceptionState& exceptionState)
85 {
86 // Section 3.1 timestampOffset attribute setter steps.
87 // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an
88 // InvalidStateError exception and abort these steps.
89 if (isRemoved()) {
90 exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
91 return;
92 }
93
94 // 4. If the readyState attribute of the parent media source is in the "ended" state then run the following steps:
95 // 4.1 Set the readyState attribute of the parent media source to "open"
96 // 4.2 Queue a task to fire a simple event named sourceopen at the parent media source.
97 m_source->openIfInEndedState();
98
99 // 5. If this object is waiting for the end of a media segment to be appended, then throw an InvalidStateError
100 // and abort these steps.
101 if (!m_webSourceBuffer->setTimestampOffset(offset)) {
102 exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
103 return;
104 }
105
106 // 6. Update the attribute to the new value.
107 m_timestampOffset = offset;
108 }
109
append(PassRefPtr<Uint8Array> data,ExceptionState & exceptionState)110 void WebKitSourceBuffer::append(PassRefPtr<Uint8Array> data, ExceptionState& exceptionState)
111 {
112 TRACE_EVENT0("media", "SourceBuffer::append");
113
114 // SourceBuffer.append() steps from October 1st version of the Media Source Extensions spec.
115 // https://dvcs.w3.org/hg/html-media/raw-file/7bab66368f2c/media-source/media-source.html#dom-append
116
117 // 2. If data is null then throw an InvalidAccessError exception and abort these steps.
118 if (!data) {
119 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
120 return;
121 }
122
123 // 3. If this object has been removed from the sourceBuffers attribute of media source then throw
124 // an InvalidStateError exception and abort these steps.
125 if (isRemoved()) {
126 exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
127 return;
128 }
129
130 // 5. If the readyState attribute of media source is in the "ended" state then run the following steps:
131 // 5.1. Set the readyState attribute of media source to "open"
132 // 5.2. Queue a task to fire a simple event named sourceopen at media source.
133 m_source->openIfInEndedState();
134
135 // Steps 6 & beyond are handled by m_webSourceBuffer.
136 m_webSourceBuffer->append(data->data(), data->length());
137 }
138
abort(ExceptionState & exceptionState)139 void WebKitSourceBuffer::abort(ExceptionState& exceptionState)
140 {
141 // Section 3.2 abort() method steps.
142 // 1. If this object has been removed from the sourceBuffers attribute of the parent media source
143 // then throw an InvalidStateError exception and abort these steps.
144 // 2. If the readyState attribute of the parent media source is not in the "open" state
145 // then throw an InvalidStateError exception and abort these steps.
146 if (isRemoved() || !m_source->isOpen()) {
147 exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
148 return;
149 }
150
151 // 4. Run the reset parser state algorithm.
152 m_webSourceBuffer->abort();
153 }
154
removedFromMediaSource()155 void WebKitSourceBuffer::removedFromMediaSource()
156 {
157 if (isRemoved())
158 return;
159
160 m_webSourceBuffer->removedFromMediaSource();
161 m_source.clear();
162 }
163
isRemoved() const164 bool WebKitSourceBuffer::isRemoved() const
165 {
166 return !m_source;
167 }
168
169 } // namespace WebCore
170