Changeset 221098 in webkit
- Timestamp:
- Aug 23, 2017 1:16:51 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r221096 r221098 1 2017-08-23 Jer Noble <jer.noble@apple.com> 2 3 Track VideoPlaybackQuality metrics when using WebCoreDecompressionSession. 4 https://bugs.webkit.org/show_bug.cgi?id=175835 5 <rdar://problem/34022234> 6 7 Reviewed by Eric Carlson. 8 9 * platform/mac/media/media-source/videoplaybackquality-decompressionsession-expected.txt: Added. 10 * platform/mac/media/media-source/videoplaybackquality-decompressionsession.html: Added. 11 1 12 2017-08-23 Matt Lewis <jlewis3@apple.com> 2 13 -
trunk/LayoutTests/media/media-source/media-source-loader.js
r178486 r221098 1 function MediaSourceLoader(url )1 function MediaSourceLoader(url, prefix) 2 2 { 3 3 this._url = url; 4 this._prefix = prefix; 4 5 setTimeout(this.loadManifest.bind(this)); 5 6 … … 41 42 { 42 43 var request = new XMLHttpRequest(); 43 request.open('GET', this._manifest.url, true); 44 var url = (this._prefix ? this._prefix : '') + this._manifest.url 45 request.open('GET', url, true); 44 46 request.responseType = 'arraybuffer'; 45 47 request.onload = this.loadMediaDataSucceeded.bind(this); -
trunk/Source/WebCore/ChangeLog
r221094 r221098 1 2017-08-23 Jer Noble <jer.noble@apple.com> 2 3 Track VideoPlaybackQuality metrics when using WebCoreDecompressionSession. 4 https://bugs.webkit.org/show_bug.cgi?id=175835 5 <rdar://problem/34022234> 6 7 Reviewed by Eric Carlson. 8 9 Test: platform/mac/media/media-source/videoplaybackquality-decompressionsession.html 10 11 Track the total number of frames decoded, dropped, & corrupted, as well as the total 12 delay imposed by decoding in the WebCoreDecompressionSession. 13 14 Drive-by fix: implement frame dropping by skipping frames whose presentation times are 15 before the video's current time and which aren't depended upon by other frames. 16 17 * platform/cf/CoreMediaSoftLink.cpp: 18 * platform/cf/CoreMediaSoftLink.h: 19 * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm: 20 (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::videoPlaybackQualityMetrics): 21 * platform/graphics/cocoa/WebCoreDecompressionSession.h: 22 (WebCore::WebCoreDecompressionSession::totalVideoFrames): 23 (WebCore::WebCoreDecompressionSession::droppedVideoFrames): 24 (WebCore::WebCoreDecompressionSession::corruptedVideoFrames): 25 (WebCore::WebCoreDecompressionSession::totalFrameDelay): 26 * platform/graphics/cocoa/WebCoreDecompressionSession.mm: 27 (WebCore::WebCoreDecompressionSession::shouldDecodeSample): 28 (WebCore::WebCoreDecompressionSession::decodeSample): 29 (WebCore::WebCoreDecompressionSession::handleDecompressionOutput): 30 1 31 2017-08-23 Andy Estes <aestes@apple.com> 2 32 -
trunk/Source/WebCore/platform/cf/CoreMediaSoftLink.cpp
r220243 r221098 49 49 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeMake, CMTime, (int64_t value, int32_t timescale), (value, timescale)) 50 50 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeMakeWithSeconds, CMTime, (Float64 seconds, int32_t preferredTimeScale), (seconds, preferredTimeScale)) 51 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeSubtract, CMTime, (CMTime minuend, CMTime subtrahend), (minuend, subtrahend)) 51 52 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeRangeGetEnd, CMTime, (CMTimeRange range), (range)) 52 53 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeRangeMake, CMTimeRange, (CMTime start, CMTime duration), (start, duration)) … … 156 157 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeMinimum, CMTime, (CMTime time1, CMTime time2), (time1, time2)) 157 158 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeRangeContainsTime, Boolean, (CMTimeRange range, CMTime time), (range, time)) 158 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeSubtract, CMTime, (CMTime minuend, CMTime subtrahend), (minuend, subtrahend))159 159 160 160 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreMedia, kCMTimeIndefinite, CMTime) -
trunk/Source/WebCore/platform/cf/CoreMediaSoftLink.h
r220243 r221098 60 60 SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreMedia, CMTimeMakeWithSeconds, CMTime, (Float64 seconds, int32_t preferredTimeScale), (seconds, preferredTimeScale)) 61 61 #define CMTimeMakeWithSeconds softLink_CoreMedia_CMTimeMakeWithSeconds 62 SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreMedia, CMTimeSubtract, CMTime, (CMTime minuend, CMTime subtrahend), (minuend, subtrahend)) 63 #define CMTimeSubtract softLink_CoreMedia_CMTimeSubtract 62 64 SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreMedia, CMTimeRangeGetEnd, CMTime, (CMTimeRange range), (range)) 63 65 #define CMTimeRangeGetEnd softLink_CoreMedia_CMTimeRangeGetEnd … … 264 266 SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreMedia, CMTimeRangeContainsTime, Boolean, (CMTimeRange range, CMTime time), (range, time)) 265 267 #define CMTimeRangeContainsTime softLink_CoreMedia_CMTimeRangeContainsTime 266 SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreMedia, CMTimeSubtract, CMTime, (CMTime minuend, CMTime subtrahend), (minuend, subtrahend))267 #define CMTimeSubtract softLink_CoreMedia_CMTimeSubtract268 268 269 269 SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreMedia, kCMTimeIndefinite, CMTime) -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
r221046 r221098 690 690 std::optional<PlatformVideoPlaybackQualityMetrics> MediaPlayerPrivateMediaSourceAVFObjC::videoPlaybackQualityMetrics() 691 691 { 692 if (m_decompressionSession) { 693 return PlatformVideoPlaybackQualityMetrics( 694 m_decompressionSession->totalVideoFrames(), 695 m_decompressionSession->droppedVideoFrames(), 696 m_decompressionSession->corruptedVideoFrames(), 697 m_decompressionSession->totalFrameDelay().toDouble() 698 ); 699 } 692 700 693 701 auto metrics = [m_sampleBufferDisplayLayer videoPerformanceMetrics]; -
trunk/Source/WebCore/platform/graphics/cocoa/WebCoreDecompressionSession.h
r220186 r221098 71 71 void flush(); 72 72 73 unsigned long totalVideoFrames() { return m_totalVideoFrames; } 74 unsigned long droppedVideoFrames() { return m_droppedVideoFrames; } 75 unsigned long corruptedVideoFrames() { return m_corruptedVideoFrames; } 76 MediaTime totalFrameDelay() { return m_totalFrameDelay; } 77 73 78 private: 74 79 WebCoreDecompressionSession(); … … 80 85 void resetAutomaticDequeueTimer(); 81 86 void automaticDequeue(); 87 bool shouldDecodeSample(CMSampleBufferRef, bool displaying); 82 88 83 89 static void decompressionOutputCallback(void* decompressionOutputRefCon, void* sourceFrameRefCon, OSStatus, VTDecodeInfoFlags, CVImageBufferRef, CMTime presentationTimeStamp, CMTime presentationDuration); … … 107 113 bool m_invalidated { false }; 108 114 int m_framesBeingDecoded { 0 }; 115 unsigned long m_totalVideoFrames { 0 }; 116 unsigned long m_droppedVideoFrames { 0 }; 117 unsigned long m_corruptedVideoFrames { 0 }; 118 MediaTime m_totalFrameDelay; 109 119 }; 110 120 -
trunk/Source/WebCore/platform/graphics/cocoa/WebCoreDecompressionSession.mm
r220538 r221098 181 181 } 182 182 183 bool WebCoreDecompressionSession::shouldDecodeSample(CMSampleBufferRef sample, bool displaying) 184 { 185 if (!displaying) 186 return true; 187 188 if (!m_timebase) 189 return true; 190 191 auto currentTime = CMTimebaseGetTime(m_timebase.get()); 192 auto presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sample); 193 if (CMTimeCompare(presentationTimeStamp, currentTime) >= 0) 194 return true; 195 196 CFArrayRef attachments = CMSampleBufferGetSampleAttachmentsArray(sample, false); 197 if (!attachments) 198 return true; 199 200 for (CFIndex index = 0, count = CFArrayGetCount(attachments); index < count; ++index) { 201 CFDictionaryRef attachmentDict = (CFDictionaryRef)CFArrayGetValueAtIndex(attachments, index); 202 CFBooleanRef dependedOn = (CFBooleanRef)CFDictionaryGetValue(attachmentDict, kCMSampleAttachmentKey_IsDependedOnByOthers); 203 if (dependedOn && !CFBooleanGetValue(dependedOn)) 204 return false; 205 } 206 207 return true; 208 } 209 183 210 void WebCoreDecompressionSession::decodeSample(CMSampleBufferRef sample, bool displaying) 184 211 { … … 213 240 flags |= kVTDecodeFrame_DoNotOutputFrame; 214 241 242 if (!shouldDecodeSample(sample, displaying)) { 243 ++m_totalVideoFrames; 244 ++m_droppedVideoFrames; 245 return; 246 } 247 215 248 VTDecompressionSessionDecodeFrame(m_decompressionSession.get(), sample, flags, reinterpret_cast<void*>(displaying), nullptr); 216 249 } … … 225 258 void WebCoreDecompressionSession::handleDecompressionOutput(bool displaying, OSStatus status, VTDecodeInfoFlags infoFlags, CVImageBufferRef rawImageBuffer, CMTime presentationTimeStamp, CMTime presentationDuration) 226 259 { 227 UNUSED_PARAM(status); 228 UNUSED_PARAM(infoFlags); 260 ++m_totalVideoFrames; 261 if (infoFlags & kVTDecodeInfo_FrameDropped) 262 ++m_droppedVideoFrames; 229 263 230 264 CMVideoFormatDescriptionRef rawImageBufferDescription = nullptr; 231 if (noErr != CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, rawImageBuffer, &rawImageBufferDescription)) 232 return; 265 if (status != noErr || noErr != CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, rawImageBuffer, &rawImageBufferDescription)) { 266 ++m_corruptedVideoFrames; 267 return; 268 } 233 269 RetainPtr<CMVideoFormatDescriptionRef> imageBufferDescription = adoptCF(rawImageBufferDescription); 234 270 … … 240 276 241 277 CMSampleBufferRef rawImageSampleBuffer = nullptr; 242 if (noErr != CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, rawImageBuffer, imageBufferDescription.get(), &imageBufferTiming, &rawImageSampleBuffer)) 243 return; 244 RefPtr<WebCoreDecompressionSession> protectedThis { this }; 245 RetainPtr<CMSampleBufferRef> imageSampleBuffer = adoptCF(rawImageSampleBuffer); 246 dispatch_async(m_enqueingQueue.get(), [protectedThis, imageSampleBuffer, displaying] { 278 if (noErr != CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, rawImageBuffer, imageBufferDescription.get(), &imageBufferTiming, &rawImageSampleBuffer)) { 279 ++m_corruptedVideoFrames; 280 return; 281 } 282 283 auto currentTime = CMTimebaseGetTime(m_timebase.get()); 284 if (m_timebase && CMTimeCompare(presentationTimeStamp, currentTime) < 0) 285 m_totalFrameDelay += toMediaTime(CMTimeSubtract(currentTime, presentationTimeStamp)); 286 287 dispatch_async(m_enqueingQueue.get(), [protectedThis = makeRefPtr(this), status, imageSampleBuffer = adoptCF(rawImageSampleBuffer), infoFlags, displaying] { 288 UNUSED_PARAM(infoFlags); 247 289 protectedThis->enqueueDecodedSample(imageSampleBuffer.get(), displaying); 248 290 });
Note: See TracChangeset
for help on using the changeset viewer.