Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 #include "platform/Logging.h" | 52 #include "platform/Logging.h" |
| 53 #include "platform/TraceEvent.h" | 53 #include "platform/TraceEvent.h" |
| 54 #include "public/platform/WebSourceBuffer.h" | 54 #include "public/platform/WebSourceBuffer.h" |
| 55 #include "wtf/MathExtras.h" | 55 #include "wtf/MathExtras.h" |
| 56 | 56 |
| 57 #include <limits> | 57 #include <limits> |
| 58 #include <sstream> | 58 #include <sstream> |
| 59 | 59 |
| 60 using blink::WebSourceBuffer; | 60 using blink::WebSourceBuffer; |
| 61 | 61 |
| 62 #define SOURCE_BUFFER_LOG_LEVEL 3 | |
| 63 | |
| 62 namespace blink { | 64 namespace blink { |
| 63 | 65 |
| 64 namespace { | 66 namespace { |
| 65 | 67 |
| 66 static bool throwExceptionIfRemovedOrUpdating(bool isRemoved, bool isUpdating, E xceptionState& exceptionState) | 68 static bool throwExceptionIfRemovedOrUpdating(bool isRemoved, bool isUpdating, E xceptionState& exceptionState) |
| 67 { | 69 { |
| 68 if (isRemoved) { | 70 if (isRemoved) { |
| 69 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "This SourceBuffer has been removed from the parent media source."); | 71 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "This SourceBuffer has been removed from the parent media source."); |
| 70 return true; | 72 return true; |
| 71 } | 73 } |
| 72 if (isUpdating) { | 74 if (isUpdating) { |
| 73 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "This SourceBuffer is still processing an 'appendBuffer', 'appendStream', or 're move' operation."); | 75 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "This SourceBuffer is still processing an 'appendBuffer', 'appendStream', or 're move' operation."); |
| 74 return true; | 76 return true; |
| 75 } | 77 } |
| 76 | 78 |
| 77 return false; | 79 return false; |
| 78 } | 80 } |
| 79 | 81 |
| 80 #if !LOG_DISABLED | |
| 81 WTF::String webTimeRangesToString(const WebTimeRanges& ranges) | 82 WTF::String webTimeRangesToString(const WebTimeRanges& ranges) |
| 82 { | 83 { |
| 83 StringBuilder stringBuilder; | 84 StringBuilder stringBuilder; |
| 84 stringBuilder.append("{"); | 85 stringBuilder.append("{"); |
| 85 for (auto& r : ranges) { | 86 for (auto& r : ranges) { |
| 86 stringBuilder.append(" ["); | 87 stringBuilder.append(" ["); |
| 87 stringBuilder.appendNumber(r.start); | 88 stringBuilder.appendNumber(r.start); |
| 88 stringBuilder.append(";"); | 89 stringBuilder.append(";"); |
| 89 stringBuilder.appendNumber(r.end); | 90 stringBuilder.appendNumber(r.end); |
| 90 stringBuilder.append("]"); | 91 stringBuilder.append("]"); |
| 91 } | 92 } |
| 92 stringBuilder.append(" }"); | 93 stringBuilder.append(" }"); |
| 93 return stringBuilder.toString(); | 94 return stringBuilder.toString(); |
| 94 } | 95 } |
| 95 #endif | |
| 96 | 96 |
| 97 } // namespace | 97 } // namespace |
| 98 | 98 |
| 99 SourceBuffer* SourceBuffer::create(PassOwnPtr<WebSourceBuffer> webSourceBuffer, MediaSource* source, GenericEventQueue* asyncEventQueue) | 99 SourceBuffer* SourceBuffer::create(PassOwnPtr<WebSourceBuffer> webSourceBuffer, MediaSource* source, GenericEventQueue* asyncEventQueue) |
| 100 { | 100 { |
| 101 SourceBuffer* sourceBuffer = new SourceBuffer(std::move(webSourceBuffer), so urce, asyncEventQueue); | 101 SourceBuffer* sourceBuffer = new SourceBuffer(std::move(webSourceBuffer), so urce, asyncEventQueue); |
| 102 sourceBuffer->suspendIfNeeded(); | 102 sourceBuffer->suspendIfNeeded(); |
| 103 return sourceBuffer; | 103 return sourceBuffer; |
| 104 } | 104 } |
| 105 | 105 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 118 , m_firstInitializationSegmentReceived(false) | 118 , m_firstInitializationSegmentReceived(false) |
| 119 , m_pendingAppendDataOffset(0) | 119 , m_pendingAppendDataOffset(0) |
| 120 , m_appendBufferAsyncPartRunner(AsyncMethodRunner<SourceBuffer>::create(this , &SourceBuffer::appendBufferAsyncPart)) | 120 , m_appendBufferAsyncPartRunner(AsyncMethodRunner<SourceBuffer>::create(this , &SourceBuffer::appendBufferAsyncPart)) |
| 121 , m_pendingRemoveStart(-1) | 121 , m_pendingRemoveStart(-1) |
| 122 , m_pendingRemoveEnd(-1) | 122 , m_pendingRemoveEnd(-1) |
| 123 , m_removeAsyncPartRunner(AsyncMethodRunner<SourceBuffer>::create(this, &Sou rceBuffer::removeAsyncPart)) | 123 , m_removeAsyncPartRunner(AsyncMethodRunner<SourceBuffer>::create(this, &Sou rceBuffer::removeAsyncPart)) |
| 124 , m_streamMaxSizeValid(false) | 124 , m_streamMaxSizeValid(false) |
| 125 , m_streamMaxSize(0) | 125 , m_streamMaxSize(0) |
| 126 , m_appendStreamAsyncPartRunner(AsyncMethodRunner<SourceBuffer>::create(this , &SourceBuffer::appendStreamAsyncPart)) | 126 , m_appendStreamAsyncPartRunner(AsyncMethodRunner<SourceBuffer>::create(this , &SourceBuffer::appendStreamAsyncPart)) |
| 127 { | 127 { |
| 128 ASSERT(m_webSourceBuffer); | 128 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ")"; |
| 129 ASSERT(m_source); | 129 |
| 130 ASSERT(m_source->mediaElement()); | 130 DCHECK(m_webSourceBuffer); |
| 131 DCHECK(m_source); | |
| 132 DCHECK(m_source->mediaElement()); | |
| 131 ThreadState::current()->registerPreFinalizer(this); | 133 ThreadState::current()->registerPreFinalizer(this); |
| 132 m_audioTracks = AudioTrackList::create(*m_source->mediaElement()); | 134 m_audioTracks = AudioTrackList::create(*m_source->mediaElement()); |
| 133 m_videoTracks = VideoTrackList::create(*m_source->mediaElement()); | 135 m_videoTracks = VideoTrackList::create(*m_source->mediaElement()); |
| 134 m_webSourceBuffer->setClient(this); | 136 m_webSourceBuffer->setClient(this); |
| 135 } | 137 } |
| 136 | 138 |
| 137 SourceBuffer::~SourceBuffer() | 139 SourceBuffer::~SourceBuffer() |
| 138 { | 140 { |
| 139 WTF_LOG(Media, "SourceBuffer(%p)::~SourceBuffer", this); | 141 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ")"; |
| 140 } | 142 } |
| 141 | 143 |
| 142 void SourceBuffer::dispose() | 144 void SourceBuffer::dispose() |
| 143 { | 145 { |
| 144 // Promptly clears a raw reference from content/ to an on-heap object | 146 // Promptly clears a raw reference from content/ to an on-heap object |
| 145 // so that content/ doesn't access it in a lazy sweeping phase. | 147 // so that content/ doesn't access it in a lazy sweeping phase. |
| 146 m_webSourceBuffer.clear(); | 148 m_webSourceBuffer.clear(); |
| 147 } | 149 } |
| 148 | 150 |
| 149 const AtomicString& SourceBuffer::segmentsKeyword() | 151 const AtomicString& SourceBuffer::segmentsKeyword() |
| 150 { | 152 { |
| 151 DEFINE_STATIC_LOCAL(const AtomicString, segments, ("segments")); | 153 DEFINE_STATIC_LOCAL(const AtomicString, segments, ("segments")); |
| 152 return segments; | 154 return segments; |
| 153 } | 155 } |
| 154 | 156 |
| 155 const AtomicString& SourceBuffer::sequenceKeyword() | 157 const AtomicString& SourceBuffer::sequenceKeyword() |
| 156 { | 158 { |
| 157 DEFINE_STATIC_LOCAL(const AtomicString, sequence, ("sequence")); | 159 DEFINE_STATIC_LOCAL(const AtomicString, sequence, ("sequence")); |
| 158 return sequence; | 160 return sequence; |
| 159 } | 161 } |
| 160 | 162 |
| 161 void SourceBuffer::setMode(const AtomicString& newMode, ExceptionState& exceptio nState) | 163 void SourceBuffer::setMode(const AtomicString& newMode, ExceptionState& exceptio nState) |
| 162 { | 164 { |
| 163 WTF_LOG(Media, "SourceBuffer::setMode %p newMode=%s", this, newMode.utf8().d ata()); | 165 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") newMode= " << newMode; |
| 164 // Section 3.1 On setting mode attribute steps. | 166 // Section 3.1 On setting mode attribute steps. |
| 165 // 1. Let new mode equal the new value being assigned to this attribute. | 167 // 1. Let new mode equal the new value being assigned to this attribute. |
| 166 // 2. If this object has been removed from the sourceBuffers attribute of th e parent media source, then throw | 168 // 2. If this object has been removed from the sourceBuffers attribute of th e parent media source, then throw |
| 167 // an INVALID_STATE_ERR exception and abort these steps. | 169 // an INVALID_STATE_ERR exception and abort these steps. |
| 168 // 3. If the updating attribute equals true, then throw an INVALID_STATE_ERR exception and abort these steps. | 170 // 3. If the updating attribute equals true, then throw an INVALID_STATE_ERR exception and abort these steps. |
| 169 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) | 171 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) |
| 170 return; | 172 return; |
| 171 | 173 |
| 172 // 4. If the readyState attribute of the parent media source is in the "ende d" state then run the following steps: | 174 // 4. If the readyState attribute of the parent media source is in the "ende d" state then run the following steps: |
| 173 // 4.1 Set the readyState attribute of the parent media source to "open" | 175 // 4.1 Set the readyState attribute of the parent media source to "open" |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 202 return TimeRanges::create(m_webSourceBuffer->buffered()); | 204 return TimeRanges::create(m_webSourceBuffer->buffered()); |
| 203 } | 205 } |
| 204 | 206 |
| 205 double SourceBuffer::timestampOffset() const | 207 double SourceBuffer::timestampOffset() const |
| 206 { | 208 { |
| 207 return m_timestampOffset; | 209 return m_timestampOffset; |
| 208 } | 210 } |
| 209 | 211 |
| 210 void SourceBuffer::setTimestampOffset(double offset, ExceptionState& exceptionSt ate) | 212 void SourceBuffer::setTimestampOffset(double offset, ExceptionState& exceptionSt ate) |
| 211 { | 213 { |
| 212 WTF_LOG(Media, "SourceBuffer::setTimestampOffset %p offset=%f", this, offset ); | 214 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") offset=" << offset; |
| 213 // Section 3.1 timestampOffset attribute setter steps. | 215 // Section 3.1 timestampOffset attribute setter steps. |
| 214 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source. html#widl-SourceBuffer-timestampOffset | 216 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source. html#widl-SourceBuffer-timestampOffset |
| 215 // 1. Let new timestamp offset equal the new value being assigned to this at tribute. | 217 // 1. Let new timestamp offset equal the new value being assigned to this at tribute. |
| 216 // 2. If this object has been removed from the sourceBuffers attribute of th e parent media source, then throw an | 218 // 2. If this object has been removed from the sourceBuffers attribute of th e parent media source, then throw an |
| 217 // InvalidStateError exception and abort these steps. | 219 // InvalidStateError exception and abort these steps. |
| 218 // 3. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. | 220 // 3. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. |
| 219 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) | 221 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) |
| 220 return; | 222 return; |
| 221 | 223 |
| 222 // 4. If the readyState attribute of the parent media source is in the "ende d" state then run the following steps: | 224 // 4. If the readyState attribute of the parent media source is in the "ende d" state then run the following steps: |
| 223 // 4.1 Set the readyState attribute of the parent media source to "open" | 225 // 4.1 Set the readyState attribute of the parent media source to "open" |
| 224 // 4.2 Queue a task to fire a simple event named sourceopen at the parent me dia source. | 226 // 4.2 Queue a task to fire a simple event named sourceopen at the parent me dia source. |
| 225 m_source->openIfInEndedState(); | 227 m_source->openIfInEndedState(); |
| 226 | 228 |
| 227 // 5. If the append state equals PARSING_MEDIA_SEGMENT, then throw an INVALI D_STATE_ERR and abort these steps. | 229 // 5. If the append state equals PARSING_MEDIA_SEGMENT, then throw an INVALI D_STATE_ERR and abort these steps. |
| 228 // 6. If the mode attribute equals "sequence", then set the group start time stamp to new timestamp offset. | 230 // 6. If the mode attribute equals "sequence", then set the group start time stamp to new timestamp offset. |
| 229 if (!m_webSourceBuffer->setTimestampOffset(offset)) { | 231 if (!m_webSourceBuffer->setTimestampOffset(offset)) { |
| 230 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "The timestamp offset may not be set while the SourceBuffer's append state is 'P ARSING_MEDIA_SEGMENT'."); | 232 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "The timestamp offset may not be set while the SourceBuffer's append state is 'P ARSING_MEDIA_SEGMENT'."); |
| 231 return; | 233 return; |
| 232 } | 234 } |
| 233 | 235 |
| 234 // 7. Update the attribute to new timestamp offset. | 236 // 7. Update the attribute to new timestamp offset. |
| 235 m_timestampOffset = offset; | 237 m_timestampOffset = offset; |
| 236 } | 238 } |
| 237 | 239 |
| 238 AudioTrackList& SourceBuffer::audioTracks() | 240 AudioTrackList& SourceBuffer::audioTracks() |
| 239 { | 241 { |
| 240 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | 242 DCHECK(RuntimeEnabledFeatures::audioVideoTracksEnabled()); |
| 241 return *m_audioTracks; | 243 return *m_audioTracks; |
| 242 } | 244 } |
| 243 | 245 |
| 244 VideoTrackList& SourceBuffer::videoTracks() | 246 VideoTrackList& SourceBuffer::videoTracks() |
| 245 { | 247 { |
| 246 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | 248 DCHECK(RuntimeEnabledFeatures::audioVideoTracksEnabled()); |
| 247 return *m_videoTracks; | 249 return *m_videoTracks; |
| 248 } | 250 } |
| 249 | 251 |
| 250 double SourceBuffer::appendWindowStart() const | 252 double SourceBuffer::appendWindowStart() const |
| 251 { | 253 { |
| 252 return m_appendWindowStart; | 254 return m_appendWindowStart; |
| 253 } | 255 } |
| 254 | 256 |
| 255 void SourceBuffer::setAppendWindowStart(double start, ExceptionState& exceptionS tate) | 257 void SourceBuffer::setAppendWindowStart(double start, ExceptionState& exceptionS tate) |
| 256 { | 258 { |
| 257 WTF_LOG(Media, "SourceBuffer::setAppendWindowStart %p start=%f", this, start ); | 259 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") start=" << start; |
| 258 // Section 3.1 appendWindowStart attribute setter steps. | 260 // Section 3.1 appendWindowStart attribute setter steps. |
| 259 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source. html#widl-SourceBuffer-appendWindowStart | 261 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source. html#widl-SourceBuffer-appendWindowStart |
| 260 // 1. If this object has been removed from the sourceBuffers attribute of th e parent media source then throw an | 262 // 1. If this object has been removed from the sourceBuffers attribute of th e parent media source then throw an |
| 261 // InvalidStateError exception and abort these steps. | 263 // InvalidStateError exception and abort these steps. |
| 262 // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. | 264 // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. |
| 263 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) | 265 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) |
| 264 return; | 266 return; |
| 265 | 267 |
| 266 // 3. If the new value is less than 0 or greater than or equal to appendWind owEnd then throw an InvalidAccessError | 268 // 3. If the new value is less than 0 or greater than or equal to appendWind owEnd then throw an InvalidAccessError |
| 267 // exception and abort these steps. | 269 // exception and abort these steps. |
| 268 if (start < 0 || start >= m_appendWindowEnd) { | 270 if (start < 0 || start >= m_appendWindowEnd) { |
| 269 MediaSource::logAndThrowDOMException(exceptionState, InvalidAccessError, ExceptionMessages::indexOutsideRange("value", start, 0.0, ExceptionMessages::Ex clusiveBound, m_appendWindowEnd, ExceptionMessages::InclusiveBound)); | 271 MediaSource::logAndThrowDOMException(exceptionState, InvalidAccessError, ExceptionMessages::indexOutsideRange("value", start, 0.0, ExceptionMessages::Ex clusiveBound, m_appendWindowEnd, ExceptionMessages::InclusiveBound)); |
| 270 return; | 272 return; |
| 271 } | 273 } |
| 272 | 274 |
| 273 m_webSourceBuffer->setAppendWindowStart(start); | 275 m_webSourceBuffer->setAppendWindowStart(start); |
| 274 | 276 |
| 275 // 4. Update the attribute to the new value. | 277 // 4. Update the attribute to the new value. |
| 276 m_appendWindowStart = start; | 278 m_appendWindowStart = start; |
| 277 } | 279 } |
| 278 | 280 |
| 279 double SourceBuffer::appendWindowEnd() const | 281 double SourceBuffer::appendWindowEnd() const |
| 280 { | 282 { |
| 281 return m_appendWindowEnd; | 283 return m_appendWindowEnd; |
| 282 } | 284 } |
| 283 | 285 |
| 284 void SourceBuffer::setAppendWindowEnd(double end, ExceptionState& exceptionState ) | 286 void SourceBuffer::setAppendWindowEnd(double end, ExceptionState& exceptionState ) |
| 285 { | 287 { |
| 286 WTF_LOG(Media, "SourceBuffer::setAppendWindowEnd %p end=%f", this, end); | 288 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") end=" << end; |
| 287 // Section 3.1 appendWindowEnd attribute setter steps. | 289 // Section 3.1 appendWindowEnd attribute setter steps. |
| 288 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source. html#widl-SourceBuffer-appendWindowEnd | 290 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source. html#widl-SourceBuffer-appendWindowEnd |
| 289 // 1. If this object has been removed from the sourceBuffers attribute of th e parent media source then throw an | 291 // 1. If this object has been removed from the sourceBuffers attribute of th e parent media source then throw an |
| 290 // InvalidStateError exception and abort these steps. | 292 // InvalidStateError exception and abort these steps. |
| 291 // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. | 293 // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. |
| 292 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) | 294 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) |
| 293 return; | 295 return; |
| 294 | 296 |
| 295 // 3. If the new value equals NaN, then throw an InvalidAccessError and abor t these steps. | 297 // 3. If the new value equals NaN, then throw an InvalidAccessError and abor t these steps. |
| 296 if (std::isnan(end)) { | 298 if (std::isnan(end)) { |
| 297 MediaSource::logAndThrowDOMException(exceptionState, InvalidAccessError, ExceptionMessages::notAFiniteNumber(end)); | 299 MediaSource::logAndThrowDOMException(exceptionState, InvalidAccessError, ExceptionMessages::notAFiniteNumber(end)); |
| 298 return; | 300 return; |
| 299 } | 301 } |
| 300 // 4. If the new value is less than or equal to appendWindowStart then throw an InvalidAccessError | 302 // 4. If the new value is less than or equal to appendWindowStart then throw an InvalidAccessError |
| 301 // exception and abort these steps. | 303 // exception and abort these steps. |
| 302 if (end <= m_appendWindowStart) { | 304 if (end <= m_appendWindowStart) { |
| 303 MediaSource::logAndThrowDOMException(exceptionState, InvalidAccessError, ExceptionMessages::indexExceedsMinimumBound("value", end, m_appendWindowStart)) ; | 305 MediaSource::logAndThrowDOMException(exceptionState, InvalidAccessError, ExceptionMessages::indexExceedsMinimumBound("value", end, m_appendWindowStart)) ; |
| 304 return; | 306 return; |
| 305 } | 307 } |
| 306 | 308 |
| 307 m_webSourceBuffer->setAppendWindowEnd(end); | 309 m_webSourceBuffer->setAppendWindowEnd(end); |
| 308 | 310 |
| 309 // 5. Update the attribute to the new value. | 311 // 5. Update the attribute to the new value. |
| 310 m_appendWindowEnd = end; | 312 m_appendWindowEnd = end; |
| 311 } | 313 } |
| 312 | 314 |
| 313 void SourceBuffer::appendBuffer(DOMArrayBuffer* data, ExceptionState& exceptionS tate) | 315 void SourceBuffer::appendBuffer(DOMArrayBuffer* data, ExceptionState& exceptionS tate) |
| 314 { | 316 { |
| 315 WTF_LOG(Media, "SourceBuffer(%p)::appendBuffer size=%u", this, data->byteLen gth()); | 317 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") size=" < < data->byteLength(); |
| 316 // Section 3.2 appendBuffer() | 318 // Section 3.2 appendBuffer() |
| 317 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data | 319 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data |
| 318 appendBufferInternal(static_cast<const unsigned char*>(data->data()), data-> byteLength(), exceptionState); | 320 appendBufferInternal(static_cast<const unsigned char*>(data->data()), data-> byteLength(), exceptionState); |
| 319 } | 321 } |
| 320 | 322 |
| 321 void SourceBuffer::appendBuffer(DOMArrayBufferView* data, ExceptionState& except ionState) | 323 void SourceBuffer::appendBuffer(DOMArrayBufferView* data, ExceptionState& except ionState) |
| 322 { | 324 { |
| 323 WTF_LOG(Media, "SourceBuffer(%p)::appendBuffer size=%u", this, data->byteLen gth()); | 325 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") size=" < < data->byteLength(); |
| 324 // Section 3.2 appendBuffer() | 326 // Section 3.2 appendBuffer() |
| 325 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data | 327 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data |
| 326 appendBufferInternal(static_cast<const unsigned char*>(data->baseAddress()), data->byteLength(), exceptionState); | 328 appendBufferInternal(static_cast<const unsigned char*>(data->baseAddress()), data->byteLength(), exceptionState); |
| 327 } | 329 } |
| 328 | 330 |
| 329 void SourceBuffer::appendStream(Stream* stream, ExceptionState& exceptionState) | 331 void SourceBuffer::appendStream(Stream* stream, ExceptionState& exceptionState) |
| 330 { | 332 { |
| 331 m_streamMaxSizeValid = false; | 333 m_streamMaxSizeValid = false; |
| 332 appendStreamInternal(stream, exceptionState); | 334 appendStreamInternal(stream, exceptionState); |
| 333 } | 335 } |
| 334 | 336 |
| 335 void SourceBuffer::appendStream(Stream* stream, unsigned long long maxSize, Exce ptionState& exceptionState) | 337 void SourceBuffer::appendStream(Stream* stream, unsigned long long maxSize, Exce ptionState& exceptionState) |
| 336 { | 338 { |
| 337 WTF_LOG(Media, "SourceBuffer(%p)::appendStream maxSize=%llu", this, maxSize) ; | 339 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") maxSize= " << maxSize; |
| 338 m_streamMaxSizeValid = maxSize > 0; | 340 m_streamMaxSizeValid = maxSize > 0; |
| 339 if (m_streamMaxSizeValid) | 341 if (m_streamMaxSizeValid) |
| 340 m_streamMaxSize = maxSize; | 342 m_streamMaxSize = maxSize; |
| 341 appendStreamInternal(stream, exceptionState); | 343 appendStreamInternal(stream, exceptionState); |
| 342 } | 344 } |
| 343 | 345 |
| 344 void SourceBuffer::abort(ExceptionState& exceptionState) | 346 void SourceBuffer::abort(ExceptionState& exceptionState) |
| 345 { | 347 { |
| 346 WTF_LOG(Media, "SourceBuffer::abort %p", this); | 348 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ")"; |
| 347 // Section 3.2 abort() method steps. | 349 // Section 3.2 abort() method steps. |
| 348 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-abort-void | 350 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-abort-void |
| 349 // 1. If this object has been removed from the sourceBuffers attribute of th e parent media source | 351 // 1. If this object has been removed from the sourceBuffers attribute of th e parent media source |
| 350 // then throw an InvalidStateError exception and abort these steps. | 352 // then throw an InvalidStateError exception and abort these steps. |
| 351 // 2. If the readyState attribute of the parent media source is not in the " open" state | 353 // 2. If the readyState attribute of the parent media source is not in the " open" state |
| 352 // then throw an InvalidStateError exception and abort these steps. | 354 // then throw an InvalidStateError exception and abort these steps. |
| 353 if (isRemoved()) { | 355 if (isRemoved()) { |
| 354 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "This SourceBuffer has been removed from the parent media source."); | 356 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "This SourceBuffer has been removed from the parent media source."); |
| 355 return; | 357 return; |
| 356 } | 358 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 367 | 369 |
| 368 // 5. Set appendWindowStart to 0. | 370 // 5. Set appendWindowStart to 0. |
| 369 setAppendWindowStart(0, exceptionState); | 371 setAppendWindowStart(0, exceptionState); |
| 370 | 372 |
| 371 // 6. Set appendWindowEnd to positive Infinity. | 373 // 6. Set appendWindowEnd to positive Infinity. |
| 372 setAppendWindowEnd(std::numeric_limits<double>::infinity(), exceptionState); | 374 setAppendWindowEnd(std::numeric_limits<double>::infinity(), exceptionState); |
| 373 } | 375 } |
| 374 | 376 |
| 375 void SourceBuffer::remove(double start, double end, ExceptionState& exceptionSta te) | 377 void SourceBuffer::remove(double start, double end, ExceptionState& exceptionSta te) |
| 376 { | 378 { |
| 377 WTF_LOG(Media, "SourceBuffer(%p)::remove start=%f end=%f", this, start, end) ; | 379 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") start=" << start << " end=" << end; |
| 378 | 380 |
| 379 // Section 3.2 remove() method steps. | 381 // Section 3.2 remove() method steps. |
| 380 // 1. If duration equals NaN, then throw an InvalidAccessError exception and abort these steps. | 382 // 1. If duration equals NaN, then throw an InvalidAccessError exception and abort these steps. |
| 381 // 2. If start is negative or greater than duration, then throw an InvalidAc cessError exception and abort these steps. | 383 // 2. If start is negative or greater than duration, then throw an InvalidAc cessError exception and abort these steps. |
| 382 | 384 |
| 383 if (start < 0 || (m_source && (std::isnan(m_source->duration()) || start > m _source->duration()))) { | 385 if (start < 0 || (m_source && (std::isnan(m_source->duration()) || start > m _source->duration()))) { |
| 384 MediaSource::logAndThrowDOMException(exceptionState, InvalidAccessError, ExceptionMessages::indexOutsideRange("start", start, 0.0, ExceptionMessages::Ex clusiveBound, !m_source || std::isnan(m_source->duration()) ? 0 : m_source->dura tion(), ExceptionMessages::ExclusiveBound)); | 386 MediaSource::logAndThrowDOMException(exceptionState, InvalidAccessError, ExceptionMessages::indexOutsideRange("start", start, 0.0, ExceptionMessages::Ex clusiveBound, !m_source || std::isnan(m_source->duration()) ? 0 : m_source->dura tion(), ExceptionMessages::ExclusiveBound)); |
| 385 return; | 387 return; |
| 386 } | 388 } |
| 387 | 389 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 return; | 444 return; |
| 443 | 445 |
| 444 const char* traceEventName = 0; | 446 const char* traceEventName = 0; |
| 445 if (!m_pendingAppendData.isEmpty()) { | 447 if (!m_pendingAppendData.isEmpty()) { |
| 446 traceEventName = "SourceBuffer::appendBuffer"; | 448 traceEventName = "SourceBuffer::appendBuffer"; |
| 447 } else if (m_stream) { | 449 } else if (m_stream) { |
| 448 traceEventName = "SourceBuffer::appendStream"; | 450 traceEventName = "SourceBuffer::appendStream"; |
| 449 } else if (m_pendingRemoveStart != -1) { | 451 } else if (m_pendingRemoveStart != -1) { |
| 450 traceEventName = "SourceBuffer::remove"; | 452 traceEventName = "SourceBuffer::remove"; |
| 451 } else { | 453 } else { |
| 452 ASSERT_NOT_REACHED(); | 454 NOTREACHED(); |
| 453 } | 455 } |
| 454 | 456 |
| 455 // 3.1. Abort the buffer append and stream append loop algorithms if they ar e running. | 457 // 3.1. Abort the buffer append and stream append loop algorithms if they ar e running. |
| 456 m_appendBufferAsyncPartRunner->stop(); | 458 m_appendBufferAsyncPartRunner->stop(); |
| 457 m_pendingAppendData.clear(); | 459 m_pendingAppendData.clear(); |
| 458 m_pendingAppendDataOffset = 0; | 460 m_pendingAppendDataOffset = 0; |
| 459 | 461 |
| 460 m_removeAsyncPartRunner->stop(); | 462 m_removeAsyncPartRunner->stop(); |
| 461 m_pendingRemoveStart = -1; | 463 m_pendingRemoveStart = -1; |
| 462 m_pendingRemoveEnd = -1; | 464 m_pendingRemoveEnd = -1; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 474 scheduleEvent(EventTypeNames::updateend); | 476 scheduleEvent(EventTypeNames::updateend); |
| 475 | 477 |
| 476 TRACE_EVENT_ASYNC_END0("media", traceEventName, this); | 478 TRACE_EVENT_ASYNC_END0("media", traceEventName, this); |
| 477 } | 479 } |
| 478 | 480 |
| 479 void SourceBuffer::removedFromMediaSource() | 481 void SourceBuffer::removedFromMediaSource() |
| 480 { | 482 { |
| 481 if (isRemoved()) | 483 if (isRemoved()) |
| 482 return; | 484 return; |
| 483 | 485 |
| 484 WTF_LOG(Media, "SourceBuffer(%p)::removedFromMediaSource", this); | 486 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ")"; |
| 485 abortIfUpdating(); | 487 abortIfUpdating(); |
| 486 | 488 |
| 487 if (RuntimeEnabledFeatures::audioVideoTracksEnabled()) { | 489 if (RuntimeEnabledFeatures::audioVideoTracksEnabled()) { |
| 488 ASSERT(m_source); | 490 DCHECK(m_source); |
| 489 if (m_source->mediaElement()->audioTracks().length() > 0 | 491 if (m_source->mediaElement()->audioTracks().length() > 0 |
| 490 || m_source->mediaElement()->videoTracks().length() > 0) { | 492 || m_source->mediaElement()->videoTracks().length() > 0) { |
| 491 removeMediaTracks(); | 493 removeMediaTracks(); |
| 492 } | 494 } |
| 493 } | 495 } |
| 494 | 496 |
| 495 m_webSourceBuffer->removedFromMediaSource(); | 497 m_webSourceBuffer->removedFromMediaSource(); |
| 496 m_webSourceBuffer.clear(); | 498 m_webSourceBuffer.clear(); |
| 497 m_source = nullptr; | 499 m_source = nullptr; |
| 498 m_asyncEventQueue = nullptr; | 500 m_asyncEventQueue = nullptr; |
| 499 } | 501 } |
| 500 | 502 |
| 501 void SourceBuffer::removeMediaTracks() | 503 void SourceBuffer::removeMediaTracks() |
| 502 { | 504 { |
| 503 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | 505 DCHECK(RuntimeEnabledFeatures::audioVideoTracksEnabled()); |
| 504 // Spec: http://w3c.github.io/media-source/#widl-MediaSource-removeSourceBuf fer-void-SourceBuffer-sourceBuffer | 506 // Spec: http://w3c.github.io/media-source/#widl-MediaSource-removeSourceBuf fer-void-SourceBuffer-sourceBuffer |
| 505 ASSERT(m_source); | 507 DCHECK(m_source); |
| 506 | 508 |
| 507 HTMLMediaElement* mediaElement = m_source->mediaElement(); | 509 HTMLMediaElement* mediaElement = m_source->mediaElement(); |
| 508 ASSERT(mediaElement); | 510 DCHECK(mediaElement); |
| 509 // 3. Let SourceBuffer audioTracks list equal the AudioTrackList object retu rned by sourceBuffer.audioTracks. | 511 // 3. Let SourceBuffer audioTracks list equal the AudioTrackList object retu rned by sourceBuffer.audioTracks. |
| 510 // 4. If the SourceBuffer audioTracks list is not empty, then run the follow ing steps: | 512 // 4. If the SourceBuffer audioTracks list is not empty, then run the follow ing steps: |
| 511 // 4.1 Let HTMLMediaElement audioTracks list equal the AudioTrackList object returned by the audioTracks attribute on the HTMLMediaElement. | 513 // 4.1 Let HTMLMediaElement audioTracks list equal the AudioTrackList object returned by the audioTracks attribute on the HTMLMediaElement. |
| 512 // 4.2 Let the removed enabled audio track flag equal false. | 514 // 4.2 Let the removed enabled audio track flag equal false. |
| 513 bool removedEnabledAudioTrack = false; | 515 bool removedEnabledAudioTrack = false; |
| 514 // 4.3 For each AudioTrack object in the SourceBuffer audioTracks list, run the following steps: | 516 // 4.3 For each AudioTrack object in the SourceBuffer audioTracks list, run the following steps: |
| 515 while (audioTracks().length() > 0) { | 517 while (audioTracks().length() > 0) { |
| 516 AudioTrack* audioTrack = audioTracks().anonymousIndexedGetter(0); | 518 AudioTrack* audioTrack = audioTracks().anonymousIndexedGetter(0); |
| 517 // 4.3.1 Set the sourceBuffer attribute on the AudioTrack object to null . | 519 // 4.3.1 Set the sourceBuffer attribute on the AudioTrack object to null . |
| 518 SourceBufferTrackBaseSupplement::setSourceBuffer(*audioTrack, nullptr); | 520 SourceBufferTrackBaseSupplement::setSourceBuffer(*audioTrack, nullptr); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 // > If more than one track for a single type are present (ie 2 audio tracks ), then the Track IDs match the ones in the first initialization segment. | 572 // > If more than one track for a single type are present (ie 2 audio tracks ), then the Track IDs match the ones in the first initialization segment. |
| 571 // I.e. we only need to search by TrackID if there is more than one track, o therwise we can assume that the only | 573 // I.e. we only need to search by TrackID if there is more than one track, o therwise we can assume that the only |
| 572 // track of the given type is the same one that we had in previous init segm ents. | 574 // track of the given type is the same one that we had in previous init segm ents. |
| 573 if (trackList.length() == 1) | 575 if (trackList.length() == 1) |
| 574 return trackList.anonymousIndexedGetter(0); | 576 return trackList.anonymousIndexedGetter(0); |
| 575 return trackList.getTrackById(id); | 577 return trackList.getTrackById(id); |
| 576 } | 578 } |
| 577 | 579 |
| 578 WebVector<WebMediaPlayer::TrackId> SourceBuffer::initializationSegmentReceived(c onst WebVector<MediaTrackInfo>& newTracks) | 580 WebVector<WebMediaPlayer::TrackId> SourceBuffer::initializationSegmentReceived(c onst WebVector<MediaTrackInfo>& newTracks) |
| 579 { | 581 { |
| 580 WTF_LOG(Media, "SourceBuffer::initializationSegmentReceived %p tracks=%zu", this, newTracks.size()); | 582 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") tracks=" << newTracks.size(); |
| 581 ASSERT(m_source); | 583 DCHECK(m_source); |
| 582 ASSERT(m_source->mediaElement()); | 584 DCHECK(m_source->mediaElement()); |
| 583 ASSERT(m_updating); | 585 DCHECK(m_updating); |
| 584 | 586 |
| 585 // TODO(servolk): Implement proper 'initialization segment received' algorit hm according to MSE spec: | 587 // TODO(servolk): Implement proper 'initialization segment received' algorit hm according to MSE spec: |
| 586 // https://w3c.github.io/media-source/#sourcebuffer-init-segment-received | 588 // https://w3c.github.io/media-source/#sourcebuffer-init-segment-received |
| 587 WebVector<WebMediaPlayer::TrackId> result(newTracks.size()); | 589 WebVector<WebMediaPlayer::TrackId> result(newTracks.size()); |
| 588 unsigned resultIdx = 0; | 590 unsigned resultIdx = 0; |
| 589 for (const auto& trackInfo : newTracks) { | 591 for (const auto& trackInfo : newTracks) { |
| 590 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) { | 592 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) { |
| 591 static WebMediaPlayer::TrackId nextTrackId = 0; | 593 static WebMediaPlayer::TrackId nextTrackId = 0; |
| 592 result[resultIdx++] = ++nextTrackId; | 594 result[resultIdx++] = ++nextTrackId; |
| 593 continue; | 595 continue; |
| 594 } | 596 } |
| 595 | 597 |
| 596 const TrackBase* trackBase = nullptr; | 598 const TrackBase* trackBase = nullptr; |
| 597 if (trackInfo.trackType == WebMediaPlayer::AudioTrack) { | 599 if (trackInfo.trackType == WebMediaPlayer::AudioTrack) { |
| 598 AudioTrack* audioTrack = nullptr; | 600 AudioTrack* audioTrack = nullptr; |
| 599 if (!m_firstInitializationSegmentReceived) { | 601 if (!m_firstInitializationSegmentReceived) { |
| 600 audioTrack = AudioTrack::create(trackInfo.byteStreamTrackId, tra ckInfo.kind, trackInfo.label, trackInfo.language, false); | 602 audioTrack = AudioTrack::create(trackInfo.byteStreamTrackId, tra ckInfo.kind, trackInfo.label, trackInfo.language, false); |
| 601 SourceBufferTrackBaseSupplement::setSourceBuffer(*audioTrack, th is); | 603 SourceBufferTrackBaseSupplement::setSourceBuffer(*audioTrack, th is); |
| 602 audioTracks().add(audioTrack); | 604 audioTracks().add(audioTrack); |
| 603 m_source->mediaElement()->audioTracks().add(audioTrack); | 605 m_source->mediaElement()->audioTracks().add(audioTrack); |
| 604 } else { | 606 } else { |
| 605 audioTrack = findExistingTrackById(audioTracks(), trackInfo.byte StreamTrackId); | 607 audioTrack = findExistingTrackById(audioTracks(), trackInfo.byte StreamTrackId); |
| 606 ASSERT(audioTrack); | 608 DCHECK(audioTrack); |
| 607 } | 609 } |
| 608 trackBase = audioTrack; | 610 trackBase = audioTrack; |
| 609 result[resultIdx++] = audioTrack->trackId(); | 611 result[resultIdx++] = audioTrack->trackId(); |
| 610 } else if (trackInfo.trackType == WebMediaPlayer::VideoTrack) { | 612 } else if (trackInfo.trackType == WebMediaPlayer::VideoTrack) { |
| 611 VideoTrack* videoTrack = nullptr; | 613 VideoTrack* videoTrack = nullptr; |
| 612 if (!m_firstInitializationSegmentReceived) { | 614 if (!m_firstInitializationSegmentReceived) { |
| 613 videoTrack = VideoTrack::create(trackInfo.byteStreamTrackId, tra ckInfo.kind, trackInfo.label, trackInfo.language, false); | 615 videoTrack = VideoTrack::create(trackInfo.byteStreamTrackId, tra ckInfo.kind, trackInfo.label, trackInfo.language, false); |
| 614 SourceBufferTrackBaseSupplement::setSourceBuffer(*videoTrack, th is); | 616 SourceBufferTrackBaseSupplement::setSourceBuffer(*videoTrack, th is); |
| 615 videoTracks().add(videoTrack); | 617 videoTracks().add(videoTrack); |
| 616 m_source->mediaElement()->videoTracks().add(videoTrack); | 618 m_source->mediaElement()->videoTracks().add(videoTrack); |
| 617 } else { | 619 } else { |
| 618 videoTrack = findExistingTrackById(videoTracks(), trackInfo.byte StreamTrackId); | 620 videoTrack = findExistingTrackById(videoTracks(), trackInfo.byte StreamTrackId); |
| 619 ASSERT(videoTrack); | 621 DCHECK(videoTrack); |
| 620 } | 622 } |
| 621 trackBase = videoTrack; | 623 trackBase = videoTrack; |
| 622 result[resultIdx++] = videoTrack->trackId(); | 624 result[resultIdx++] = videoTrack->trackId(); |
| 623 } else { | 625 } else { |
| 624 NOTREACHED(); | 626 NOTREACHED(); |
| 625 } | 627 } |
| 626 (void)trackBase; | 628 (void)trackBase; |
| 627 #if !LOG_DISABLED | 629 #if !LOG_DISABLED |
| 628 const char* logActionStr = m_firstInitializationSegmentReceived ? "using existing" : "added"; | 630 const char* logActionStr = m_firstInitializationSegmentReceived ? "using existing" : "added"; |
| 629 const char* logTrackTypeStr = (trackInfo.trackType == WebMediaPlayer::Au dioTrack) ? "audio" : "video"; | 631 const char* logTrackTypeStr = (trackInfo.trackType == WebMediaPlayer::Au dioTrack) ? "audio" : "video"; |
| 630 WTF_LOG(Media, "Tracks (sb=%p): %s %sTrack %p trackId=%d id=%s label=%s lang=%s", this, logActionStr, logTrackTypeStr, trackBase, trackBase->trackId(), trackBase->id().utf8().data(), trackBase->label().utf8().data(), trackBase->lang uage().utf8().data()); | 632 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") " << logActionStr << " " |
| 633 << logTrackTypeStr << " Track " << trackBase << "trackId=" << trackBase- >trackId() << " id=" | |
|
wolenetz
2016/05/31 17:46:18
nit: indentation
Srirama
2016/06/01 11:39:35
Done.
| |
| 634 << trackBase->id() << " label=" << trackBase->label() << " lang=" << tra ckBase->language(); | |
| 631 #endif | 635 #endif |
| 632 } | 636 } |
| 633 | 637 |
| 634 if (!m_firstInitializationSegmentReceived) { | 638 if (!m_firstInitializationSegmentReceived) { |
| 635 // 5. If active track flag equals true, then run the following steps: | 639 // 5. If active track flag equals true, then run the following steps: |
| 636 // 5.1. Add this SourceBuffer to activeSourceBuffers. | 640 // 5.1. Add this SourceBuffer to activeSourceBuffers. |
| 637 // 5.2. Queue a task to fire a simple event named addsourcebuffer at | 641 // 5.2. Queue a task to fire a simple event named addsourcebuffer at |
| 638 // activesourcebuffers. | 642 // activesourcebuffers. |
| 639 m_source->setSourceBufferActive(this); | 643 m_source->setSourceBufferActive(this); |
| 640 | 644 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 681 return EventTargetNames::SourceBuffer; | 685 return EventTargetNames::SourceBuffer; |
| 682 } | 686 } |
| 683 | 687 |
| 684 bool SourceBuffer::isRemoved() const | 688 bool SourceBuffer::isRemoved() const |
| 685 { | 689 { |
| 686 return !m_source; | 690 return !m_source; |
| 687 } | 691 } |
| 688 | 692 |
| 689 void SourceBuffer::scheduleEvent(const AtomicString& eventName) | 693 void SourceBuffer::scheduleEvent(const AtomicString& eventName) |
| 690 { | 694 { |
| 691 ASSERT(m_asyncEventQueue); | 695 DCHECK(m_asyncEventQueue); |
| 692 | 696 |
| 693 Event* event = Event::create(eventName); | 697 Event* event = Event::create(eventName); |
| 694 event->setTarget(this); | 698 event->setTarget(this); |
| 695 | 699 |
| 696 m_asyncEventQueue->enqueueEvent(event); | 700 m_asyncEventQueue->enqueueEvent(event); |
| 697 } | 701 } |
| 698 | 702 |
| 699 bool SourceBuffer::prepareAppend(size_t newDataSize, ExceptionState& exceptionSt ate) | 703 bool SourceBuffer::prepareAppend(size_t newDataSize, ExceptionState& exceptionSt ate) |
| 700 { | 704 { |
| 701 TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::prepareAppend", this); | 705 TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::prepareAppend", this); |
| 702 // http://w3c.github.io/media-source/#sourcebuffer-prepare-append | 706 // http://w3c.github.io/media-source/#sourcebuffer-prepare-append |
| 703 // 3.5.4 Prepare Append Algorithm | 707 // 3.5.4 Prepare Append Algorithm |
| 704 // 1. If the SourceBuffer has been removed from the sourceBuffers attribute of the parent media source then throw an InvalidStateError exception and abort t hese steps. | 708 // 1. If the SourceBuffer has been removed from the sourceBuffers attribute of the parent media source then throw an InvalidStateError exception and abort t hese steps. |
| 705 // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. | 709 // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. |
| 706 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) { | 710 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) { |
| 707 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this); | 711 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this); |
| 708 return false; | 712 return false; |
| 709 } | 713 } |
| 710 | 714 |
| 711 // 3. If the HTMLMediaElement.error attribute is not null, then throw an Inv alidStateError exception and abort these steps. | 715 // 3. If the HTMLMediaElement.error attribute is not null, then throw an Inv alidStateError exception and abort these steps. |
| 712 ASSERT(m_source); | 716 DCHECK(m_source); |
| 713 ASSERT(m_source->mediaElement()); | 717 DCHECK(m_source->mediaElement()); |
| 714 if (m_source->mediaElement()->error()) { | 718 if (m_source->mediaElement()->error()) { |
| 715 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "The HTMLMediaElement.error attribute is not null."); | 719 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "The HTMLMediaElement.error attribute is not null."); |
| 716 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this); | 720 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this); |
| 717 return false; | 721 return false; |
| 718 } | 722 } |
| 719 | 723 |
| 720 // 4. If the readyState attribute of the parent media source is in the "ende d" state then run the following steps: | 724 // 4. If the readyState attribute of the parent media source is in the "ende d" state then run the following steps: |
| 721 // 1. Set the readyState attribute of the parent media source to "open" | 725 // 1. Set the readyState attribute of the parent media source to "open" |
| 722 // 2. Queue a task to fire a simple event named sourceopen at the parent media source. | 726 // 2. Queue a task to fire a simple event named sourceopen at the parent media source. |
| 723 m_source->openIfInEndedState(); | 727 m_source->openIfInEndedState(); |
| 724 | 728 |
| 725 // 5. Run the coded frame eviction algorithm. | 729 // 5. Run the coded frame eviction algorithm. |
| 726 if (!evictCodedFrames(newDataSize)) { | 730 if (!evictCodedFrames(newDataSize)) { |
| 727 // 6. If the buffer full flag equals true, then throw a QUOTA_EXCEEDED_E RR exception and abort these steps. | 731 // 6. If the buffer full flag equals true, then throw a QUOTA_EXCEEDED_E RR exception and abort these steps. |
| 728 WTF_LOG(Media, "SourceBuffer(%p)::prepareAppend -> throw QuotaExceededEr ror", this); | 732 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") -> t hrow QuotaExceededError"; |
| 729 MediaSource::logAndThrowDOMException(exceptionState, QuotaExceededError, "The SourceBuffer is full, and cannot free space to append additional buffers." ); | 733 MediaSource::logAndThrowDOMException(exceptionState, QuotaExceededError, "The SourceBuffer is full, and cannot free space to append additional buffers." ); |
| 730 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this); | 734 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this); |
| 731 return false; | 735 return false; |
| 732 } | 736 } |
| 733 | 737 |
| 734 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this); | 738 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this); |
| 735 return true; | 739 return true; |
| 736 } | 740 } |
| 737 | 741 |
| 738 bool SourceBuffer::evictCodedFrames(size_t newDataSize) | 742 bool SourceBuffer::evictCodedFrames(size_t newDataSize) |
| 739 { | 743 { |
| 740 ASSERT(m_source); | 744 DCHECK(m_source); |
| 741 ASSERT(m_source->mediaElement()); | 745 DCHECK(m_source->mediaElement()); |
| 742 double currentTime = m_source->mediaElement()->currentTime(); | 746 double currentTime = m_source->mediaElement()->currentTime(); |
| 743 bool result = m_webSourceBuffer->evictCodedFrames(currentTime, newDataSize); | 747 bool result = m_webSourceBuffer->evictCodedFrames(currentTime, newDataSize); |
| 744 if (!result) { | 748 DVLOG_IF(SOURCE_BUFFER_LOG_LEVEL, !result) << __FUNCTION__ << "(" << this << ") failed. newDataSize=" << newDataSize |
| 745 WTF_LOG(Media, "SourceBuffer(%p)::evictCodedFrames failed. newDataSize=% zu currentTime=%f buffered=%s", this, newDataSize, currentTime, webTimeRangesToS tring(m_webSourceBuffer->buffered()).utf8().data()); | 749 << " currentTime=" << currentTime << " buffered=" << webTimeRangesToString(m _webSourceBuffer->buffered()); |
| 746 } | |
| 747 return result; | 750 return result; |
| 748 } | 751 } |
| 749 | 752 |
| 750 void SourceBuffer::appendBufferInternal(const unsigned char* data, unsigned size , ExceptionState& exceptionState) | 753 void SourceBuffer::appendBufferInternal(const unsigned char* data, unsigned size , ExceptionState& exceptionState) |
| 751 { | 754 { |
| 752 TRACE_EVENT_ASYNC_BEGIN1("media", "SourceBuffer::appendBuffer", this, "size" , size); | 755 TRACE_EVENT_ASYNC_BEGIN1("media", "SourceBuffer::appendBuffer", this, "size" , size); |
| 753 // Section 3.2 appendBuffer() | 756 // Section 3.2 appendBuffer() |
| 754 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data | 757 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data |
| 755 | 758 |
| 756 // 1. Run the prepare append algorithm. | 759 // 1. Run the prepare append algorithm. |
| 757 if (!prepareAppend(size, exceptionState)) { | 760 if (!prepareAppend(size, exceptionState)) { |
| 758 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this); | 761 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this); |
| 759 return; | 762 return; |
| 760 } | 763 } |
| 761 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "p repareAppend"); | 764 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "p repareAppend"); |
| 762 | 765 |
| 763 // 2. Add data to the end of the input buffer. | 766 // 2. Add data to the end of the input buffer. |
| 764 ASSERT(data || size == 0); | 767 DCHECK_EQ(size, 0u); |
|
Srirama
2016/05/23 13:46:18
Removed assert for "data" as we are already checki
wolenetz
2016/05/31 17:46:18
The original condition was correct:
Caller either
Srirama
2016/06/01 11:39:35
Done.
| |
| 765 if (data) | 768 if (data) |
| 766 m_pendingAppendData.append(data, size); | 769 m_pendingAppendData.append(data, size); |
| 767 m_pendingAppendDataOffset = 0; | 770 m_pendingAppendDataOffset = 0; |
| 768 | 771 |
| 769 // 3. Set the updating attribute to true. | 772 // 3. Set the updating attribute to true. |
| 770 m_updating = true; | 773 m_updating = true; |
| 771 | 774 |
| 772 // 4. Queue a task to fire a simple event named updatestart at this SourceBu ffer object. | 775 // 4. Queue a task to fire a simple event named updatestart at this SourceBu ffer object. |
| 773 scheduleEvent(EventTypeNames::updatestart); | 776 scheduleEvent(EventTypeNames::updatestart); |
| 774 | 777 |
| 775 // 5. Asynchronously run the buffer append algorithm. | 778 // 5. Asynchronously run the buffer append algorithm. |
| 776 m_appendBufferAsyncPartRunner->runAsync(); | 779 m_appendBufferAsyncPartRunner->runAsync(); |
| 777 | 780 |
| 778 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "i nitialDelay"); | 781 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "i nitialDelay"); |
| 779 } | 782 } |
| 780 | 783 |
| 781 void SourceBuffer::appendBufferAsyncPart() | 784 void SourceBuffer::appendBufferAsyncPart() |
| 782 { | 785 { |
| 783 ASSERT(m_updating); | 786 DCHECK(m_updating); |
| 784 | 787 |
| 785 // Section 3.5.4 Buffer Append Algorithm | 788 // Section 3.5.4 Buffer Append Algorithm |
| 786 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#sourcebuffer-buffer-append | 789 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#sourcebuffer-buffer-append |
| 787 | 790 |
| 788 // 1. Run the segment parser loop algorithm. | 791 // 1. Run the segment parser loop algorithm. |
| 789 // Step 2 doesn't apply since we run Step 1 synchronously here. | 792 // Step 2 doesn't apply since we run Step 1 synchronously here. |
| 790 ASSERT(m_pendingAppendData.size() >= m_pendingAppendDataOffset); | 793 DCHECK_GE(m_pendingAppendData.size(), m_pendingAppendDataOffset); |
| 791 size_t appendSize = m_pendingAppendData.size() - m_pendingAppendDataOffset; | 794 size_t appendSize = m_pendingAppendData.size() - m_pendingAppendDataOffset; |
| 792 | 795 |
| 793 // Impose an arbitrary max size for a single append() call so that an append | 796 // Impose an arbitrary max size for a single append() call so that an append |
| 794 // doesn't block the renderer event loop very long. This value was selected | 797 // doesn't block the renderer event loop very long. This value was selected |
| 795 // by looking at YouTube SourceBuffer usage across a variety of bitrates. | 798 // by looking at YouTube SourceBuffer usage across a variety of bitrates. |
| 796 // This value allows relatively large appends while keeping append() call | 799 // This value allows relatively large appends while keeping append() call |
| 797 // duration in the ~5-15ms range. | 800 // duration in the ~5-15ms range. |
| 798 const size_t MaxAppendSize = 128 * 1024; | 801 const size_t MaxAppendSize = 128 * 1024; |
| 799 if (appendSize > MaxAppendSize) | 802 if (appendSize > MaxAppendSize) |
| 800 appendSize = MaxAppendSize; | 803 appendSize = MaxAppendSize; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 823 m_updating = false; | 826 m_updating = false; |
| 824 m_pendingAppendData.clear(); | 827 m_pendingAppendData.clear(); |
| 825 m_pendingAppendDataOffset = 0; | 828 m_pendingAppendDataOffset = 0; |
| 826 | 829 |
| 827 // 4. Queue a task to fire a simple event named update at this SourceBuffer object. | 830 // 4. Queue a task to fire a simple event named update at this SourceBuffer object. |
| 828 scheduleEvent(EventTypeNames::update); | 831 scheduleEvent(EventTypeNames::update); |
| 829 | 832 |
| 830 // 5. Queue a task to fire a simple event named updateend at this SourceBuff er object. | 833 // 5. Queue a task to fire a simple event named updateend at this SourceBuff er object. |
| 831 scheduleEvent(EventTypeNames::updateend); | 834 scheduleEvent(EventTypeNames::updateend); |
| 832 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this); | 835 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this); |
| 833 WTF_LOG(Media, "SourceBuffer(%p)::appendBuffer ended. buffered=%s", this, we bTimeRangesToString(m_webSourceBuffer->buffered()).utf8().data()); | 836 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") ended. b uffered=" << webTimeRangesToString(m_webSourceBuffer->buffered()); |
| 834 } | 837 } |
| 835 | 838 |
| 836 void SourceBuffer::removeAsyncPart() | 839 void SourceBuffer::removeAsyncPart() |
| 837 { | 840 { |
| 838 ASSERT(m_updating); | 841 DCHECK(m_updating); |
| 839 ASSERT(m_pendingRemoveStart >= 0); | 842 DCHECK_GE(m_pendingRemoveStart, 0); |
| 840 ASSERT(m_pendingRemoveStart < m_pendingRemoveEnd); | 843 DCHECK_LT(m_pendingRemoveStart, m_pendingRemoveEnd); |
| 841 | 844 |
| 842 // Section 3.2 remove() method steps | 845 // Section 3.2 remove() method steps |
| 843 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-remove-void-double-start-double-end | 846 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-remove-void-double-start-double-end |
| 844 | 847 |
| 845 // 9. Run the coded frame removal algorithm with start and end as the start and end of the removal range. | 848 // 9. Run the coded frame removal algorithm with start and end as the start and end of the removal range. |
| 846 m_webSourceBuffer->remove(m_pendingRemoveStart, m_pendingRemoveEnd); | 849 m_webSourceBuffer->remove(m_pendingRemoveStart, m_pendingRemoveEnd); |
| 847 | 850 |
| 848 // 10. Set the updating attribute to false. | 851 // 10. Set the updating attribute to false. |
| 849 m_updating = false; | 852 m_updating = false; |
| 850 m_pendingRemoveStart = -1; | 853 m_pendingRemoveStart = -1; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 885 | 888 |
| 886 // 4. Asynchronously run the stream append loop algorithm with stream and ma xSize. | 889 // 4. Asynchronously run the stream append loop algorithm with stream and ma xSize. |
| 887 stream->neuter(); | 890 stream->neuter(); |
| 888 m_loader = FileReaderLoader::create(FileReaderLoader::ReadByClient, this); | 891 m_loader = FileReaderLoader::create(FileReaderLoader::ReadByClient, this); |
| 889 m_stream = stream; | 892 m_stream = stream; |
| 890 m_appendStreamAsyncPartRunner->runAsync(); | 893 m_appendStreamAsyncPartRunner->runAsync(); |
| 891 } | 894 } |
| 892 | 895 |
| 893 void SourceBuffer::appendStreamAsyncPart() | 896 void SourceBuffer::appendStreamAsyncPart() |
| 894 { | 897 { |
| 895 ASSERT(m_updating); | 898 DCHECK(m_updating); |
| 896 ASSERT(m_loader); | 899 DCHECK(m_loader); |
| 897 ASSERT(m_stream); | 900 DCHECK(m_stream); |
| 898 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendStream", this, "a ppendStreamAsyncPart"); | 901 TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendStream", this, "a ppendStreamAsyncPart"); |
| 899 | 902 |
| 900 // Section 3.5.6 Stream Append Loop | 903 // Section 3.5.6 Stream Append Loop |
| 901 // http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop | 904 // http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop |
| 902 | 905 |
| 903 // 1. If maxSize is set, then let bytesLeft equal maxSize. | 906 // 1. If maxSize is set, then let bytesLeft equal maxSize. |
| 904 // 2. Loop Top: If maxSize is set and bytesLeft equals 0, then jump to the l oop done step below. | 907 // 2. Loop Top: If maxSize is set and bytesLeft equals 0, then jump to the l oop done step below. |
| 905 if (m_streamMaxSizeValid && !m_streamMaxSize) { | 908 if (m_streamMaxSizeValid && !m_streamMaxSize) { |
| 906 appendStreamDone(true); | 909 appendStreamDone(true); |
| 907 return; | 910 return; |
| 908 } | 911 } |
| 909 | 912 |
| 910 // Steps 3-11 are handled by m_loader. | 913 // Steps 3-11 are handled by m_loader. |
| 911 // Note: Passing 0 here signals that maxSize was not set. (i.e. Read all the data in the stream). | 914 // Note: Passing 0 here signals that maxSize was not set. (i.e. Read all the data in the stream). |
| 912 m_loader->start(getExecutionContext(), *m_stream, m_streamMaxSizeValid ? m_s treamMaxSize : 0); | 915 m_loader->start(getExecutionContext(), *m_stream, m_streamMaxSizeValid ? m_s treamMaxSize : 0); |
| 913 } | 916 } |
| 914 | 917 |
| 915 void SourceBuffer::appendStreamDone(bool success) | 918 void SourceBuffer::appendStreamDone(bool success) |
| 916 { | 919 { |
| 917 ASSERT(m_updating); | 920 DCHECK(m_updating); |
| 918 ASSERT(m_loader); | 921 DCHECK(m_loader); |
| 919 ASSERT(m_stream); | 922 DCHECK(m_stream); |
| 920 | 923 |
| 921 clearAppendStreamState(); | 924 clearAppendStreamState(); |
| 922 | 925 |
| 923 if (!success) { | 926 if (!success) { |
| 924 appendError(false); | 927 appendError(false); |
| 925 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); | 928 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); |
| 926 return; | 929 return; |
| 927 } | 930 } |
| 928 | 931 |
| 929 // Section 3.5.6 Stream Append Loop | 932 // Section 3.5.6 Stream Append Loop |
| 930 // Steps 1-11 are handled by appendStreamAsyncPart(), |m_loader|, and |m_web SourceBuffer|. | 933 // Steps 1-11 are handled by appendStreamAsyncPart(), |m_loader|, and |m_web SourceBuffer|. |
| 931 | 934 |
| 932 // 12. Loop Done: Set the updating attribute to false. | 935 // 12. Loop Done: Set the updating attribute to false. |
| 933 m_updating = false; | 936 m_updating = false; |
| 934 | 937 |
| 935 // 13. Queue a task to fire a simple event named update at this SourceBuffer object. | 938 // 13. Queue a task to fire a simple event named update at this SourceBuffer object. |
| 936 scheduleEvent(EventTypeNames::update); | 939 scheduleEvent(EventTypeNames::update); |
| 937 | 940 |
| 938 // 14. Queue a task to fire a simple event named updateend at this SourceBuf fer object. | 941 // 14. Queue a task to fire a simple event named updateend at this SourceBuf fer object. |
| 939 scheduleEvent(EventTypeNames::updateend); | 942 scheduleEvent(EventTypeNames::updateend); |
| 940 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); | 943 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); |
| 941 WTF_LOG(Media, "SourceBuffer(%p)::appendStream ended. buffered=%s", this, we bTimeRangesToString(m_webSourceBuffer->buffered()).utf8().data()); | 944 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") ended. b uffered=" << webTimeRangesToString(m_webSourceBuffer->buffered()); |
| 942 } | 945 } |
| 943 | 946 |
| 944 void SourceBuffer::clearAppendStreamState() | 947 void SourceBuffer::clearAppendStreamState() |
| 945 { | 948 { |
| 946 m_streamMaxSizeValid = false; | 949 m_streamMaxSizeValid = false; |
| 947 m_streamMaxSize = 0; | 950 m_streamMaxSize = 0; |
| 948 m_loader.clear(); | 951 m_loader.clear(); |
| 949 m_stream = nullptr; | 952 m_stream = nullptr; |
| 950 } | 953 } |
| 951 | 954 |
| 952 void SourceBuffer::appendError(bool decodeError) | 955 void SourceBuffer::appendError(bool decodeError) |
| 953 { | 956 { |
| 954 WTF_LOG(Media, "SourceBuffer::appendError %p decodeError=%d", this, decodeEr ror); | 957 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") decodeEr ror=" << decodeError; |
| 955 // Section 3.5.3 Append Error Algorithm | 958 // Section 3.5.3 Append Error Algorithm |
| 956 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#sourcebuffer-append-error | 959 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#sourcebuffer-append-error |
| 957 | 960 |
| 958 // 1. Run the reset parser state algorithm. | 961 // 1. Run the reset parser state algorithm. |
| 959 m_webSourceBuffer->resetParserState(); | 962 m_webSourceBuffer->resetParserState(); |
| 960 | 963 |
| 961 // 2. Set the updating attribute to false. | 964 // 2. Set the updating attribute to false. |
| 962 m_updating = false; | 965 m_updating = false; |
| 963 | 966 |
| 964 // 3. Queue a task to fire a simple event named error at this SourceBuffer o bject. | 967 // 3. Queue a task to fire a simple event named error at this SourceBuffer o bject. |
| 965 scheduleEvent(EventTypeNames::error); | 968 scheduleEvent(EventTypeNames::error); |
| 966 | 969 |
| 967 // 4. Queue a task to fire a simple event named updateend at this SourceBuff er object. | 970 // 4. Queue a task to fire a simple event named updateend at this SourceBuff er object. |
| 968 scheduleEvent(EventTypeNames::updateend); | 971 scheduleEvent(EventTypeNames::updateend); |
| 969 | 972 |
| 970 // 5. If decode error is true, then run the end of stream algorithm with the | 973 // 5. If decode error is true, then run the end of stream algorithm with the |
| 971 // error parameter set to "decode". | 974 // error parameter set to "decode". |
| 972 if (decodeError) | 975 if (decodeError) |
| 973 m_source->endOfStream("decode", ASSERT_NO_EXCEPTION); | 976 m_source->endOfStream("decode", ASSERT_NO_EXCEPTION); |
| 974 } | 977 } |
| 975 | 978 |
| 976 void SourceBuffer::didStartLoading() | 979 void SourceBuffer::didStartLoading() |
| 977 { | 980 { |
| 978 WTF_LOG(Media, "SourceBuffer(%p)::didStartLoading", this); | 981 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ")"; |
| 979 } | 982 } |
| 980 | 983 |
| 981 void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength ) | 984 void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength ) |
| 982 { | 985 { |
| 983 WTF_LOG(Media, "SourceBuffer(%p)::didReceiveDataForClient dataLength=%u", th is, dataLength); | 986 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") dataLeng th=" << dataLength; |
| 984 ASSERT(m_updating); | 987 DCHECK(m_updating); |
| 985 ASSERT(m_loader); | 988 DCHECK(m_loader); |
| 986 | 989 |
| 987 // Section 3.5.6 Stream Append Loop | 990 // Section 3.5.6 Stream Append Loop |
| 988 // http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop | 991 // http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop |
| 989 | 992 |
| 990 // 10. Run the coded frame eviction algorithm. | 993 // 10. Run the coded frame eviction algorithm. |
| 991 if (!evictCodedFrames(dataLength)) { | 994 if (!evictCodedFrames(dataLength)) { |
| 992 // 11. (in appendStreamDone) If the buffer full flag equals true, then r un the append error algorithm with the decode error parameter set to false and a bort this algorithm. | 995 // 11. (in appendStreamDone) If the buffer full flag equals true, then r un the append error algorithm with the decode error parameter set to false and a bort this algorithm. |
| 993 appendStreamDone(false); | 996 appendStreamDone(false); |
| 994 return; | 997 return; |
| 995 } | 998 } |
| 996 | 999 |
| 997 m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), data Length, &m_timestampOffset); | 1000 m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), data Length, &m_timestampOffset); |
| 998 } | 1001 } |
| 999 | 1002 |
| 1000 void SourceBuffer::didFinishLoading() | 1003 void SourceBuffer::didFinishLoading() |
| 1001 { | 1004 { |
| 1002 WTF_LOG(Media, "SourceBuffer(%p)::didFinishLoading", this); | 1005 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ")"; |
| 1003 ASSERT(m_loader); | 1006 DCHECK(m_loader); |
| 1004 appendStreamDone(true); | 1007 appendStreamDone(true); |
| 1005 } | 1008 } |
| 1006 | 1009 |
| 1007 void SourceBuffer::didFail(FileError::ErrorCode errorCode) | 1010 void SourceBuffer::didFail(FileError::ErrorCode errorCode) |
| 1008 { | 1011 { |
| 1009 WTF_LOG(Media, "SourceBuffer(%p)::didFail errorCode=%d", this, errorCode); | 1012 DVLOG(SOURCE_BUFFER_LOG_LEVEL) << __FUNCTION__ << "(" << this << ") errorCod e=" << errorCode; |
| 1010 // m_loader might be already released, in case appendStream has failed due | 1013 // m_loader might be already released, in case appendStream has failed due |
| 1011 // to evictCodedFrames failing in didReceiveDataForClient. In that case | 1014 // to evictCodedFrames failing in didReceiveDataForClient. In that case |
| 1012 // appendStreamDone will be invoked from there, no need to repeat it here. | 1015 // appendStreamDone will be invoked from there, no need to repeat it here. |
| 1013 if (m_loader) | 1016 if (m_loader) |
| 1014 appendStreamDone(false); | 1017 appendStreamDone(false); |
| 1015 } | 1018 } |
| 1016 | 1019 |
| 1017 DEFINE_TRACE(SourceBuffer) | 1020 DEFINE_TRACE(SourceBuffer) |
| 1018 { | 1021 { |
| 1019 visitor->trace(m_source); | 1022 visitor->trace(m_source); |
| 1020 visitor->trace(m_trackDefaults); | 1023 visitor->trace(m_trackDefaults); |
| 1021 visitor->trace(m_asyncEventQueue); | 1024 visitor->trace(m_asyncEventQueue); |
| 1022 visitor->trace(m_appendBufferAsyncPartRunner); | 1025 visitor->trace(m_appendBufferAsyncPartRunner); |
| 1023 visitor->trace(m_removeAsyncPartRunner); | 1026 visitor->trace(m_removeAsyncPartRunner); |
| 1024 visitor->trace(m_appendStreamAsyncPartRunner); | 1027 visitor->trace(m_appendStreamAsyncPartRunner); |
| 1025 visitor->trace(m_stream); | 1028 visitor->trace(m_stream); |
| 1026 visitor->trace(m_audioTracks); | 1029 visitor->trace(m_audioTracks); |
| 1027 visitor->trace(m_videoTracks); | 1030 visitor->trace(m_videoTracks); |
| 1028 EventTargetWithInlineData::trace(visitor); | 1031 EventTargetWithInlineData::trace(visitor); |
| 1029 ActiveDOMObject::trace(visitor); | 1032 ActiveDOMObject::trace(visitor); |
| 1030 } | 1033 } |
| 1031 | 1034 |
| 1032 } // namespace blink | 1035 } // namespace blink |
| OLD | NEW |