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 21 matching lines...) Expand all Loading... | |
32 | 32 |
33 #include "bindings/core/v8/ExceptionMessages.h" | 33 #include "bindings/core/v8/ExceptionMessages.h" |
34 #include "bindings/core/v8/ExceptionState.h" | 34 #include "bindings/core/v8/ExceptionState.h" |
35 #include "core/dom/DOMArrayBuffer.h" | 35 #include "core/dom/DOMArrayBuffer.h" |
36 #include "core/dom/DOMArrayBufferView.h" | 36 #include "core/dom/DOMArrayBufferView.h" |
37 #include "core/dom/ExceptionCode.h" | 37 #include "core/dom/ExceptionCode.h" |
38 #include "core/dom/ExecutionContext.h" | 38 #include "core/dom/ExecutionContext.h" |
39 #include "core/events/Event.h" | 39 #include "core/events/Event.h" |
40 #include "core/events/GenericEventQueue.h" | 40 #include "core/events/GenericEventQueue.h" |
41 #include "core/fileapi/FileReaderLoader.h" | 41 #include "core/fileapi/FileReaderLoader.h" |
42 #include "core/frame/Deprecation.h" | |
43 #include "core/frame/UseCounter.h" | |
42 #include "core/html/HTMLMediaElement.h" | 44 #include "core/html/HTMLMediaElement.h" |
43 #include "core/html/MediaError.h" | 45 #include "core/html/MediaError.h" |
44 #include "core/html/TimeRanges.h" | 46 #include "core/html/TimeRanges.h" |
45 #include "core/html/track/AudioTrack.h" | 47 #include "core/html/track/AudioTrack.h" |
46 #include "core/html/track/AudioTrackList.h" | 48 #include "core/html/track/AudioTrackList.h" |
47 #include "core/html/track/VideoTrack.h" | 49 #include "core/html/track/VideoTrack.h" |
48 #include "core/html/track/VideoTrackList.h" | 50 #include "core/html/track/VideoTrackList.h" |
49 #include "core/streams/Stream.h" | 51 #include "core/streams/Stream.h" |
50 #include "modules/mediasource/MediaSource.h" | 52 #include "modules/mediasource/MediaSource.h" |
51 #include "modules/mediasource/SourceBufferTrackBaseSupplement.h" | 53 #include "modules/mediasource/SourceBufferTrackBaseSupplement.h" |
52 #include "platform/Logging.h" | 54 #include "platform/Logging.h" |
55 #include "platform/RuntimeEnabledFeatures.h" | |
53 #include "platform/TraceEvent.h" | 56 #include "platform/TraceEvent.h" |
54 #include "public/platform/WebSourceBuffer.h" | 57 #include "public/platform/WebSourceBuffer.h" |
55 #include "wtf/MathExtras.h" | 58 #include "wtf/MathExtras.h" |
56 #include <limits> | 59 #include <limits> |
57 #include <memory> | 60 #include <memory> |
58 #include <sstream> | 61 #include <sstream> |
59 | 62 |
60 using blink::WebSourceBuffer; | 63 using blink::WebSourceBuffer; |
61 | 64 |
62 #define SBLOG DVLOG(3) | 65 #define SBLOG DVLOG(3) |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 SBLOG << __FUNCTION__ << " this=" << this << " maxSize=" << maxSize; | 342 SBLOG << __FUNCTION__ << " this=" << this << " maxSize=" << maxSize; |
340 m_streamMaxSizeValid = maxSize > 0; | 343 m_streamMaxSizeValid = maxSize > 0; |
341 if (m_streamMaxSizeValid) | 344 if (m_streamMaxSizeValid) |
342 m_streamMaxSize = maxSize; | 345 m_streamMaxSize = maxSize; |
343 appendStreamInternal(stream, exceptionState); | 346 appendStreamInternal(stream, exceptionState); |
344 } | 347 } |
345 | 348 |
346 void SourceBuffer::abort(ExceptionState& exceptionState) | 349 void SourceBuffer::abort(ExceptionState& exceptionState) |
347 { | 350 { |
348 SBLOG << __FUNCTION__ << " this=" << this; | 351 SBLOG << __FUNCTION__ << " this=" << this; |
349 // Section 3.2 abort() method steps. | 352 // http://w3c.github.io/media-source/#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 | |
351 // 1. If this object has been removed from the sourceBuffers attribute of th e parent media source | 353 // 1. If this object has been removed from the sourceBuffers attribute of th e parent media source |
352 // then throw an InvalidStateError exception and abort these steps. | 354 // then throw an InvalidStateError exception and abort these steps. |
353 // 2. If the readyState attribute of the parent media source is not in the " open" state | 355 // 2. If the readyState attribute of the parent media source is not in the " open" state |
354 // then throw an InvalidStateError exception and abort these steps. | 356 // then throw an InvalidStateError exception and abort these steps. |
355 if (isRemoved()) { | 357 if (isRemoved()) { |
356 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "This SourceBuffer has been removed from the parent media source."); | 358 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "This SourceBuffer has been removed from the parent media source."); |
357 return; | 359 return; |
358 } | 360 } |
359 if (!m_source->isOpen()) { | 361 if (!m_source->isOpen()) { |
360 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "The parent media source's readyState is not 'open'."); | 362 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError, "The parent media source's readyState is not 'open'."); |
361 return; | 363 return; |
362 } | 364 } |
363 | 365 |
364 // 3. If the sourceBuffer.updating attribute equals true, then run the follo wing steps: ... | 366 // 3. If the range removal algorithm is running, then throw an |
367 // InvalidStateError exception and abort these steps. | |
368 if (m_pendingRemoveStart != -1) { | |
369 DCHECK(m_updating); | |
370 // Throwing the exception and aborting these steps is new behavior that | |
371 // is implemented behind the MediaSourceNewAbortAndDuration | |
372 // RuntimeEnabledFeature. | |
373 if (RuntimeEnabledFeatures::mediaSourceNewAbortAndDurationEnabled()) { | |
374 MediaSource::logAndThrowDOMException(exceptionState, InvalidStateErr or, "Aborting asynchronous remove() operation is disallowed."); | |
375 return; | |
376 } | |
377 | |
378 Deprecation::countDeprecation(m_source->mediaElement()->document(), UseC ounter::MediaSourceAbortRemove); | |
379 cancelRemove(); | |
380 } | |
381 | |
382 // 4. If the sourceBuffer.updating attribute equals true, then run the follo wing steps: ... | |
365 abortIfUpdating(); | 383 abortIfUpdating(); |
366 | 384 |
367 // 4. Run the reset parser state algorithm. | 385 // 5. Run the reset parser state algorithm. |
368 m_webSourceBuffer->resetParserState(); | 386 m_webSourceBuffer->resetParserState(); |
369 | 387 |
370 // 5. Set appendWindowStart to 0. | 388 // 6. Set appendWindowStart to 0. |
371 setAppendWindowStart(0, exceptionState); | 389 setAppendWindowStart(0, exceptionState); |
372 | 390 |
373 // 6. Set appendWindowEnd to positive Infinity. | 391 // 7. Set appendWindowEnd to positive Infinity. |
374 setAppendWindowEnd(std::numeric_limits<double>::infinity(), exceptionState); | 392 setAppendWindowEnd(std::numeric_limits<double>::infinity(), exceptionState); |
375 } | 393 } |
376 | 394 |
377 void SourceBuffer::remove(double start, double end, ExceptionState& exceptionSta te) | 395 void SourceBuffer::remove(double start, double end, ExceptionState& exceptionSta te) |
378 { | 396 { |
379 SBLOG << __FUNCTION__ << " this=" << this << " start=" << start << " end=" < < end; | 397 SBLOG << __FUNCTION__ << " this=" << this << " start=" << start << " end=" < < end; |
380 | 398 |
381 // Section 3.2 remove() method steps. | 399 // Section 3.2 remove() method steps. |
382 // 1. If duration equals NaN, then throw an InvalidAccessError exception and abort these steps. | 400 // 1. If duration equals NaN, then throw an InvalidAccessError 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. | 401 // 2. If start is negative or greater than duration, then throw an InvalidAc cessError exception and abort these steps. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
428 // and abort these steps. | 446 // and abort these steps. |
429 // 2. If the updating attribute equals true, then throw an InvalidStateError | 447 // 2. If the updating attribute equals true, then throw an InvalidStateError |
430 // exception and abort these steps. | 448 // exception and abort these steps. |
431 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) | 449 if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionStat e)) |
432 return; | 450 return; |
433 | 451 |
434 // 3. Update the attribute to the new value. | 452 // 3. Update the attribute to the new value. |
435 m_trackDefaults = trackDefaults; | 453 m_trackDefaults = trackDefaults; |
436 } | 454 } |
437 | 455 |
456 void SourceBuffer::cancelRemove() | |
457 { | |
458 DCHECK(m_updating); | |
459 DCHECK_NE(m_pendingRemoveStart, -1); | |
460 m_removeAsyncPartRunner->stop(); | |
461 m_pendingRemoveStart = -1; | |
462 m_pendingRemoveEnd = -1; | |
463 m_updating = false; | |
464 | |
465 if (!RuntimeEnabledFeatures::mediaSourceNewAbortAndDurationEnabled()) { | |
466 scheduleEvent(EventTypeNames::abort); | |
467 scheduleEvent(EventTypeNames::updateend); | |
468 } | |
469 | |
470 TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::remove", this); | |
471 } | |
472 | |
438 void SourceBuffer::abortIfUpdating() | 473 void SourceBuffer::abortIfUpdating() |
439 { | 474 { |
440 // Section 3.2 abort() method step 3 substeps. | 475 // Section 3.2 abort() method step 4 substeps. |
441 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sou rce.html#widl-SourceBuffer-abort-void | 476 // http://w3c.github.io/media-source/#widl-SourceBuffer-abort-void |
442 | 477 |
443 if (!m_updating) | 478 if (!m_updating) |
444 return; | 479 return; |
445 | 480 |
481 DCHECK_EQ(m_pendingRemoveStart, -1); | |
482 | |
446 const char* traceEventName = 0; | 483 const char* traceEventName = 0; |
447 if (!m_pendingAppendData.isEmpty()) { | 484 if (!m_pendingAppendData.isEmpty()) { |
448 traceEventName = "SourceBuffer::appendBuffer"; | 485 traceEventName = "SourceBuffer::appendBuffer"; |
449 } else if (m_stream) { | 486 } else if (m_stream) { |
450 traceEventName = "SourceBuffer::appendStream"; | 487 traceEventName = "SourceBuffer::appendStream"; |
451 } else if (m_pendingRemoveStart != -1) { | |
452 traceEventName = "SourceBuffer::remove"; | |
453 } else { | 488 } else { |
454 NOTREACHED(); | 489 NOTREACHED(); |
455 } | 490 } |
456 | 491 |
457 // 3.1. Abort the buffer append and stream append loop algorithms if they ar e running. | 492 // 4.1. Abort the buffer append and stream append loop algorithms if they ar e running. |
458 m_appendBufferAsyncPartRunner->stop(); | 493 m_appendBufferAsyncPartRunner->stop(); |
459 m_pendingAppendData.clear(); | 494 m_pendingAppendData.clear(); |
460 m_pendingAppendDataOffset = 0; | 495 m_pendingAppendDataOffset = 0; |
461 | 496 |
462 m_removeAsyncPartRunner->stop(); | |
463 m_pendingRemoveStart = -1; | |
464 m_pendingRemoveEnd = -1; | |
465 | |
466 m_appendStreamAsyncPartRunner->stop(); | 497 m_appendStreamAsyncPartRunner->stop(); |
467 clearAppendStreamState(); | 498 clearAppendStreamState(); |
468 | 499 |
469 // 3.2. Set the updating attribute to false. | 500 // 4.2. Set the updating attribute to false. |
470 m_updating = false; | 501 m_updating = false; |
471 | 502 |
472 // 3.3. Queue a task to fire a simple event named abort at this SourceBuffer object. | 503 // 4.3. Queue a task to fire a simple event named abort at this SourceBuffer object. |
473 scheduleEvent(EventTypeNames::abort); | 504 scheduleEvent(EventTypeNames::abort); |
474 | 505 |
475 // 3.4. Queue a task to fire a simple event named updateend at this SourceBu ffer object. | 506 // 4.4. Queue a task to fire a simple event named updateend at this SourceBu ffer object. |
476 scheduleEvent(EventTypeNames::updateend); | 507 scheduleEvent(EventTypeNames::updateend); |
477 | 508 |
478 TRACE_EVENT_ASYNC_END0("media", traceEventName, this); | 509 TRACE_EVENT_ASYNC_END0("media", traceEventName, this); |
479 } | 510 } |
480 | 511 |
481 void SourceBuffer::removedFromMediaSource() | 512 void SourceBuffer::removedFromMediaSource() |
482 { | 513 { |
483 if (isRemoved()) | 514 if (isRemoved()) |
484 return; | 515 return; |
485 | 516 |
486 SBLOG << __FUNCTION__ << " this=" << this; | 517 SBLOG << __FUNCTION__ << " this=" << this; |
487 abortIfUpdating(); | 518 if (m_pendingRemoveStart != -1) { |
519 cancelRemove(); | |
520 } else { | |
521 abortIfUpdating(); | |
522 } | |
488 | 523 |
489 if (RuntimeEnabledFeatures::audioVideoTracksEnabled()) { | 524 if (RuntimeEnabledFeatures::audioVideoTracksEnabled()) { |
490 DCHECK(m_source); | 525 DCHECK(m_source); |
491 if (m_source->mediaElement()->audioTracks().length() > 0 | 526 if (m_source->mediaElement()->audioTracks().length() > 0 |
492 || m_source->mediaElement()->videoTracks().length() > 0) { | 527 || m_source->mediaElement()->videoTracks().length() > 0) { |
493 removeMediaTracks(); | 528 removeMediaTracks(); |
494 } | 529 } |
495 } | 530 } |
496 | 531 |
497 m_webSourceBuffer->removedFromMediaSource(); | 532 m_webSourceBuffer->removedFromMediaSource(); |
498 m_webSourceBuffer.reset(); | 533 m_webSourceBuffer.reset(); |
499 m_source = nullptr; | 534 m_source = nullptr; |
500 m_asyncEventQueue = nullptr; | 535 m_asyncEventQueue = nullptr; |
501 } | 536 } |
502 | 537 |
538 double SourceBuffer::highestPresentationTimestamp() | |
539 { | |
540 DCHECK(!isRemoved()); | |
541 | |
542 SBLOG << __FUNCTION__ << " this=" << this; | |
chcunningham
2016/06/29 21:19:24
Do you need both SBLOGs? (here and 2 lines down)
wolenetz
2016/06/30 01:35:49
Nope. I was being extra-verbose. I'll keep the lat
| |
543 double pts = m_webSourceBuffer->highestPresentationTimestamp(); | |
544 SBLOG << __FUNCTION__ << " this=" << this << ", pts=" << pts; | |
545 return pts; | |
546 } | |
547 | |
503 void SourceBuffer::removeMediaTracks() | 548 void SourceBuffer::removeMediaTracks() |
504 { | 549 { |
505 DCHECK(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | 550 DCHECK(RuntimeEnabledFeatures::audioVideoTracksEnabled()); |
506 // Spec: http://w3c.github.io/media-source/#widl-MediaSource-removeSourceBuf fer-void-SourceBuffer-sourceBuffer | 551 // Spec: http://w3c.github.io/media-source/#widl-MediaSource-removeSourceBuf fer-void-SourceBuffer-sourceBuffer |
507 DCHECK(m_source); | 552 DCHECK(m_source); |
508 | 553 |
509 HTMLMediaElement* mediaElement = m_source->mediaElement(); | 554 HTMLMediaElement* mediaElement = m_source->mediaElement(); |
510 DCHECK(mediaElement); | 555 DCHECK(mediaElement); |
511 // 3. Let SourceBuffer audioTracks list equal the AudioTrackList object retu rned by sourceBuffer.audioTracks. | 556 // 3. Let SourceBuffer audioTracks list equal the AudioTrackList object retu rned by sourceBuffer.audioTracks. |
512 // 4. If the SourceBuffer audioTracks list is not empty, then run the follow ing steps: | 557 // 4. If the SourceBuffer audioTracks list is not empty, then run the follow ing steps: |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1049 visitor->trace(m_removeAsyncPartRunner); | 1094 visitor->trace(m_removeAsyncPartRunner); |
1050 visitor->trace(m_appendStreamAsyncPartRunner); | 1095 visitor->trace(m_appendStreamAsyncPartRunner); |
1051 visitor->trace(m_stream); | 1096 visitor->trace(m_stream); |
1052 visitor->trace(m_audioTracks); | 1097 visitor->trace(m_audioTracks); |
1053 visitor->trace(m_videoTracks); | 1098 visitor->trace(m_videoTracks); |
1054 EventTargetWithInlineData::trace(visitor); | 1099 EventTargetWithInlineData::trace(visitor); |
1055 ActiveDOMObject::trace(visitor); | 1100 ActiveDOMObject::trace(visitor); |
1056 } | 1101 } |
1057 | 1102 |
1058 } // namespace blink | 1103 } // namespace blink |
OLD | NEW |