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 double pts = m_webSourceBuffer->highestPresentationTimestamp(); |
| 543 SBLOG << __FUNCTION__ << " this=" << this << ", pts=" << pts; |
| 544 return pts; |
| 545 } |
| 546 |
503 void SourceBuffer::removeMediaTracks() | 547 void SourceBuffer::removeMediaTracks() |
504 { | 548 { |
505 DCHECK(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | 549 DCHECK(RuntimeEnabledFeatures::audioVideoTracksEnabled()); |
506 // Spec: http://w3c.github.io/media-source/#widl-MediaSource-removeSourceBuf
fer-void-SourceBuffer-sourceBuffer | 550 // Spec: http://w3c.github.io/media-source/#widl-MediaSource-removeSourceBuf
fer-void-SourceBuffer-sourceBuffer |
507 DCHECK(m_source); | 551 DCHECK(m_source); |
508 | 552 |
509 HTMLMediaElement* mediaElement = m_source->mediaElement(); | 553 HTMLMediaElement* mediaElement = m_source->mediaElement(); |
510 DCHECK(mediaElement); | 554 DCHECK(mediaElement); |
511 // 3. Let SourceBuffer audioTracks list equal the AudioTrackList object retu
rned by sourceBuffer.audioTracks. | 555 // 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: | 556 // 4. If the SourceBuffer audioTracks list is not empty, then run the follow
ing steps: |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 visitor->trace(m_removeAsyncPartRunner); | 1259 visitor->trace(m_removeAsyncPartRunner); |
1216 visitor->trace(m_appendStreamAsyncPartRunner); | 1260 visitor->trace(m_appendStreamAsyncPartRunner); |
1217 visitor->trace(m_stream); | 1261 visitor->trace(m_stream); |
1218 visitor->trace(m_audioTracks); | 1262 visitor->trace(m_audioTracks); |
1219 visitor->trace(m_videoTracks); | 1263 visitor->trace(m_videoTracks); |
1220 EventTargetWithInlineData::trace(visitor); | 1264 EventTargetWithInlineData::trace(visitor); |
1221 ActiveDOMObject::trace(visitor); | 1265 ActiveDOMObject::trace(visitor); |
1222 } | 1266 } |
1223 | 1267 |
1224 } // namespace blink | 1268 } // namespace blink |
OLD | NEW |