Skip to content
Permalink
Browse files
2010-10-28 Eric Carlson <eric.carlson@apple.com>
        Reviewed by Adam Roben.

        Seeking by very small increment doesn't generate 'seeked' event
        https://bugs.webkit.org/show_bug.cgi?id=48530

        Test: media/video-seek-by-small-increment.html

        * html/HTMLMediaElement.cpp:
        (WebCore::HTMLMediaElement::seek): Ask the media engine for its closest time value so we can
        avoid asking it to seek to the current time.

        * platform/graphics/MediaPlayer.cpp:
        (WebCore::MediaPlayer::mediaTimeForTimeValue): New.
        * platform/graphics/MediaPlayer.h:
        * platform/graphics/MediaPlayerPrivate.h:
        (WebCore::MediaPlayerPrivateInterface::mediaTimeForTimeValue): Ditto.

        * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
        (WebCore::MediaPlayerPrivate::mediaTimeForTimeValue): Return the closest value in the movie's time scale.

        * platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:
        (WebCore::MediaPlayerPrivateQuickTimeVisualContext::mediaTimeForTimeValue): Ditto
        * platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h:

        * platform/graphics/win/QTMovie.cpp:
        (QTMovie::timeScale): Return the movie's time scale.
        * platform/graphics/win/QTMovie.h:

2010-10-28  Eric Carlson  <eric.carlson@apple.com>

        Reviewed by Adam Roben.

        Seeking by very small increment doesn't generate 'seeked' event
        https://bugs.webkit.org/show_bug.cgi?id=48530

        * media/video-seek-by-small-increment-expected.txt: Added.
        * media/video-seek-by-small-increment.html: Added.



Canonical link: https://commits.webkit.org/61326@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@70814 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
eric-carlson committed Oct 28, 2010
1 parent 4c72212 commit feba1f50b8069b73f3a2ed7dc005faf2752b2340
Showing 14 changed files with 198 additions and 0 deletions.
@@ -1,3 +1,13 @@
2010-10-28 Eric Carlson <eric.carlson@apple.com>

Reviewed by Adam Roben.

Seeking by very small increment doesn't generate 'seeked' event
https://bugs.webkit.org/show_bug.cgi?id=48530

* media/video-seek-by-small-increment-expected.txt: Added.
* media/video-seek-by-small-increment.html: Added.

2010-10-28 David Hyatt <hyatt@apple.com>

Reviewed by Beth Dakin.
@@ -0,0 +1,36 @@
Test seeking by very small increments.

EVENT(canplaythrough)
EXPECTED (seekedEventCount == '0') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '1') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '2') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '3') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '4') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '5') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '6') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '7') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '8') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '9') OK
EVENT(seeking)
EVENT(seeked)
EXPECTED (seekedEventCount == '10') OK
END OF TEST

@@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<head>
<script src=media-file.js></script>
<script src=video-test.js></script>

<script>
var seekedEventCount = 0;
var seeksAttempted = 0;
var increment = 0.0004;

function seekIncrement()
{
// We want to verify that seeking by an increment smaller than the test movie's time scale
// succeeds. test.mp4 has a time scale of 2500 (the smallest unit of time in that file
// is 0.0004 seconds), so start with that and decrease by half each time.
increment /= 2;
return increment;
}

function seeked()
{
++seekedEventCount;
}

function attemptSeek()
{
var now = video.currentTime;

video.currentTime = now + seekIncrement();
++seeksAttempted;
setTimeout(testAgain, 10);
}

function testAgain()
{
reportExpected(seeksAttempted == seekedEventCount, "seekedEventCount", "==", seeksAttempted, seekedEventCount);

if (seeksAttempted == 10) {
endTest();
return;
}

setTimeout(attemptSeek, 100);
}

function start()
{
findMediaElement();
video.src = findMediaFile("video", "content/test");

waitForEvent('canplaythrough', testAgain);
waitForEvent('seeked', seeked);
waitForEvent('seeking');
waitForEvent('play');
waitForEvent('pause');
}
</script>
</head>
<body>
<video controls></video>
<p>Test seeking by very small increments.</p>
<script>start()</script>
</body>
</html>
@@ -1,3 +1,34 @@
2010-10-28 Eric Carlson <eric.carlson@apple.com>

Reviewed by Adam Roben.

Seeking by very small increment doesn't generate 'seeked' event
https://bugs.webkit.org/show_bug.cgi?id=48530

Test: media/video-seek-by-small-increment.html

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::seek): Ask the media engine for its closest time value so we can
avoid asking it to seek to the current time.

* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::mediaTimeForTimeValue): New.
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::mediaTimeForTimeValue): Ditto.

* platform/graphics/mac/MediaPlayerPrivateQTKit.h:
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivate::mediaTimeForTimeValue): Return the closest value in the movie's time scale.

* platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:
(WebCore::MediaPlayerPrivateQuickTimeVisualContext::mediaTimeForTimeValue): Ditto
* platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h:

* platform/graphics/win/QTMovie.cpp:
(QTMovie::timeScale): Return the movie's time scale.
* platform/graphics/win/QTMovie.h:

2010-10-28 David Hyatt <hyatt@apple.com>

Reviewed by Beth Dakin.
@@ -1113,6 +1113,18 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec)
float earliestTime = m_player->startTime();
time = max(time, earliestTime);

// Ask the media engine for the time value in the movie's time scale before comparing with current time. This
// is necessary because if the seek time is not equal to currentTime but the delta is less than the movie's
// time scale, we will ask the media engine to "seek" to the current movie time, which may be a noop and
// not generate a timechanged callback. This means m_seeking will never be cleared and we will never
// fire a 'seeked' event.
#if !LOG_DISABLED
float mediaTime = m_player->mediaTimeForTimeValue(time);
if (time != mediaTime)
LOG(Media, "HTMLMediaElement::seek(%f) - media timeline equivalent is %f", time, mediaTime);
#endif
time = m_player->mediaTimeForTimeValue(time);

// 7 - If the (possibly now changed) new playback position is not in one of the ranges given in the
// seekable attribute, then let it be the position in one of the ranges given in the seekable attribute
// that is the nearest to the new playback position. ... If there are no ranges given in the seekable
@@ -643,6 +643,11 @@ MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const
return m_private->movieLoadType();
}

float MediaPlayer::mediaTimeForTimeValue(float timeValue) const
{
return m_private->mediaTimeForTimeValue(timeValue);
}

// Client callbacks.
void MediaPlayer::networkStateChanged()
{
@@ -274,6 +274,8 @@ class MediaPlayer : public Noncopyable {

bool hasSingleSecurityOrigin() const;

float mediaTimeForTimeValue(float) const;

private:
MediaPlayer(MediaPlayerClient*);

@@ -125,6 +125,10 @@ class MediaPlayerPrivateInterface : public Noncopyable {

virtual void prepareForRendering() { }

// Time value in the movie's time scale. It is only necessary to override this if the media
// engine uses rational numbers to represent media time.
virtual float mediaTimeForTimeValue(float timeValue) const { return timeValue; }

};

}
@@ -173,6 +173,8 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {

bool isReadyForVideoSetup() const;

virtual float mediaTimeForTimeValue(float) const;

MediaPlayer* m_player;
RetainPtr<QTMovie> m_qtMovie;
RetainPtr<QTMovieView> m_qtMovieView;
@@ -1540,6 +1540,15 @@ static void addFileTypesToCache(NSArray * fileTypes, HashSet<String> &cache)
resumeLoad();
}

float MediaPlayerPrivate::mediaTimeForTimeValue(float timeValue) const
{
if (!metaDataAvailable())
return timeValue;

QTTime qttime = createQTTime(timeValue);
return static_cast<float>(qttime.timeValue) / qttime.timeScale;
}

} // namespace WebCore

@implementation WebCoreMovieObserver
@@ -1053,6 +1053,16 @@ void MediaPlayerPrivateQuickTimeVisualContext::setPreload(MediaPlayer::Preload p
resumeLoad();
}

float MediaPlayerPrivateQuickTimeVisualContext::mediaTimeForTimeValue(float timeValue) const
{
long timeScale;
if (m_readyState < MediaPlayer::HaveMetadata || !(timeScale = m_movie->timeScale()))
return timeValue;

long mediaTimeValue = static_cast<long>(timeValue * timeScale);
return static_cast<float>(mediaTimeValue) / timeScale;
}

MediaPlayerPrivateQuickTimeVisualContext::MediaRenderingMode MediaPlayerPrivateQuickTimeVisualContext::currentRenderingMode() const
{
if (!m_movie)
@@ -173,6 +173,8 @@ class MediaPlayerPrivateQuickTimeVisualContext : public MediaPlayerPrivateInterf

void retrieveAndResetMovieTransform();

virtual float mediaTimeForTimeValue(float) const;

MediaPlayer* m_player;
RefPtr<QTMovie> m_movie;
#if USE(ACCELERATED_COMPOSITING)
@@ -738,6 +738,14 @@ void QTMovie::setClosedCaptionsVisible(bool visible)
QTSetTrackProperty(ccTrack, closedCaptionTrackType, closedCaptionDisplayPropertyID, sizeof(doDisplay), &doDisplay);
}

long QTMovie::timeScale() const
{
if (!m_private->m_movie)
return 0;

return GetMovieTimeScale(m_private->m_movie);
}

static void initializeSupportedTypes()
{
if (gSupportedTypes)
@@ -115,6 +115,8 @@ class QTMOVIEWIN_API QTMovie : public RefCounted<QTMovie> {

Movie getMovieHandle() const;

long timeScale() const;

private:
QTMoviePrivate* m_private;
friend class QTMoviePrivate;

0 comments on commit feba1f5

Please sign in to comment.