Home | History | Annotate | Download | only in mediasource
      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 
     46 PassRefPtr<WebKitSourceBuffer> WebKitSourceBuffer::create(PassOwnPtr<WebSourceBuffer> webSourceBuffer, PassRefPtr<WebKitMediaSource> source)
     47 {
     48     return adoptRef(new WebKitSourceBuffer(webSourceBuffer, source));
     49 }
     50 
     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 
     61 WebKitSourceBuffer::~WebKitSourceBuffer()
     62 {
     63 }
     64 
     65 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 
     79 double WebKitSourceBuffer::timestampOffset() const
     80 {
     81     return m_timestampOffset;
     82 }
     83 
     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 
    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 
    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 
    155 void WebKitSourceBuffer::removedFromMediaSource()
    156 {
    157     if (isRemoved())
    158         return;
    159 
    160     m_webSourceBuffer->removedFromMediaSource();
    161     m_source.clear();
    162 }
    163 
    164 bool WebKitSourceBuffer::isRemoved() const
    165 {
    166     return !m_source;
    167 }
    168 
    169 } // namespace WebCore
    170