Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 2581533002: MSE: Fix logic bugs with high precision duration (Closed)
Patch Set: Fix orientation test Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 1654
1655 selectInitialTracksIfNecessary(); 1655 selectInitialTracksIfNecessary();
1656 1656
1657 MediaFragmentURIParser fragmentParser(m_currentSrc); 1657 MediaFragmentURIParser fragmentParser(m_currentSrc);
1658 m_fragmentEndTime = fragmentParser.endTime(); 1658 m_fragmentEndTime = fragmentParser.endTime();
1659 1659
1660 // Set the current playback position and the official playback position to 1660 // Set the current playback position and the official playback position to
1661 // the earliest possible position. 1661 // the earliest possible position.
1662 setOfficialPlaybackPosition(earliestPossiblePosition()); 1662 setOfficialPlaybackPosition(earliestPossiblePosition());
1663 1663
1664 m_duration = duration(); 1664 m_duration = m_webMediaPlayer->duration();
1665 scheduleEvent(EventTypeNames::durationchange); 1665 scheduleEvent(EventTypeNames::durationchange);
1666 1666
1667 if (isHTMLVideoElement()) 1667 if (isHTMLVideoElement())
1668 scheduleEvent(EventTypeNames::resize); 1668 scheduleEvent(EventTypeNames::resize);
1669 scheduleEvent(EventTypeNames::loadedmetadata); 1669 scheduleEvent(EventTypeNames::loadedmetadata);
1670 1670
1671 bool jumped = false; 1671 bool jumped = false;
1672 if (m_defaultPlaybackStartPosition > 0) { 1672 if (m_defaultPlaybackStartPosition > 0) {
1673 seek(m_defaultPlaybackStartPosition); 1673 seek(m_defaultPlaybackStartPosition);
1674 jumped = true; 1674 jumped = true;
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1953 } 1953 }
1954 1954
1955 double HTMLMediaElement::officialPlaybackPosition() const { 1955 double HTMLMediaElement::officialPlaybackPosition() const {
1956 // Hold updates to official playback position while paused or waiting for more 1956 // Hold updates to official playback position while paused or waiting for more
1957 // data. The underlying media player may continue to make small advances in 1957 // data. The underlying media player may continue to make small advances in
1958 // currentTime (e.g. as samples in the last rendered audio buffer are played 1958 // currentTime (e.g. as samples in the last rendered audio buffer are played
1959 // played out), but advancing currentTime while paused/waiting sends a mixed 1959 // played out), but advancing currentTime while paused/waiting sends a mixed
1960 // signal about the state of playback. 1960 // signal about the state of playback.
1961 bool waitingForData = m_readyState <= kHaveCurrentData; 1961 bool waitingForData = m_readyState <= kHaveCurrentData;
1962 if (m_officialPlaybackPositionNeedsUpdate && !m_paused && !waitingForData) { 1962 if (m_officialPlaybackPositionNeedsUpdate && !m_paused && !waitingForData) {
1963 // Internal player position may advance slightly beyond duration because 1963 setOfficialPlaybackPosition(currentPlaybackPosition());
1964 // many files use imprecise duration. Clamp official position to duration.
1965 double newPosition = std::min(duration(), currentPlaybackPosition());
1966 setOfficialPlaybackPosition(newPosition);
1967 } 1964 }
1968 1965
1969 #if LOG_OFFICIAL_TIME_STATUS 1966 #if LOG_OFFICIAL_TIME_STATUS
1970 static const double minCachedDeltaForWarning = 0.01; 1967 static const double minCachedDeltaForWarning = 0.01;
1971 double delta = 1968 double delta =
1972 std::abs(m_officialPlaybackPosition - currentPlaybackPosition()); 1969 std::abs(m_officialPlaybackPosition - currentPlaybackPosition());
1973 if (delta > minCachedDeltaForWarning) { 1970 if (delta > minCachedDeltaForWarning) {
1974 BLINK_MEDIA_LOG << "currentTime(" << (void*)this 1971 BLINK_MEDIA_LOG << "currentTime(" << (void*)this
1975 << ") - WARNING, cached time is " << delta 1972 << ") - WARNING, cached time is " << delta
1976 << "seconds off of media time when paused/waiting"; 1973 << "seconds off of media time when paused/waiting";
1977 } 1974 }
1978 #endif 1975 #endif
1979 1976
1980 return m_officialPlaybackPosition; 1977 return m_officialPlaybackPosition;
1981 } 1978 }
1982 1979
1983 void HTMLMediaElement::setOfficialPlaybackPosition(double position) const { 1980 void HTMLMediaElement::setOfficialPlaybackPosition(double position) const {
1984 #if LOG_OFFICIAL_TIME_STATUS 1981 #if LOG_OFFICIAL_TIME_STATUS
1985 BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this 1982 BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this
1986 << ") was:" << m_officialPlaybackPosition 1983 << ") was:" << m_officialPlaybackPosition
1987 << " now:" << position; 1984 << " now:" << position;
1988 #endif 1985 #endif
1989 1986
1990 m_officialPlaybackPosition = position; 1987 // Internal player position may advance slightly beyond duration because
1988 // many files use imprecise duration. Clamp official position to duration when
1989 // known. Duration may be unknown when readyState < HAVE_METADATA.
1990 m_officialPlaybackPosition =
1991 !std::isnan(duration()) ? std::min(duration(), position) : position;
wolenetz 2017/01/09 22:19:35 nit: swap the ternary clauses to remove leading '!
chcunningham 2017/01/10 18:49:29 Done.
1992
1993 if (m_officialPlaybackPosition != position) {
1994 BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this
1995 << ") position:" << position
1996 << " truncated to duration:" << m_officialPlaybackPosition;
1997 }
1991 1998
1992 // Once set, official playback position should hold steady until the next 1999 // Once set, official playback position should hold steady until the next
1993 // stable state. We approximate this by using a microtask to mark the 2000 // stable state. We approximate this by using a microtask to mark the
1994 // need for an update after the current (micro)task has completed. When 2001 // need for an update after the current (micro)task has completed. When
1995 // needed, the update is applied in the next call to 2002 // needed, the update is applied in the next call to
1996 // officialPlaybackPosition(). 2003 // officialPlaybackPosition().
1997 m_officialPlaybackPositionNeedsUpdate = false; 2004 m_officialPlaybackPositionNeedsUpdate = false;
1998 Microtask::enqueueMicrotask( 2005 Microtask::enqueueMicrotask(
1999 WTF::bind(&HTMLMediaElement::requireOfficialPlaybackPositionUpdate, 2006 WTF::bind(&HTMLMediaElement::requireOfficialPlaybackPositionUpdate,
2000 wrapWeakPersistent(this))); 2007 wrapWeakPersistent(this)));
(...skipping 21 matching lines...) Expand all
2022 // playback start position to that time. 2029 // playback start position to that time.
2023 if (m_readyState == kHaveNothing) { 2030 if (m_readyState == kHaveNothing) {
2024 m_defaultPlaybackStartPosition = time; 2031 m_defaultPlaybackStartPosition = time;
2025 return; 2032 return;
2026 } 2033 }
2027 2034
2028 seek(time); 2035 seek(time);
2029 } 2036 }
2030 2037
2031 double HTMLMediaElement::duration() const { 2038 double HTMLMediaElement::duration() const {
2032 // FIXME: remove m_webMediaPlayer check once we figure out how 2039 return m_duration;
2033 // m_webMediaPlayer is going out of sync with readystate.
2034 // m_webMediaPlayer is cleared but readystate is not set to kHaveNothing.
2035 if (!m_webMediaPlayer || m_readyState < kHaveMetadata)
2036 return std::numeric_limits<double>::quiet_NaN();
2037
2038 // FIXME: Refactor so m_duration is kept current (in both MSE and
2039 // non-MSE cases) once we have transitioned from kHaveNothing ->
2040 // kHaveMetadata. Currently, m_duration may be out of date for at least MSE
2041 // case because MediaSource and SourceBuffer do not notify the element
2042 // directly upon duration changes caused by endOfStream, remove, or append
2043 // operations; rather the notification is triggered by the WebMediaPlayer
2044 // implementation observing that the underlying engine has updated duration
2045 // and notifying the element to consult its MediaSource for current
2046 // duration. See http://crbug.com/266644
2047
2048 if (m_mediaSource)
2049 return m_mediaSource->duration();
2050
2051 return webMediaPlayer()->duration();
2052 } 2040 }
2053 2041
2054 bool HTMLMediaElement::paused() const { 2042 bool HTMLMediaElement::paused() const {
2055 return m_paused; 2043 return m_paused;
2056 } 2044 }
2057 2045
2058 double HTMLMediaElement::defaultPlaybackRate() const { 2046 double HTMLMediaElement::defaultPlaybackRate() const {
2059 return m_defaultPlaybackRate; 2047 return m_defaultPlaybackRate;
2060 } 2048 }
2061 2049
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after
3062 } 3050 }
3063 // Queue a task to fire a simple event named ended at the media element. 3051 // Queue a task to fire a simple event named ended at the media element.
3064 scheduleEvent(EventTypeNames::ended); 3052 scheduleEvent(EventTypeNames::ended);
3065 } 3053 }
3066 } 3054 }
3067 updatePlayState(); 3055 updatePlayState();
3068 } 3056 }
3069 3057
3070 void HTMLMediaElement::durationChanged() { 3058 void HTMLMediaElement::durationChanged() {
3071 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ")"; 3059 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ")";
3060
3061 // durationChanged() triggered by media player.
wolenetz 2017/01/09 22:19:34 nit: s/() trig/() is trig/ ?
chcunningham 2017/01/10 18:49:29 Done.
3062 CHECK(m_webMediaPlayer);
3063 double newDuration = m_webMediaPlayer->duration();
3064
3072 // If the duration is changed such that the *current playback position* ends 3065 // If the duration is changed such that the *current playback position* ends
3073 // up being greater than the time of the end of the media resource, then the 3066 // up being greater than the time of the end of the media resource, then the
3074 // user agent must also seek to the time of the end of the media resource. 3067 // user agent must also seek to the time of the end of the media resource.
3075 durationChanged(duration(), currentPlaybackPosition() > duration()); 3068 durationChanged(newDuration, currentPlaybackPosition() > newDuration);
3076 } 3069 }
3077 3070
3078 void HTMLMediaElement::durationChanged(double duration, bool requestSeek) { 3071 void HTMLMediaElement::durationChanged(double duration, bool requestSeek) {
wolenetz 2017/01/09 22:19:34 aside: the .h comment for this method indicates it
chcunningham 2017/01/10 18:49:29 The only external caller is MSE's durationChangeAl
3079 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ", " << duration 3072 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ", " << duration
3080 << ", " << boolString(requestSeek) << ")"; 3073 << ", " << boolString(requestSeek) << ")";
3081 3074
3082 // Abort if duration unchanged. 3075 // Abort if duration unchanged.
3083 if (m_duration == duration) 3076 if (m_duration == duration)
3084 return; 3077 return;
3085 3078
3086 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ") : " << m_duration 3079 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ") : " << m_duration
3087 << " -> " << duration; 3080 << " -> " << duration;
3088 m_duration = duration; 3081 m_duration = duration;
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
4131 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); 4124 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE);
4132 } 4125 }
4133 4126
4134 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) { 4127 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) {
4135 m_mostlyFillingViewport = true; 4128 m_mostlyFillingViewport = true;
4136 if (m_webMediaPlayer) 4129 if (m_webMediaPlayer)
4137 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport); 4130 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport);
4138 } 4131 }
4139 4132
4140 } // namespace blink 4133 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698