<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[160336] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/160336">160336</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2013-12-09 15:36:56 -0800 (Mon, 09 Dec 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>[MSE] Add support for VideoPlaybackMetrics.
https://bugs.webkit.org/show_bug.cgi?id=125380
Reviewed by Eric Carlson.
Source/WebCore:
Test: media/media-source/media-source-video-playback-quality.html
Add a new object type VideoPlaybackQuality to be returned by
HTMLMediaElement.getVideoPlaybackQuality().
HTMLMediaElements must separately track a droppedVideoFrame count, as
certain operations on SourceBuffer will drop incoming frames, which must
be accounted for. Reset this count when the media engine changes, which is
indicitive of a new media load requset starting.
Add the new VideoPlaybackQuality class:
* Modules/mediasource/VideoPlaybackQuality.cpp: Added.
(WebCore::VideoPlaybackQuality::create):
(WebCore::VideoPlaybackQuality::VideoPlaybackQuality):
* Modules/mediasource/VideoPlaybackQuality.h: Added.
(WebCore::VideoPlaybackQuality::creationTime):
(WebCore::VideoPlaybackQuality::totalVideoFrames):
(WebCore::VideoPlaybackQuality::droppedVideoFrames):
(WebCore::VideoPlaybackQuality::corruptedVideoFrames):
(WebCore::VideoPlaybackQuality::totalFrameDelay):
* Modules/mediasource/VideoPlaybackQuality.idl: Added.
Add support for the new class to HTMLMediaElement:
* html/HTMLMediaElement.cpp:
(HTMLMediaElement::shouldUseVideoPluginProxy):
(HTMLMediaElement::getVideoPlaybackQuality):
* html/HTMLMediaElement.h:
* html/HTMLMediaElement.idl:
Report the video quality metrics from the MediaPlayer:
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::totalVideoFrames):
(WebCore::MediaPlayer::droppedVideoFrames):
(WebCore::MediaPlayer::corruptedVideoFrames):
(WebCore::MediaPlayer::totalFrameDelay):
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::totalVideoFrames):
(WebCore::MediaPlayerPrivateInterface::droppedVideoFrames):
(WebCore::MediaPlayerPrivateInterface::corruptedVideoFrames):
(WebCore::MediaPlayerPrivateInterface::totalFrameDelay):
Correctly report the dropped frame count:
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::TrackBuffer::TrackBuffer): needsRandomAccessFlag defaults to true.
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): Check the sync status of the incoming sample.
(WebCore::SourceBuffer::didDropSample): Notify the media element of a dropped frame.
* Modules/mediasource/SourceBuffer.h:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement):
(HTMLMediaElement::mediaPlayerEngineUpdated): Reset m_droppedFrameCount.
(HTMLMediaElement::getVideoPlaybackQuality): Return a new VideoPlaybackQuality object.
* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement::incrementDroppedFrameCount): Simple incrementer.
* platform/MediaSample.h:
(WebCore::MediaSample::isSync): Convenience function.
(WebCore::MediaSample::isNonDisplaying): Ditto.
Add support in the AVFoundation MediaSource Engine:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::totalVideoFrames):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::droppedVideoFrames):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::corruptedVideoFrames):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::totalFrameDelay):
Add support in the Mock MediaSource Engine:
* platform/mock/mediasource/MockBox.h:
* platform/mock/mediasource/MockMediaPlayerMediaSource.cpp:
(WebCore::MockMediaPlayerMediaSource::totalVideoFrames): Simple accessor.
(WebCore::MockMediaPlayerMediaSource::droppedVideoFrames): Ditto.
(WebCore::MockMediaPlayerMediaSource::corruptedVideoFrames): Ditto.
(WebCore::MockMediaPlayerMediaSource::totalFrameDelay): Ditto.
* platform/mock/mediasource/MockMediaPlayerMediaSource.h:
* platform/mock/mediasource/MockMediaSourcePrivate.cpp:
(WebCore::MockMediaSourcePrivate::MockMediaSourcePrivate):
* platform/mock/mediasource/MockMediaSourcePrivate.h:
* platform/mock/mediasource/MockSourceBufferPrivate.cpp:
(WebCore::MockSourceBufferPrivate::enqueueSample): Increment the frame counts based on
the incoming sample.
* platform/mock/mediasource/MockSourceBufferPrivate.h:
Add the new files to the project:
* bindings/gobject/GNUmakefile.am:
* DerivedSources.make:
* WebCore.xcodeproj/project.pbxproj:
* GNUMakefile.list.am:
* CMakeLists.txt:
LayoutTests:
* media/media-source/media-source-video-playback-quality-expected.txt: Added.
* media/media-source/media-source-video-playback-quality.html: Added.
* media/media-source/mock-media-source.js:
(var):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourcecanplaythroughhtml">trunk/LayoutTests/media/media-source/media-source-canplaythrough.html</a></li>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceplayhtml">trunk/LayoutTests/media/media-source/media-source-play.html</a></li>
<li><a href="#trunkLayoutTestsmediamediasourcemockmediasourcejs">trunk/LayoutTests/media/media-source/mock-media-source.js</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesmake">trunk/Source/WebCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceWebCoreGNUmakefilelistam">trunk/Source/WebCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceSourceBuffercpp">trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceSourceBufferh">trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsgobjectGNUmakefileam">trunk/Source/WebCore/bindings/gobject/GNUmakefile.am</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementcpp">trunk/Source/WebCore/html/HTMLMediaElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementh">trunk/Source/WebCore/html/HTMLMediaElement.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementidl">trunk/Source/WebCore/html/HTMLMediaElement.idl</a></li>
<li><a href="#trunkSourceWebCoreplatformMediaSampleh">trunk/Source/WebCore/platform/MediaSample.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayercpp">trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayerh">trunk/Source/WebCore/platform/graphics/MediaPlayer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayerPrivateh">trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCh">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCmm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmockmediasourceMockBoxh">trunk/Source/WebCore/platform/mock/mediasource/MockBox.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockmediasourceMockMediaPlayerMediaSourcecpp">trunk/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockmediasourceMockMediaPlayerMediaSourceh">trunk/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockmediasourceMockMediaSourcePrivatecpp">trunk/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockmediasourceMockMediaSourcePrivateh">trunk/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockmediasourceMockSourceBufferPrivatecpp">trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockmediasourceMockSourceBufferPrivateh">trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourcevideoplaybackqualityexpectedtxt">trunk/LayoutTests/media/media-source/media-source-video-playback-quality-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourcevideoplaybackqualityhtml">trunk/LayoutTests/media/media-source/media-source-video-playback-quality.html</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceVideoPlaybackQualitycpp">trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceVideoPlaybackQualityh">trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceVideoPlaybackQualityidl">trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.idl</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/LayoutTests/ChangeLog        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2013-12-09 Jer Noble <jer.noble@apple.com>
+
+ [MSE] Add support for VideoPlaybackMetrics.
+ https://bugs.webkit.org/show_bug.cgi?id=125380
+
+ Reviewed by Eric Carlson.
+
+ * media/media-source/media-source-video-playback-quality-expected.txt: Added.
+ * media/media-source/media-source-video-playback-quality.html: Added.
+ * media/media-source/mock-media-source.js:
+ (var):
+
</ins><span class="cx"> 2013-12-09 Ryosuke Niwa <rniwa@webkit.org>
</span><span class="cx">
</span><span class="cx"> Implement Document.cloneNode()
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourcecanplaythroughhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/media-source/media-source-canplaythrough.html (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-canplaythrough.html        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/LayoutTests/media/media-source/media-source-canplaythrough.html        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -39,7 +39,7 @@
</span><span class="cx"> function sourceUpdated() {
</span><span class="cx"> source.activeSourceBuffers.length;
</span><span class="cx"> if (nextRequest < totalLength) {
</span><del>- sourceBuffer.appendBuffer(makeASample(nextRequest, nextRequest, 1, 1, 0));
</del><ins>+ sourceBuffer.appendBuffer(makeASample(nextRequest, nextRequest, 1, 1, SAMPLE_FLAG.SYNC));
</ins><span class="cx"> ++nextRequest;
</span><span class="cx"> }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceplayhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/media-source/media-source-play.html (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-play.html        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/LayoutTests/media/media-source/media-source-play.html        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> function loadSamples() {
</span><del>- sample = makeASample(0, 0, 10, 1, 0);
</del><ins>+ sample = makeASample(0, 0, 10, 1, SAMPLE_FLAG.SYNC);
</ins><span class="cx"> waitForEventOn(sourceBuffer, 'updateend', play, false, true);
</span><span class="cx"> run('sourceBuffer.appendBuffer(sample)');
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourcevideoplaybackqualityexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-video-playback-quality-expected.txt (0 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-video-playback-quality-expected.txt         (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-video-playback-quality-expected.txt        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updateend)
+Test that beginning a buffer with a non-sync sample results in that sample being dropped.
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(updateend)
+RUN(quality = video.getVideoPlaybackQuality())
+EXPECTED (quality.totalVideoFrames == '1') OK
+EXPECTED (quality.corruptedVideoFrames == '0') OK
+EXPECTED (quality.droppedVideoFrames == '1') OK
+EXPECTED (quality.totalFrameDelay == '0') OK
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(updateend)
+RUN(quality = video.getVideoPlaybackQuality())
+EXPECTED (quality.totalVideoFrames == '8') OK
+EXPECTED (quality.corruptedVideoFrames == '1') OK
+EXPECTED (quality.droppedVideoFrames == '2') OK
+EXPECTED (quality.totalFrameDelay == '3') OK
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourcevideoplaybackqualityhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-video-playback-quality.html (0 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-video-playback-quality.html         (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-video-playback-quality.html        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+ <title>mock-media-source</title>
+ <script src="mock-media-source.js"></script>
+ <script src="../video-test.js"></script>
+ <script>
+ var source;
+ var sourceBuffer;
+ var initSegment;
+ var samples;
+ var quality;
+
+ if (window.internals)
+ internals.initializeMockMediaSource();
+
+ function runTest()
+ {
+ findMediaElement();
+
+ source = new MediaSource();
+ waitForEventOn(source, 'sourceopen', sourceOpen);
+ run('video.src = URL.createObjectURL(source)');
+ }
+
+ function sourceOpen()
+ {
+ run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+ waitForEventOn(sourceBuffer, 'updateend', loadSample, false, true);
+ initSegment = makeAInit(8, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+ run('sourceBuffer.appendBuffer(initSegment)');
+ }
+
+ function loadSample()
+ {
+ samples = concatenateSamples([makeASample(0, 0, 1, 1, SAMPLE_FLAG.NONE)]);
+ waitForEventOn(sourceBuffer, 'updateend', loadMoreSamples, false, true);
+ consoleWrite('Test that beginning a buffer with a non-sync sample results in that sample being dropped.')
+ run('sourceBuffer.appendBuffer(samples)');
+ }
+
+ function loadMoreSamples()
+ {
+ run('quality = video.getVideoPlaybackQuality()');
+ testExpected('quality.totalVideoFrames', 1);
+ testExpected('quality.corruptedVideoFrames', 0);
+ testExpected('quality.droppedVideoFrames', 1);
+ testExpected('quality.totalFrameDelay', 0);
+
+ samples = concatenateSamples([
+ makeASample(0, 0, 1, 1, SAMPLE_FLAG.SYNC),
+ makeASample(1, 1, 1, 1, SAMPLE_FLAG.CORRUPTED),
+ makeASample(2, 2, 1, 1, SAMPLE_FLAG.DROPPED),
+ makeASample(4, 4, 1, 1, SAMPLE_FLAG.DELAYED),
+ makeASample(5, 5, 1, 1, SAMPLE_FLAG.DELAYED),
+ makeASample(6, 6, 1, 1, SAMPLE_FLAG.DELAYED),
+ makeASample(7, 7, 1, 1, SAMPLE_FLAG.NONE),
+ ]);
+ waitForEventOn(sourceBuffer, 'updateend', samplesAdded, false, true);
+ run('sourceBuffer.appendBuffer(samples)');
+ }
+
+ function samplesAdded()
+ {
+ run('quality = video.getVideoPlaybackQuality()');
+ testExpected('quality.totalVideoFrames', 8);
+ testExpected('quality.corruptedVideoFrames', 1);
+ testExpected('quality.droppedVideoFrames', 2);
+ testExpected('quality.totalFrameDelay', 3);
+ endTest();
+ }
+ </script>
+</head>
+<body onload="runTest()">
+ <video></video>
+</body>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemockmediasourcejs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/media-source/mock-media-source.js (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/mock-media-source.js        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/LayoutTests/media/media-source/mock-media-source.js        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -11,6 +11,9 @@
</span><span class="cx"> var SAMPLE_FLAG = {
</span><span class="cx"> NONE: 0,
</span><span class="cx"> SYNC: 1 << 0,
</span><ins>+ CORRUPTED: 1 << 1,
+ DROPPED: 1 << 2,
+ DELAYED: 1 << 3,
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> function makeASample(presentationTime, decodeTime, duration, trackID, flags) {
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/CMakeLists.txt        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -185,6 +185,7 @@
</span><span class="cx"> Modules/mediasource/MediaSource.idl
</span><span class="cx"> Modules/mediasource/SourceBuffer.idl
</span><span class="cx"> Modules/mediasource/SourceBufferList.idl
</span><ins>+ Modules/mediasource/VideoPlaybackQuality.idl
</ins><span class="cx">
</span><span class="cx"> Modules/mediastream/AllAudioCapabilities.idl
</span><span class="cx"> Modules/mediastream/AllVideoCapabilities.idl
</span><span class="lines">@@ -829,6 +830,7 @@
</span><span class="cx"> Modules/mediasource/MediaSourceRegistry.cpp
</span><span class="cx"> Modules/mediasource/SourceBuffer.cpp
</span><span class="cx"> Modules/mediasource/SourceBufferList.cpp
</span><ins>+ Modules/mediasource/VideoPlaybackQuality.cpp
</ins><span class="cx">
</span><span class="cx"> Modules/mediastream/AudioStreamTrack.cpp
</span><span class="cx"> Modules/mediastream/CapabilityRange.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/ChangeLog        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -1,3 +1,99 @@
</span><ins>+2013-12-09 Jer Noble <jer.noble@apple.com>
+
+ [MSE] Add support for VideoPlaybackMetrics.
+ https://bugs.webkit.org/show_bug.cgi?id=125380
+
+ Reviewed by Eric Carlson.
+
+ Test: media/media-source/media-source-video-playback-quality.html
+
+ Add a new object type VideoPlaybackQuality to be returned by
+ HTMLMediaElement.getVideoPlaybackQuality().
+
+ HTMLMediaElements must separately track a droppedVideoFrame count, as
+ certain operations on SourceBuffer will drop incoming frames, which must
+ be accounted for. Reset this count when the media engine changes, which is
+ indicitive of a new media load requset starting.
+
+ Add the new VideoPlaybackQuality class:
+ * Modules/mediasource/VideoPlaybackQuality.cpp: Added.
+ (WebCore::VideoPlaybackQuality::create):
+ (WebCore::VideoPlaybackQuality::VideoPlaybackQuality):
+ * Modules/mediasource/VideoPlaybackQuality.h: Added.
+ (WebCore::VideoPlaybackQuality::creationTime):
+ (WebCore::VideoPlaybackQuality::totalVideoFrames):
+ (WebCore::VideoPlaybackQuality::droppedVideoFrames):
+ (WebCore::VideoPlaybackQuality::corruptedVideoFrames):
+ (WebCore::VideoPlaybackQuality::totalFrameDelay):
+ * Modules/mediasource/VideoPlaybackQuality.idl: Added.
+
+ Add support for the new class to HTMLMediaElement:
+ * html/HTMLMediaElement.cpp:
+ (HTMLMediaElement::shouldUseVideoPluginProxy):
+ (HTMLMediaElement::getVideoPlaybackQuality):
+ * html/HTMLMediaElement.h:
+ * html/HTMLMediaElement.idl:
+
+ Report the video quality metrics from the MediaPlayer:
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::totalVideoFrames):
+ (WebCore::MediaPlayer::droppedVideoFrames):
+ (WebCore::MediaPlayer::corruptedVideoFrames):
+ (WebCore::MediaPlayer::totalFrameDelay):
+ * platform/graphics/MediaPlayer.h:
+ * platform/graphics/MediaPlayerPrivate.h:
+ (WebCore::MediaPlayerPrivateInterface::totalVideoFrames):
+ (WebCore::MediaPlayerPrivateInterface::droppedVideoFrames):
+ (WebCore::MediaPlayerPrivateInterface::corruptedVideoFrames):
+ (WebCore::MediaPlayerPrivateInterface::totalFrameDelay):
+
+ Correctly report the dropped frame count:
+ * Modules/mediasource/SourceBuffer.cpp:
+ (WebCore::SourceBuffer::TrackBuffer::TrackBuffer): needsRandomAccessFlag defaults to true.
+ (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): Check the sync status of the incoming sample.
+ (WebCore::SourceBuffer::didDropSample): Notify the media element of a dropped frame.
+ * Modules/mediasource/SourceBuffer.h:
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement):
+ (HTMLMediaElement::mediaPlayerEngineUpdated): Reset m_droppedFrameCount.
+ (HTMLMediaElement::getVideoPlaybackQuality): Return a new VideoPlaybackQuality object.
+ * html/HTMLMediaElement.h:
+ (WebCore::HTMLMediaElement::incrementDroppedFrameCount): Simple incrementer.
+ * platform/MediaSample.h:
+ (WebCore::MediaSample::isSync): Convenience function.
+ (WebCore::MediaSample::isNonDisplaying): Ditto.
+
+ Add support in the AVFoundation MediaSource Engine:
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::totalVideoFrames):
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::droppedVideoFrames):
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::corruptedVideoFrames):
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::totalFrameDelay):
+
+ Add support in the Mock MediaSource Engine:
+ * platform/mock/mediasource/MockBox.h:
+ * platform/mock/mediasource/MockMediaPlayerMediaSource.cpp:
+ (WebCore::MockMediaPlayerMediaSource::totalVideoFrames): Simple accessor.
+ (WebCore::MockMediaPlayerMediaSource::droppedVideoFrames): Ditto.
+ (WebCore::MockMediaPlayerMediaSource::corruptedVideoFrames): Ditto.
+ (WebCore::MockMediaPlayerMediaSource::totalFrameDelay): Ditto.
+ * platform/mock/mediasource/MockMediaPlayerMediaSource.h:
+ * platform/mock/mediasource/MockMediaSourcePrivate.cpp:
+ (WebCore::MockMediaSourcePrivate::MockMediaSourcePrivate):
+ * platform/mock/mediasource/MockMediaSourcePrivate.h:
+ * platform/mock/mediasource/MockSourceBufferPrivate.cpp:
+ (WebCore::MockSourceBufferPrivate::enqueueSample): Increment the frame counts based on
+ the incoming sample.
+ * platform/mock/mediasource/MockSourceBufferPrivate.h:
+
+ Add the new files to the project:
+ * bindings/gobject/GNUmakefile.am:
+ * DerivedSources.make:
+ * WebCore.xcodeproj/project.pbxproj:
+ * GNUMakefile.list.am:
+ * CMakeLists.txt:
+
</ins><span class="cx"> 2013-12-09 Simon Fraser <simon.fraser@apple.com>
</span><span class="cx">
</span><span class="cx"> Avoid divide by zero in scrollbar code, and protect against Obj-C exceptions
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources.make (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources.make        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/DerivedSources.make        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -103,6 +103,7 @@
</span><span class="cx"> $(WebCore)/Modules/mediasource/SourceBufferList.idl \
</span><span class="cx">         $(WebCore)/Modules/mediasource/TextTrackMediaSource.idl \
</span><span class="cx">         $(WebCore)/Modules/mediasource/VideoTrackMediaSource.idl \
</span><ins>+        $(WebCore)/Modules/mediasource/VideoPlaybackQuality.idl \
</ins><span class="cx">         $(WebCore)/Modules/mediastream/AllVideoCapabilities.idl \
</span><span class="cx">         $(WebCore)/Modules/mediastream/AllAudioCapabilities.idl \
</span><span class="cx">         $(WebCore)/Modules/mediastream/AudioStreamTrack.idl \
</span></span></pre></div>
<a id="trunkSourceWebCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/GNUmakefile.list.am (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/GNUmakefile.list.am        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/GNUmakefile.list.am        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -735,6 +735,8 @@
</span><span class="cx">         DerivedSources/WebCore/JSValidityState.h \
</span><span class="cx">         DerivedSources/WebCore/JSVoidCallback.cpp \
</span><span class="cx">         DerivedSources/WebCore/JSVoidCallback.h \
</span><ins>+        DerivedSources/WebCore/JSVideoPlaybackQuality.h \
+        DerivedSources/WebCore/JSVideoPlaybackQuality.cpp \
</ins><span class="cx">         DerivedSources/WebCore/JSVideoStreamTrack.h \
</span><span class="cx">         DerivedSources/WebCore/JSVideoStreamTrack.cpp \
</span><span class="cx">         DerivedSources/WebCore/JSVideoTrack.cpp \
</span><span class="lines">@@ -1202,6 +1204,7 @@
</span><span class="cx">         $(WebCore)/Modules/mediasource/MediaSource.idl \
</span><span class="cx">         $(WebCore)/Modules/mediasource/SourceBuffer.idl \
</span><span class="cx">         $(WebCore)/Modules/mediasource/SourceBufferList.idl \
</span><ins>+        $(WebCore)/Modules/mediasource/VideoPlaybackQuality.idl \
</ins><span class="cx">         $(WebCore)/Modules/mediastream/AllVideoCapabilities.idl \
</span><span class="cx">         $(WebCore)/Modules/mediastream/AllAudioCapabilities.idl \
</span><span class="cx">         $(WebCore)/Modules/mediastream/AudioStreamTrack.idl \
</span><span class="lines">@@ -1884,6 +1887,8 @@
</span><span class="cx">         Source/WebCore/Modules/mediasource/DOMURLMediaSource.h \
</span><span class="cx">         Source/WebCore/Modules/mediasource/SampleMap.cpp \
</span><span class="cx">         Source/WebCore/Modules/mediasource/SampleMap.h \
</span><ins>+        Source/WebCore/Modules/mediasource/VideoPlaybackQuality.cpp \
+        Source/WebCore/Modules/mediasource/VideoPlaybackQuality.h \
</ins><span class="cx">         Source/WebCore/Modules/mediastream/AllAudioCapabilities.h \
</span><span class="cx">         Source/WebCore/Modules/mediastream/AllVideoCapabilities.h \
</span><span class="cx">         Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp \
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceSourceBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx"> , lastFrameDuration(MediaTime::invalidTime())
</span><span class="cx"> , highestPresentationTimestamp(MediaTime::invalidTime())
</span><span class="cx"> , lastEnqueuedPresentationTime(MediaTime::invalidTime())
</span><del>- , needRandomAccessFlag(false)
</del><ins>+ , needRandomAccessFlag(true)
</ins><span class="cx"> , enabled(false)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -860,11 +860,18 @@
</span><span class="cx"> // FIXME: implement append windows
</span><span class="cx">
</span><span class="cx"> // 1.11 If the need random access point flag on track buffer equals true, then run the following steps:
</span><del>- // 1.11.1 If the coded frame is not a random access point, then drop the coded frame and jump
- // to the top of the loop to start processing the next coded frame.
- // 1.11.2 Set the need random access point flag on track buffer to false.
- // NOTE: MockSampleBoxes are not decodable.
</del><ins>+ if (trackBuffer.needRandomAccessFlag) {
+ // 1.11.1 If the coded frame is not a random access point, then drop the coded frame and jump
+ // to the top of the loop to start processing the next coded frame.
+ if (!sample->isSync()) {
+ didDropSample();
+ return;
+ }
</ins><span class="cx">
</span><ins>+ // 1.11.2 Set the need random access point flag on track buffer to false.
+ trackBuffer.needRandomAccessFlag = false;
+ }
+
</ins><span class="cx"> // 1.12 Let spliced audio frame be an unset variable for holding audio splice information
</span><span class="cx"> // 1.13 Let spliced timed text frame be an unset variable for holding timed text splice information
</span><span class="cx"> // FIXME: Add support for sample splicing.
</span><span class="lines">@@ -1146,6 +1153,12 @@
</span><span class="cx"> LOG(Media, "SourceBuffer::provideMediaData(%p) - Enqueued %u samples", this, enqueuedSamples);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void SourceBuffer::didDropSample()
+{
+ if (!isRemoved())
+ m_source->mediaElement()->incrementDroppedFrameCount();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceSourceBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -141,6 +141,7 @@
</span><span class="cx"> bool validateInitializationSegment(const InitializationSegment&);
</span><span class="cx">
</span><span class="cx"> void provideMediaData();
</span><ins>+ void didDropSample();
</ins><span class="cx">
</span><span class="cx"> RefPtr<SourceBufferPrivate> m_private;
</span><span class="cx"> MediaSource* m_source;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceVideoPlaybackQualitycpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.cpp (0 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.cpp         (rev 0)
+++ trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.cpp        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "VideoPlaybackQuality.h"
+
+namespace WebCore {
+
+RefPtr<VideoPlaybackQuality> VideoPlaybackQuality::create(double creationTime, unsigned long totalVideoFrames, unsigned long droppedVideoFrames, unsigned long corruptedVideoFrames, double totalFrameDelay)
+{
+ return adoptRef(new VideoPlaybackQuality(creationTime, totalVideoFrames, droppedVideoFrames, corruptedVideoFrames, totalFrameDelay));
+}
+
+VideoPlaybackQuality::VideoPlaybackQuality(double creationTime, unsigned long totalVideoFrames, unsigned long droppedVideoFrames, unsigned long corruptedVideoFrames, double totalFrameDelay)
+ : m_creationTime(creationTime)
+ , m_totalVideoFrames(totalVideoFrames)
+ , m_droppedVideoFrames(droppedVideoFrames)
+ , m_corruptedVideoFrames(corruptedVideoFrames)
+ , m_totalFrameDelay(totalFrameDelay)
+{
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceVideoPlaybackQualityh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.h (0 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.h         (rev 0)
+++ trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VideoPlaybackQuality_h
+#define VideoPlaybackQuality_h
+
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class VideoPlaybackQuality : public RefCounted<VideoPlaybackQuality> {
+ WTF_MAKE_NONCOPYABLE(VideoPlaybackQuality)
+public:
+ static RefPtr<VideoPlaybackQuality> create(double creationTime, unsigned long totalVideoFrames, unsigned long droppedVideoFrames, unsigned long corruptedVideoFrames, double totalFrameDelay);
+
+ double creationTime() const { return m_creationTime; }
+ unsigned long totalVideoFrames() const { return m_totalVideoFrames; }
+ unsigned long droppedVideoFrames() const { return m_droppedVideoFrames; }
+ unsigned long corruptedVideoFrames() const { return m_corruptedVideoFrames; }
+ double totalFrameDelay() const { return m_totalFrameDelay; }
+
+protected:
+ VideoPlaybackQuality(double creationTime, unsigned long totalVideoFrames, unsigned long droppedVideoFrames, unsigned long corruptedVideoFrames, double totalFrameDelay);
+
+ double m_creationTime;
+ unsigned long m_totalVideoFrames;
+ unsigned long m_droppedVideoFrames;
+ unsigned long m_corruptedVideoFrames;
+ double m_totalFrameDelay;
+};
+
+}
+
+#endif // VideoPlaybackQuality_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceVideoPlaybackQualityidl"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.idl (0 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.idl         (rev 0)
+++ trunk/Source/WebCore/Modules/mediasource/VideoPlaybackQuality.idl        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=MEDIA_SOURCE,
+ NoInterfaceObject,
+ ImplementationLacksVTable,
+] interface VideoPlaybackQuality {
+ readonly attribute double creationTime;
+ readonly attribute unsigned long totalVideoFrames;
+ readonly attribute unsigned long droppedVideoFrames;
+ readonly attribute unsigned long corruptedVideoFrames;
+ readonly attribute double totalFrameDelay;
+};
+
+
+
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -5418,6 +5418,9 @@
</span><span class="cx">                 CDE3A85817F6020400C5BE20 /* AudioTrackPrivateAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = CDE3A85617F6020400C5BE20 /* AudioTrackPrivateAVFObjC.h */; };
</span><span class="cx">                 CDE7FC44181904B1002BBB77 /* OrderIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE7FC42181904B1002BBB77 /* OrderIterator.cpp */; };
</span><span class="cx">                 CDE7FC45181904B1002BBB77 /* OrderIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = CDE7FC43181904B1002BBB77 /* OrderIterator.h */; };
</span><ins>+                CDE83DB1183C44060031EAA3 /* VideoPlaybackQuality.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE83DAF183C44060031EAA3 /* VideoPlaybackQuality.cpp */; };
+                CDE83DB2183C44060031EAA3 /* VideoPlaybackQuality.h in Headers */ = {isa = PBXBuildFile; fileRef = CDE83DB0183C44060031EAA3 /* VideoPlaybackQuality.h */; };
+                CDE83DB6183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE83DB4183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp */; };
</ins><span class="cx">                 CDEA763014608A53008B31F1 /* PlatformClockCA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */; };
</span><span class="cx">                 CDEA76341460B56F008B31F1 /* ClockGeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA76321460AE29008B31F1 /* ClockGeneric.cpp */; };
</span><span class="cx">                 CDEA76351460B71A008B31F1 /* Clock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA76331460B462008B31F1 /* Clock.cpp */; };
</span><span class="lines">@@ -12543,6 +12546,11 @@
</span><span class="cx">                 CDE6560E17CA6E7600526BA7 /* mediaControlsApple.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = mediaControlsApple.js; sourceTree = "<group>"; };
</span><span class="cx">                 CDE7FC42181904B1002BBB77 /* OrderIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OrderIterator.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 CDE7FC43181904B1002BBB77 /* OrderIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OrderIterator.h; sourceTree = "<group>"; };
</span><ins>+                CDE83DAF183C44060031EAA3 /* VideoPlaybackQuality.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoPlaybackQuality.cpp; sourceTree = "<group>"; };
+                CDE83DB0183C44060031EAA3 /* VideoPlaybackQuality.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoPlaybackQuality.h; sourceTree = "<group>"; };
+                CDE83DB3183C441E0031EAA3 /* VideoPlaybackQuality.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = VideoPlaybackQuality.idl; sourceTree = "<group>"; };
+                CDE83DB4183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVideoPlaybackQuality.cpp; sourceTree = "<group>"; };
+                CDE83DB5183D352A0031EAA3 /* JSVideoPlaybackQuality.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVideoPlaybackQuality.h; sourceTree = "<group>"; };
</ins><span class="cx">                 CDEA762C14608224008B31F1 /* Clock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clock.h; sourceTree = "<group>"; };
</span><span class="cx">                 CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformClockCA.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 CDEA762F146084EE008B31F1 /* PlatformClockCA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformClockCA.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -17769,6 +17777,8 @@
</span><span class="cx">                                 BE8EF048171C9014009B48C3 /* JSVideoTrackList.cpp */,
</span><span class="cx">                                 BE8EF049171C9014009B48C3 /* JSVideoTrackList.h */,
</span><span class="cx">                                 97E9EC8B15DC492F004F2E71 /* JSVoidCallback.cpp */,
</span><ins>+                                CDE83DB4183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp */,
+                                CDE83DB5183D352A0031EAA3 /* JSVideoPlaybackQuality.h */,
</ins><span class="cx">                                 97E9EC8C15DC492F004F2E71 /* JSVoidCallback.h */,
</span><span class="cx">                                 A7D20F60107F406900A80392 /* JSWebGLActiveInfo.cpp */,
</span><span class="cx">                                 A7D20F61107F406900A80392 /* JSWebGLActiveInfo.h */,
</span><span class="lines">@@ -18574,6 +18584,9 @@
</span><span class="cx">                                 CD3A495D17A9D01B00274E42 /* SourceBufferList.idl */,
</span><span class="cx">                                 CD8B5A48180E138B008B8E65 /* TextTrackMediaSource.h */,
</span><span class="cx">                                 CD8B5A47180E1361008B8E65 /* TextTrackMediaSource.idl */,
</span><ins>+                                CDE83DAF183C44060031EAA3 /* VideoPlaybackQuality.cpp */,
+                                CDE83DB0183C44060031EAA3 /* VideoPlaybackQuality.h */,
+                                CDE83DB3183C441E0031EAA3 /* VideoPlaybackQuality.idl */,
</ins><span class="cx">                                 CD8B5A45180DFF4E008B8E65 /* VideoTrackMediaSource.h */,
</span><span class="cx">                                 CD8B5A44180DD8D6008B8E65 /* VideoTrackMediaSource.idl */,
</span><span class="cx">                                 CDD7089418359F6E002B3DC6 /* SampleMap.cpp */,
</span><span class="lines">@@ -23907,6 +23920,7 @@
</span><span class="cx">                                 B2FA3DFD0AB75A6F000E5AC4 /* JSSVGSVGElement.h in Headers */,
</span><span class="cx">                                 B2FA3DFF0AB75A6F000E5AC4 /* JSSVGSwitchElement.h in Headers */,
</span><span class="cx">                                 B2FA3E010AB75A6F000E5AC4 /* JSSVGSymbolElement.h in Headers */,
</span><ins>+                                CDE83DB2183C44060031EAA3 /* VideoPlaybackQuality.h in Headers */,
</ins><span class="cx">                                 B2FA3E030AB75A6F000E5AC4 /* JSSVGTextContentElement.h in Headers */,
</span><span class="cx">                                 B2FA3E050AB75A6F000E5AC4 /* JSSVGTextElement.h in Headers */,
</span><span class="cx">                                 B22362290C3AF04A0008CA9B /* JSSVGTextPathElement.h in Headers */,
</span><span class="lines">@@ -26432,6 +26446,7 @@
</span><span class="cx">                                 4FB390AD15EF61F3007AD51F /* GeneratedImage.cpp in Sources */,
</span><span class="cx">                                 2D481F03146B5C6500AA7834 /* GradientImage.cpp in Sources */,
</span><span class="cx">                                 0720B0A014D3323500642955 /* GenericEventQueue.cpp in Sources */,
</span><ins>+                                CDE83DB1183C44060031EAA3 /* VideoPlaybackQuality.cpp in Sources */,
</ins><span class="cx">                                 9746AF2314F4DDE6003E7A70 /* Geolocation.cpp in Sources */,
</span><span class="cx">                                 9746AF2614F4DDE6003E7A70 /* GeolocationController.cpp in Sources */,
</span><span class="cx">                                 B2C3DA6D0D006CD600EF6F26 /* GlyphPageTreeNode.cpp in Sources */,
</span><span class="lines">@@ -28025,6 +28040,7 @@
</span><span class="cx">                                 B22279A40D00BF220071B782 /* SVGComponentTransferFunctionElement.cpp in Sources */,
</span><span class="cx">                                 B2227B050D00BFF10071B782 /* SVGCSSComputedStyleDeclaration.cpp in Sources */,
</span><span class="cx">                                 078E090C17D14CEE00420AA1 /* RTCSessionDescription.cpp in Sources */,
</span><ins>+                                CDE83DB6183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp in Sources */,
</ins><span class="cx">                                 B2227B060D00BFF10071B782 /* SVGCSSParser.cpp in Sources */,
</span><span class="cx">                                 B2227B080D00BFF10071B782 /* SVGCSSStyleSelector.cpp in Sources */,
</span><span class="cx">                                 B22279A70D00BF220071B782 /* SVGCursorElement.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsgobjectGNUmakefileam"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/gobject/GNUmakefile.am (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/gobject/GNUmakefile.am        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/bindings/gobject/GNUmakefile.am        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -443,6 +443,7 @@
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMTextTrackCue.h \
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMTextTrackCueList.h \
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMTrackEvent.h \
</span><ins>+        DerivedSources/webkitdom/WebKitDOMVideoPlaybackQuality.h \
</ins><span class="cx">         DerivedSources/webkitdom/WebKitDOMVideoTrack.h \
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMVideoTrackList.h
</span><span class="cx"> webkitgtk_gdom_built_sources += \
</span><span class="lines">@@ -460,6 +461,7 @@
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMTextTrackCuePrivate.h \
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMTextTrackCueList.cpp \
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMTextTrackCueListPrivate.h \
</span><ins>+        DerivedSources/webkitdom/WebKitDOMVideoPlaybackQuality.cpp \
</ins><span class="cx">         DerivedSources/webkitdom/WebKitDOMVideoTrack.cpp \
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMVideoTrackList.cpp \
</span><span class="cx">         DerivedSources/webkitdom/WebKitDOMTrackEvent.cpp \
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -108,7 +108,10 @@
</span><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span><ins>+#include "DOMWindow.h"
</ins><span class="cx"> #include "HTMLMediaSource.h"
</span><ins>+#include "Performance.h"
+#include "VideoPlaybackQuality.h"
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="lines">@@ -271,6 +274,9 @@
</span><span class="cx"> , m_preload(MediaPlayer::Auto)
</span><span class="cx"> , m_displayMode(Unknown)
</span><span class="cx"> , m_processingMediaPlayerCallback(0)
</span><ins>+#if ENABLE(MEDIA_SOURCE)
+ , m_droppedVideoFrames(0)
+#endif
</ins><span class="cx"> , m_cachedTime(MediaPlayer::invalidTime())
</span><span class="cx"> , m_clockTimeAtLastCachedTimeUpdate(0)
</span><span class="cx"> , m_minimumClockTimeToUpdateCachedTime(0)
</span><span class="lines">@@ -3908,6 +3914,10 @@
</span><span class="cx"> if (renderer())
</span><span class="cx"> renderer()->updateFromElement();
</span><span class="cx"> endProcessingMediaPlayerCallback();
</span><ins>+
+#if ENABLE(MEDIA_SOURCE)
+ m_droppedVideoFrames = 0;
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable(MediaPlayer*)
</span><span class="lines">@@ -5230,6 +5240,29 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if ENABLE(MEDIA_SOURCE)
+RefPtr<VideoPlaybackQuality> HTMLMediaElement::getVideoPlaybackQuality()
+{
+#if ENABLE(WEB_TIMING)
+ DOMWindow* domWindow = document().domWindow();
+ Performance* performance = domWindow ? domWindow->performance() : nullptr;
+ double now = performance ? performance->now() : 0;
+#else
+ DocumentLoader* loader = document().loader();
+ double now = loader ? 1000.0 * loader->timing()->monotonicTimeToZeroBasedDocumentTime(monotonicallyIncreasingTime()) : 0;
+#endif
+
+ if (!m_player)
+ return VideoPlaybackQuality::create(now, 0, 0, 0, 0);
+
+ return VideoPlaybackQuality::create(now,
+ m_droppedVideoFrames + m_player->totalVideoFrames(),
+ m_droppedVideoFrames + m_player->droppedVideoFrames(),
+ m_player->corruptedVideoFrames(),
+ m_player->totalFrameDelay());
+}
+#endif
+
</ins><span class="cx"> #if ENABLE(MEDIA_CONTROLS_SCRIPT)
</span><span class="cx"> DOMWrapperWorld& HTMLMediaElement::ensureIsolatedWorld()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -80,6 +80,9 @@
</span><span class="cx"> #if ENABLE(ENCRYPTED_MEDIA_V2)
</span><span class="cx"> class MediaKeys;
</span><span class="cx"> #endif
</span><ins>+#if ENABLE(MEDIA_SOURCE)
+class VideoPlaybackQuality;
+#endif
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="cx"> class AudioTrackList;
</span><span class="lines">@@ -201,7 +204,8 @@
</span><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span><span class="cx"> // Media Source.
</span><span class="cx"> void closeMediaSource();
</span><del>-#endif
</del><ins>+ void incrementDroppedFrameCount() { ++m_droppedVideoFrames; }
+#endif
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(ENCRYPTED_MEDIA)
</span><span class="cx"> void webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionCode&);
</span><span class="lines">@@ -398,6 +402,10 @@
</span><span class="cx"> void mediaLoadingFailed(MediaPlayer::NetworkState);
</span><span class="cx"> void mediaLoadingFailedFatally(MediaPlayer::NetworkState);
</span><span class="cx">
</span><ins>+#if ENABLE(MEDIA_SOURCE)
+ RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality();
+#endif
+
</ins><span class="cx"> protected:
</span><span class="cx"> HTMLMediaElement(const QualifiedName&, Document&, bool);
</span><span class="cx"> virtual ~HTMLMediaElement();
</span><span class="lines">@@ -699,6 +707,7 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span><span class="cx"> RefPtr<HTMLMediaSource> m_mediaSource;
</span><ins>+ unsigned long m_droppedVideoFrames;
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> mutable double m_cachedTime;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.idl (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.idl        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/html/HTMLMediaElement.idl        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -117,4 +117,6 @@
</span><span class="cx">
</span><span class="cx"> [Reflect, TreatNullAs=NullString] attribute DOMString mediaGroup;
</span><span class="cx"> [CustomSetter] attribute MediaController controller;
</span><ins>+
+ [Conditional=MEDIA_SOURCE] VideoPlaybackQuality getVideoPlaybackQuality();
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformMediaSampleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/MediaSample.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/MediaSample.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/MediaSample.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -63,6 +63,9 @@
</span><span class="cx"> };
</span><span class="cx"> virtual SampleFlags flags() const = 0;
</span><span class="cx"> virtual PlatformSample platformSample() = 0;
</span><ins>+
+ bool isSync() const { return flags() & IsSync; }
+ bool isNonDisplaying() const { return flags() & NonDisplaying; }
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -1239,6 +1239,40 @@
</span><span class="cx"> return m_private->fileSize();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if ENABLE(MEDIA_SOURCE)
+unsigned long MediaPlayer::totalVideoFrames()
+{
+ if (!m_private)
+ return 0;
+
+ return m_private->totalVideoFrames();
+}
+
+unsigned long MediaPlayer::droppedVideoFrames()
+{
+ if (!m_private)
+ return 0;
+
+ return m_private->droppedVideoFrames();
+}
+
+unsigned long MediaPlayer::corruptedVideoFrames()
+{
+ if (!m_private)
+ return 0;
+
+ return m_private->corruptedVideoFrames();
+}
+
+double MediaPlayer::totalFrameDelay()
+{
+ if (!m_private)
+ return 0;
+
+ return m_private->totalFrameDelay();
+}
+#endif
+
</ins><span class="cx"> void MediaPlayerFactorySupport::callRegisterMediaEngine(MediaEngineRegister registerMediaEngine)
</span><span class="cx"> {
</span><span class="cx"> registerMediaEngine(addMediaEngine);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayer.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -514,6 +514,13 @@
</span><span class="cx">
</span><span class="cx"> unsigned long long fileSize() const;
</span><span class="cx">
</span><ins>+#if ENABLE(MEDIA_SOURCE)
+ unsigned long totalVideoFrames();
+ unsigned long droppedVideoFrames();
+ unsigned long corruptedVideoFrames();
+ double totalFrameDelay();
+#endif
+
</ins><span class="cx"> private:
</span><span class="cx"> MediaPlayer(MediaPlayerClient*);
</span><span class="cx"> MediaPlayerFactory* nextBestMediaEngine(MediaPlayerFactory*) const;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayerPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -215,6 +215,13 @@
</span><span class="cx"> virtual size_t extraMemoryCost() const { return 0; }
</span><span class="cx">
</span><span class="cx"> virtual unsigned long long fileSize() const { return 0; }
</span><ins>+
+#if ENABLE(MEDIA_SOURCE)
+ virtual unsigned long totalVideoFrames() { return 0; }
+ virtual unsigned long droppedVideoFrames() { return 0; }
+ virtual unsigned long corruptedVideoFrames() { return 0; }
+ virtual double totalFrameDelay() { return 0; }
+#endif
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -129,6 +129,11 @@
</span><span class="cx">
</span><span class="cx"> virtual size_t extraMemoryCost() const OVERRIDE;
</span><span class="cx">
</span><ins>+ virtual unsigned long totalVideoFrames() OVERRIDE;
+ virtual unsigned long droppedVideoFrames() OVERRIDE;
+ virtual unsigned long corruptedVideoFrames() OVERRIDE;
+ virtual double totalFrameDelay() OVERRIDE;
+
</ins><span class="cx"> void ensureLayer();
</span><span class="cx"> void destroyLayer();
</span><span class="cx"> void durationChanged();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -50,7 +50,22 @@
</span><span class="cx"> SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVURLAsset)
</span><span class="cx"> SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferDisplayLayer)
</span><span class="cx"> SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVStreamDataParser)
</span><ins>+SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVVideoPerformanceMetrics)
</ins><span class="cx">
</span><ins>+#pragma mark -
+#pragma mark AVVideoPerformanceMetrics
+
+@interface AVVideoPerformanceMetrics : NSObject
+- (unsigned long)totalNumberOfVideoFrames;
+- (unsigned long)numberOfDroppedVideoFrames;
+- (unsigned long)numberOfCorruptedVideoFrames;
+- (double)totalFrameDelay;
+@end
+
+@interface AVSampleBufferDisplayLayer (WebCoreAVSampleBufferDisplayLayerPrivate)
+- (AVVideoPerformanceMetrics *)videoPerformanceMetrics;
+@end
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> #pragma mark -
</span><span class="lines">@@ -366,6 +381,26 @@
</span><span class="cx"> return 0;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+unsigned long MediaPlayerPrivateMediaSourceAVFObjC::totalVideoFrames()
+{
+ return [[m_sampleBufferDisplayLayer videoPerformanceMetrics] totalNumberOfVideoFrames];
+}
+
+unsigned long MediaPlayerPrivateMediaSourceAVFObjC::droppedVideoFrames()
+{
+ return [[m_sampleBufferDisplayLayer videoPerformanceMetrics] numberOfDroppedVideoFrames];
+}
+
+unsigned long MediaPlayerPrivateMediaSourceAVFObjC::corruptedVideoFrames()
+{
+ return [[m_sampleBufferDisplayLayer videoPerformanceMetrics] numberOfCorruptedVideoFrames];
+}
+
+double MediaPlayerPrivateMediaSourceAVFObjC::totalFrameDelay()
+{
+ return [[m_sampleBufferDisplayLayer videoPerformanceMetrics] totalFrameDelay];
+}
+
</ins><span class="cx"> #pragma mark -
</span><span class="cx"> #pragma mark Utility Methods
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockmediasourceMockBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/mediasource/MockBox.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/mediasource/MockBox.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockBox.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -129,8 +129,16 @@
</span><span class="cx"> int32_t trackID() const { return m_trackID; }
</span><span class="cx"> uint8_t flags() const { return m_flags; }
</span><span class="cx">
</span><del>- enum { IsSync = 1 << 0 };
</del><ins>+ enum {
+ IsSync = 1 << 0,
+ IsCorrupted = 1 << 1,
+ IsDropped = 1 << 2,
+ IsDelayed = 1 << 3,
+ };
</ins><span class="cx"> bool isSync() const { return m_flags & IsSync; }
</span><ins>+ bool isCorrupted() const { return m_flags & IsCorrupted; }
+ bool isDropped() const { return m_flags & IsDropped; }
+ bool isDelayed() const { return m_flags & IsDelayed; }
</ins><span class="cx">
</span><span class="cx"> protected:
</span><span class="cx"> MediaTime m_presentationTimestamp;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockmediasourceMockMediaPlayerMediaSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -245,6 +245,26 @@
</span><span class="cx"> m_player->networkStateChanged();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+unsigned long MockMediaPlayerMediaSource::totalVideoFrames()
+{
+ return m_mediaSourcePrivate ? m_mediaSourcePrivate->totalVideoFrames() : 0;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+unsigned long MockMediaPlayerMediaSource::droppedVideoFrames()
+{
+ return m_mediaSourcePrivate ? m_mediaSourcePrivate->droppedVideoFrames() : 0;
+}
+
+unsigned long MockMediaPlayerMediaSource::corruptedVideoFrames()
+{
+ return m_mediaSourcePrivate ? m_mediaSourcePrivate->corruptedVideoFrames() : 0;
+}
+
+double MockMediaPlayerMediaSource::totalFrameDelay()
+{
+ return m_mediaSourcePrivate ? m_mediaSourcePrivate->totalFrameDelay() : 0;
+}
+
+}
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockmediasourceMockMediaPlayerMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -77,6 +77,10 @@
</span><span class="cx"> virtual double currentTimeDouble() const OVERRIDE;
</span><span class="cx"> virtual double durationDouble() const OVERRIDE;
</span><span class="cx"> virtual void seekWithTolerance(double time, double, double) OVERRIDE;
</span><ins>+ virtual unsigned long totalVideoFrames() OVERRIDE;
+ virtual unsigned long droppedVideoFrames() OVERRIDE;
+ virtual unsigned long corruptedVideoFrames() OVERRIDE;
+ virtual double totalFrameDelay() OVERRIDE;
</ins><span class="cx">
</span><span class="cx"> MediaPlayer* m_player;
</span><span class="cx"> RefPtr<HTMLMediaSource> m_mediaSource;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockmediasourceMockMediaSourcePrivatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.cpp (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.cpp        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.cpp        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -44,6 +44,10 @@
</span><span class="cx"> : m_player(parent)
</span><span class="cx"> , m_duration(std::numeric_limits<float>::quiet_NaN())
</span><span class="cx"> , m_isEnded(false)
</span><ins>+ , m_totalVideoFrames(0)
+ , m_droppedVideoFrames(0)
+ , m_corruptedVideoFrames(0)
+ , m_totalFrameDelay(0)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockmediasourceMockMediaSourcePrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -52,6 +52,16 @@
</span><span class="cx"> void seekToTime(const MediaTime&);
</span><span class="cx"> MediaTime seekToTime(const MediaTime&, const MediaTime& negativeThreshold, const MediaTime& positiveThreshold);
</span><span class="cx">
</span><ins>+ unsigned long totalVideoFrames() const { return m_totalVideoFrames; }
+ unsigned long droppedVideoFrames() const { return m_droppedVideoFrames; }
+ unsigned long corruptedVideoFrames() const { return m_corruptedVideoFrames; }
+ double totalFrameDelay() const { return m_totalFrameDelay; }
+
+ void incrementTotalVideoFrames() { ++m_totalVideoFrames; }
+ void incrementDroppedFrames() { ++m_droppedVideoFrames; }
+ void incrementCorruptedFrames() { ++m_corruptedVideoFrames; }
+ void incrementTotalFrameDelayBy(double delay) { m_totalFrameDelay += delay; }
+
</ins><span class="cx"> private:
</span><span class="cx"> MockMediaSourcePrivate(MockMediaPlayerMediaSource*);
</span><span class="cx">
</span><span class="lines">@@ -74,6 +84,11 @@
</span><span class="cx"> Vector<RefPtr<MockSourceBufferPrivate>> m_sourceBuffers;
</span><span class="cx"> Vector<MockSourceBufferPrivate*> m_activeSourceBuffers;
</span><span class="cx"> bool m_isEnded;
</span><ins>+
+ unsigned long m_totalVideoFrames;
+ unsigned long m_droppedVideoFrames;
+ unsigned long m_corruptedVideoFrames;
+ double m_totalFrameDelay;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockmediasourceMockSourceBufferPrivatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -218,6 +218,28 @@
</span><span class="cx"> m_mediaSource->sourceBufferPrivateDidChangeActiveState(this, isActive);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void MockSourceBufferPrivate::enqueueSample(PassRefPtr<MediaSample> sample, AtomicString)
+{
+ if (!m_mediaSource || !sample)
+ return;
+
+ PlatformSample platformSample = sample->platformSample();
+ if (platformSample.type != PlatformSample::MockSampleBoxType)
+ return;
+
+ MockSampleBox* box = platformSample.sample.mockSampleBox;
+ if (!box)
+ return;
+
+ m_mediaSource->incrementTotalVideoFrames();
+ if (box->isCorrupted())
+ m_mediaSource->incrementCorruptedFrames();
+ if (box->isDropped())
+ m_mediaSource->incrementDroppedFrames();
+ if (box->isDelayed())
+ m_mediaSource->incrementTotalFrameDelayBy(1);
+}
+
</ins><span class="cx"> bool MockSourceBufferPrivate::hasVideo() const
</span><span class="cx"> {
</span><span class="cx"> if (!m_client)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockmediasourceMockSourceBufferPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h (160335 => 160336)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h        2013-12-09 23:27:42 UTC (rev 160335)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h        2013-12-09 23:36:56 UTC (rev 160336)
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx"> virtual bool isFull() OVERRIDE;
</span><span class="cx">
</span><span class="cx"> virtual void flushAndEnqueueNonDisplayingSamples(Vector<RefPtr<MediaSample>>, AtomicString) OVERRIDE { }
</span><del>- virtual void enqueueSample(PassRefPtr<MediaSample>, AtomicString) OVERRIDE { }
</del><ins>+ virtual void enqueueSample(PassRefPtr<MediaSample>, AtomicString) OVERRIDE;
</ins><span class="cx"> virtual bool isReadyForMoreSamples() OVERRIDE { return true; }
</span><span class="cx"> virtual void setActive(bool) OVERRIDE;
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>