OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
651 // a task to fire a simple event named abort at the media element. | 651 // a task to fire a simple event named abort at the media element. |
652 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) | 652 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) |
653 scheduleEvent(EventTypeNames::abort); | 653 scheduleEvent(EventTypeNames::abort); |
654 | 654 |
655 closeMediaSource(); | 655 closeMediaSource(); |
656 | 656 |
657 createMediaPlayer(); | 657 createMediaPlayer(); |
658 | 658 |
659 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps | 659 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps |
660 if (m_networkState != NETWORK_EMPTY) { | 660 if (m_networkState != NETWORK_EMPTY) { |
661 // 4.1 - Queue a task to fire a simple event named emptied at the media element. | |
662 scheduleEvent(EventTypeNames::emptied); | |
663 | |
664 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. | |
661 m_networkState = NETWORK_EMPTY; | 665 m_networkState = NETWORK_EMPTY; |
666 | |
667 // 4.3 - Forget the media element's media-resource-specific tracks. | |
668 forgetResourceSpecificTracks(); | |
669 | |
670 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate. | |
662 m_readyState = HAVE_NOTHING; | 671 m_readyState = HAVE_NOTHING; |
663 m_readyStateMaximum = HAVE_NOTHING; | 672 m_readyStateMaximum = HAVE_NOTHING; |
673 | |
674 // 4.5 - If the paused attribute is false, then set it to true. | |
675 m_paused = true; | |
676 | |
677 // 4.6 - If seeking is true, set it to false. | |
678 m_seeking = false; | |
679 | |
680 // 4.7 - Set the current playback position to 0. | |
681 // Set the official playback position to 0. | |
682 // If this changed the official playback position, then queue a ta sk to fire a simple event named timeupdate at the media element. | |
683 // FIXME: Add support for firing this event. | |
684 | |
685 // 4.8 - Set the initial playback position to 0. | |
686 // FIXME: Make this less subtle. The position only becomes 0 because of the createMediaPlayer() call | |
687 // above. | |
664 refreshCachedTime(); | 688 refreshCachedTime(); |
665 m_paused = true; | |
666 m_seeking = false; | |
667 invalidateCachedTime(); | 689 invalidateCachedTime(); |
668 scheduleEvent(EventTypeNames::emptied); | 690 |
691 // 4.9 - Set the timeline offset to Not-a-Number (NaN). | |
692 // 4.10 - Update the duration attribute to Not-a-Number (NaN). | |
693 | |
694 | |
669 updateMediaController(); | 695 updateMediaController(); |
670 if (RuntimeEnabledFeatures::videoTrackEnabled()) | 696 if (RuntimeEnabledFeatures::videoTrackEnabled()) |
671 updateActiveTextTrackCues(0); | 697 updateActiveTextTrackCues(0); |
672 } | 698 } |
673 | 699 |
674 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. | 700 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. |
675 setPlaybackRate(defaultPlaybackRate()); | 701 setPlaybackRate(defaultPlaybackRate()); |
676 | 702 |
677 // 6 - Set the error attribute to null and the autoplaying flag to true. | 703 // 6 - Set the error attribute to null and the autoplaying flag to true. |
678 m_error = nullptr; | 704 m_error = nullptr; |
679 m_autoplaying = true; | 705 m_autoplaying = true; |
680 | 706 |
681 // 7 - Invoke the media element's resource selection algorithm. | 707 // 7 - Invoke the media element's resource selection algorithm. |
682 | 708 |
683 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. | 709 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. |
684 | 710 |
685 // The resource selection algorithm | 711 // The resource selection algorithm |
686 // 1 - Set the networkState to NETWORK_NO_SOURCE | 712 // 1 - Set the networkState to NETWORK_NO_SOURCE |
687 m_networkState = NETWORK_NO_SOURCE; | 713 m_networkState = NETWORK_NO_SOURCE; |
688 | 714 |
689 // 2 - Asynchronously await a stable state. | 715 // 2 - Asynchronously await a stable state. |
690 | 716 |
691 m_playedTimeRanges = TimeRanges::create(); | 717 m_playedTimeRanges = TimeRanges::create(); |
718 | |
719 // FIXME: Investigate whether these can be moved into m_networkState != NETW ORK_EMPTY block above | |
720 // so they are closer to the relevant spec steps. | |
692 m_lastSeekTime = 0; | 721 m_lastSeekTime = 0; |
693 m_duration = numeric_limits<double>::quiet_NaN(); | 722 m_duration = numeric_limits<double>::quiet_NaN(); |
694 | 723 |
695 // The spec doesn't say to block the load event until we actually run the as ynchronous section | 724 // The spec doesn't say to block the load event until we actually run the as ynchronous section |
696 // algorithm, but do it now because we won't start that until after the time r fires and the | 725 // algorithm, but do it now because we won't start that until after the time r fires and the |
697 // event may have already fired by then. | 726 // event may have already fired by then. |
698 setShouldDelayLoadEvent(true); | 727 setShouldDelayLoadEvent(true); |
699 | 728 |
700 configureMediaControls(); | 729 configureMediaControls(); |
701 } | 730 } |
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1352 | 1381 |
1353 // 4.8.10.5 | 1382 // 4.8.10.5 |
1354 // 6 - Reaching this step indicates that the media resource failed to load o r that the given | 1383 // 6 - Reaching this step indicates that the media resource failed to load o r that the given |
1355 // URL could not be resolved. In one atomic operation, run the following ste ps: | 1384 // URL could not be resolved. In one atomic operation, run the following ste ps: |
1356 | 1385 |
1357 // 6.1 - Set the error attribute to a new MediaError object whose code attri bute is set to | 1386 // 6.1 - Set the error attribute to a new MediaError object whose code attri bute is set to |
1358 // MEDIA_ERR_SRC_NOT_SUPPORTED. | 1387 // MEDIA_ERR_SRC_NOT_SUPPORTED. |
1359 m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED); | 1388 m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED); |
1360 | 1389 |
1361 // 6.2 - Forget the media element's media-resource-specific text tracks. | 1390 // 6.2 - Forget the media element's media-resource-specific text tracks. |
1391 forgetResourceSpecificTracks(); | |
1362 | 1392 |
1363 // 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE v alue. | 1393 // 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE v alue. |
1364 m_networkState = NETWORK_NO_SOURCE; | 1394 m_networkState = NETWORK_NO_SOURCE; |
1365 | 1395 |
1366 // 7 - Queue a task to fire a simple event named error at the media element. | 1396 // 7 - Queue a task to fire a simple event named error at the media element. |
1367 scheduleEvent(EventTypeNames::error); | 1397 scheduleEvent(EventTypeNames::error); |
1368 | 1398 |
1369 closeMediaSource(); | 1399 closeMediaSource(); |
1370 | 1400 |
1371 // 8 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. | 1401 // 8 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1426 } | 1456 } |
1427 | 1457 |
1428 void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error) | 1458 void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error) |
1429 { | 1459 { |
1430 stopPeriodicTimers(); | 1460 stopPeriodicTimers(); |
1431 | 1461 |
1432 // If we failed while trying to load a <source> element, the movie was never parsed, and there are more | 1462 // If we failed while trying to load a <source> element, the movie was never parsed, and there are more |
1433 // <source> children, schedule the next one | 1463 // <source> children, schedule the next one |
1434 if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) { | 1464 if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) { |
1435 | 1465 |
1466 // resource selection algorithm | |
1467 // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DO M manipulation task source, to fire a simple event named error at the candidate element. | |
1436 if (m_currentSourceNode) | 1468 if (m_currentSourceNode) |
1437 m_currentSourceNode->scheduleErrorEvent(); | 1469 m_currentSourceNode->scheduleErrorEvent(); |
1438 else | 1470 else |
1439 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed"); | 1471 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed"); |
1440 | 1472 |
1473 // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorit hm says the synchronous section has ended. | |
1474 | |
1475 // 9.Otherwise.11 - Forget the media element's media-resource-specific t racks. | |
1476 forgetResourceSpecificTracks(); | |
1477 | |
1441 if (havePotentialSourceChild()) { | 1478 if (havePotentialSourceChild()) { |
1442 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>"); | 1479 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>"); |
1443 scheduleNextSourceChild(); | 1480 scheduleNextSourceChild(); |
1444 } else { | 1481 } else { |
1445 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - no more <source> elements, waiting"); | 1482 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - no more <source> elements, waiting"); |
1446 waitForSourceChange(); | 1483 waitForSourceChange(); |
1447 } | 1484 } |
1448 | 1485 |
1449 return; | 1486 return; |
1450 } | 1487 } |
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2489 | 2526 |
2490 if (!m_textTracks) | 2527 if (!m_textTracks) |
2491 return; | 2528 return; |
2492 | 2529 |
2493 // This cast is safe because we created the InbandTextTrack with the WebInba ndTextTrack | 2530 // This cast is safe because we created the InbandTextTrack with the WebInba ndTextTrack |
2494 // passed to mediaPlayerDidAddTextTrack. | 2531 // passed to mediaPlayerDidAddTextTrack. |
2495 RefPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack-> client()); | 2532 RefPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack-> client()); |
2496 if (!textTrack) | 2533 if (!textTrack) |
2497 return; | 2534 return; |
2498 | 2535 |
2499 removeTextTrack(textTrack.get()); | 2536 removeTextTrack(textTrack.get(), true); |
2500 } | 2537 } |
2501 | 2538 |
2502 void HTMLMediaElement::closeCaptionTracksChanged() | 2539 void HTMLMediaElement::closeCaptionTracksChanged() |
2503 { | 2540 { |
2504 if (hasMediaControls()) | 2541 if (hasMediaControls()) |
2505 mediaControls()->closedCaptionTracksChanged(); | 2542 mediaControls()->closedCaptionTracksChanged(); |
2506 } | 2543 } |
2507 | 2544 |
2508 void HTMLMediaElement::addTextTrack(TextTrack* track) | 2545 void HTMLMediaElement::addTextTrack(TextTrack* track) |
2509 { | 2546 { |
2510 textTracks()->append(track); | 2547 textTracks()->append(track); |
2511 | 2548 |
2512 closeCaptionTracksChanged(); | 2549 closeCaptionTracksChanged(); |
2513 } | 2550 } |
2514 | 2551 |
2515 void HTMLMediaElement::removeTextTrack(TextTrack* track) | 2552 void HTMLMediaElement::removeTextTrack(TextTrack* track, bool scheduleEvent) |
2516 { | 2553 { |
2517 TrackDisplayUpdateScope scope(this); | 2554 TrackDisplayUpdateScope scope(this); |
2518 TextTrackCueList* cues = track->cues(); | 2555 TextTrackCueList* cues = track->cues(); |
2519 if (cues) | 2556 if (cues) |
2520 textTrackRemoveCues(track, cues); | 2557 textTrackRemoveCues(track, cues); |
2521 m_textTracks->remove(track); | 2558 m_textTracks->remove(track, scheduleEvent); |
2522 | 2559 |
2523 closeCaptionTracksChanged(); | 2560 closeCaptionTracksChanged(); |
2524 } | 2561 } |
2525 | 2562 |
2526 void HTMLMediaElement::removeAllInbandTracks() | 2563 void HTMLMediaElement::forgetResourceSpecificTracks() |
2527 { | 2564 { |
2528 if (!m_textTracks) | 2565 if (m_textTracks) { |
2529 return; | 2566 TrackDisplayUpdateScope scope(this); |
2567 for (int i = m_textTracks->length() - 1; i >= 0; --i) { | |
adamk
2014/02/26 00:45:32
length() - 1 is scary since that's an unsigned. Ar
| |
2568 TextTrack* track = m_textTracks->item(i); | |
2530 | 2569 |
2531 TrackDisplayUpdateScope scope(this); | 2570 if (track->trackType() == TextTrack::InBand) |
2532 for (int i = m_textTracks->length() - 1; i >= 0; --i) { | 2571 removeTextTrack(track, false); |
2533 TextTrack* track = m_textTracks->item(i); | 2572 } |
2534 | |
2535 if (track->trackType() == TextTrack::InBand) | |
2536 removeTextTrack(track); | |
2537 } | 2573 } |
2538 } | 2574 } |
2539 | 2575 |
2540 PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicString& kind, c onst AtomicString& label, const AtomicString& language, ExceptionState& exceptio nState) | 2576 PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicString& kind, c onst AtomicString& label, const AtomicString& language, ExceptionState& exceptio nState) |
2541 { | 2577 { |
2542 ASSERT(RuntimeEnabledFeatures::videoTrackEnabled()); | 2578 ASSERT(RuntimeEnabledFeatures::videoTrackEnabled()); |
2543 | 2579 |
2544 // 4.8.10.12.4 Text track API | 2580 // 4.8.10.12.4 Text track API |
2545 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps: | 2581 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps: |
2546 | 2582 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2629 | 2665 |
2630 textTrack->setHasBeenConfigured(false); | 2666 textTrack->setHasBeenConfigured(false); |
2631 | 2667 |
2632 if (!m_textTracks) | 2668 if (!m_textTracks) |
2633 return; | 2669 return; |
2634 | 2670 |
2635 // 4.8.10.12.3 Sourcing out-of-band text tracks | 2671 // 4.8.10.12.3 Sourcing out-of-band text tracks |
2636 // When a track element's parent element changes and the old parent was a me dia element, | 2672 // When a track element's parent element changes and the old parent was a me dia element, |
2637 // then the user agent must remove the track element's corresponding text tr ack from the | 2673 // then the user agent must remove the track element's corresponding text tr ack from the |
2638 // media element's list of text tracks. | 2674 // media element's list of text tracks. |
2639 removeTextTrack(textTrack.get()); | 2675 removeTextTrack(textTrack.get(), true); |
2640 | 2676 |
2641 size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack.get()); | 2677 size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack.get()); |
2642 if (index != kNotFound) | 2678 if (index != kNotFound) |
2643 m_textTracksWhenResourceSelectionBegan.remove(index); | 2679 m_textTracksWhenResourceSelectionBegan.remove(index); |
2644 } | 2680 } |
2645 | 2681 |
2646 static int textTrackLanguageSelectionScore(const TextTrack& track) | 2682 static int textTrackLanguageSelectionScore(const TextTrack& track) |
2647 { | 2683 { |
2648 if (track.language().isEmpty()) | 2684 if (track.language().isEmpty()) |
2649 return 0; | 2685 return 0; |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3382 m_player.clear(); | 3418 m_player.clear(); |
3383 | 3419 |
3384 #if ENABLE(WEB_AUDIO) | 3420 #if ENABLE(WEB_AUDIO) |
3385 if (m_audioSourceNode) | 3421 if (m_audioSourceNode) |
3386 m_audioSourceNode->unlock(); | 3422 m_audioSourceNode->unlock(); |
3387 #endif | 3423 #endif |
3388 } | 3424 } |
3389 | 3425 |
3390 void HTMLMediaElement::clearMediaPlayer(int flags) | 3426 void HTMLMediaElement::clearMediaPlayer(int flags) |
3391 { | 3427 { |
3392 removeAllInbandTracks(); | 3428 forgetResourceSpecificTracks(); |
3393 | 3429 |
3394 closeMediaSource(); | 3430 closeMediaSource(); |
3395 | 3431 |
3396 setMediaKeysInternal(0); | 3432 setMediaKeysInternal(0); |
3397 | 3433 |
3398 clearMediaPlayerAndAudioSourceProviderClient(); | 3434 clearMediaPlayerAndAudioSourceProviderClient(); |
3399 | 3435 |
3400 stopPeriodicTimers(); | 3436 stopPeriodicTimers(); |
3401 m_loadTimer.stop(); | 3437 m_loadTimer.stop(); |
3402 | 3438 |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3904 { | 3940 { |
3905 m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource)); | 3941 m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource)); |
3906 } | 3942 } |
3907 | 3943 |
3908 bool HTMLMediaElement::isInteractiveContent() const | 3944 bool HTMLMediaElement::isInteractiveContent() const |
3909 { | 3945 { |
3910 return fastHasAttribute(controlsAttr); | 3946 return fastHasAttribute(controlsAttr); |
3911 } | 3947 } |
3912 | 3948 |
3913 } | 3949 } |
OLD | NEW |