Changeset 202829 in webkit
- Timestamp:
- Jul 5, 2016 1:22:58 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r202826 r202829 1 2016-07-05 Jer Noble <jer.noble@apple.com> 2 3 REGRESSION (r202641): Netflix playback stalls after a few seconds 4 https://bugs.webkit.org/show_bug.cgi?id=159365 5 6 Reviewed by Eric Carlson. 7 8 * media/media-source/media-source-small-gap-expected.txt: Added. 9 * media/media-source/media-source-small-gap.html: Added. 10 1 11 2016-07-05 Myles C. Maxfield <mmaxfield@apple.com> 2 12 -
trunk/Source/WTF/ChangeLog
r202799 r202829 1 2016-07-01 Jer Noble <jer.noble@apple.com> 2 3 REGRESSION (r202641): Netflix playback stalls after a few seconds 4 https://bugs.webkit.org/show_bug.cgi?id=159365 5 6 Reviewed by Eric Carlson. 7 8 Add a isBetween() convenience method. 9 10 * wtf/MediaTime.cpp: 11 (WTF::MediaTime::isBetween): 12 * wtf/MediaTime.h: 13 1 14 2016-07-03 Per Arne Vollan <pvollan@apple.com> 2 15 -
trunk/Source/WTF/wtf/MediaTime.cpp
r176863 r202829 434 434 } 435 435 436 bool MediaTime::isBetween(const MediaTime& a, const MediaTime& b) const 437 { 438 if (a > b) 439 return *this > b && *this < a; 440 return *this > a && *this < b; 441 } 442 436 443 const MediaTime& MediaTime::zeroTime() 437 444 { -
trunk/Source/WTF/wtf/MediaTime.h
r176863 r202829 89 89 90 90 ComparisonFlags compare(const MediaTime& rhs) const; 91 bool isBetween(const MediaTime&, const MediaTime&) const; 91 92 92 93 bool isValid() const { return m_timeFlags & Valid; } -
trunk/Source/WebCore/ChangeLog
r202822 r202829 1 2016-07-01 Jer Noble <jer.noble@apple.com> 2 3 REGRESSION (r202641): Netflix playback stalls after a few seconds 4 https://bugs.webkit.org/show_bug.cgi?id=159365 5 6 Reviewed by Eric Carlson. 7 8 Test: LayoutTests/media/media-source/media-source-small-gap.html 9 10 In r202641, we removed a "fudge factor" of 1 millisecond added onto the duration 11 of every sample for the purposes of calculating a SourceBuffer's buffered ranges. 12 Netflix (and likely other providers) have streams that have 1 "timeScale" gaps 13 between segments (e.g., 1/9000s, 1/3003s, etc.). Fill those gaps by looking for 14 the previous and next samples and extending the buffered range to cover the gaps 15 if they're short enough. We have to ensure that we correctly remove those extended 16 durations when we remove samples from the SourceBuffer as well. 17 18 * Modules/mediasource/SourceBuffer.cpp: 19 (WebCore::removeSamplesFromTrackBuffer): 20 (WebCore::SourceBuffer::removeCodedFrames): 21 (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): 22 1 23 2016-07-05 Brady Eidson <beidson@apple.com> 2 24 -
trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp
r202641 r202829 653 653 } 654 654 655 static P assRefPtr<TimeRanges>removeSamplesFromTrackBuffer(const DecodeOrderSampleMap::MapType& samples, SourceBuffer::TrackBuffer& trackBuffer, const SourceBuffer* buffer, const char* logPrefix)655 static PlatformTimeRanges removeSamplesFromTrackBuffer(const DecodeOrderSampleMap::MapType& samples, SourceBuffer::TrackBuffer& trackBuffer, const SourceBuffer* buffer, const char* logPrefix) 656 656 { 657 657 #if !LOG_DISABLED … … 664 664 #endif 665 665 666 auto erasedRanges = TimeRanges::create();666 PlatformTimeRanges erasedRanges; 667 667 for (auto sampleIt : samples) { 668 668 const DecodeOrderSampleMap::KeyType& decodeKey = sampleIt.first; … … 682 682 auto startTime = sample->presentationTime(); 683 683 auto endTime = startTime + sample->duration(); 684 erasedRanges ->ranges().add(startTime, endTime);684 erasedRanges.add(startTime, endTime); 685 685 686 686 #if !LOG_DISABLED … … 693 693 } 694 694 695 // Because we may have added artificial padding in the buffered ranges when adding samples, we may 696 // need to remove that padding when removing those same samples. Walk over the erased ranges looking 697 // for unbuffered areas and expand erasedRanges to encompass those areas. 698 PlatformTimeRanges additionalErasedRanges; 699 for (unsigned i = 0; i < erasedRanges.length(); ++i) { 700 auto erasedStart = erasedRanges.start(i); 701 auto erasedEnd = erasedRanges.end(i); 702 auto startIterator = trackBuffer.samples.presentationOrder().reverseFindSampleBeforePresentationTime(erasedStart); 703 if (startIterator == trackBuffer.samples.presentationOrder().rend()) 704 additionalErasedRanges.add(MediaTime::zeroTime(), erasedStart); 705 else { 706 auto& previousSample = *startIterator->second; 707 if (previousSample.presentationTime() + previousSample.duration() < erasedStart) 708 additionalErasedRanges.add(previousSample.presentationTime() + previousSample.duration(), erasedStart); 709 } 710 711 auto endIterator = trackBuffer.samples.presentationOrder().findSampleOnOrAfterPresentationTime(erasedEnd); 712 if (endIterator == trackBuffer.samples.presentationOrder().end()) 713 additionalErasedRanges.add(erasedEnd, MediaTime::positiveInfiniteTime()); 714 else { 715 auto& nextSample = *endIterator->second; 716 if (nextSample.presentationTime() > erasedEnd) 717 additionalErasedRanges.add(erasedEnd, nextSample.presentationTime()); 718 } 719 } 720 if (additionalErasedRanges.length()) 721 erasedRanges.unionWith(additionalErasedRanges); 722 695 723 #if !LOG_DISABLED 696 724 if (bytesRemoved) … … 698 726 #endif 699 727 700 return WTFMove(erasedRanges);728 return erasedRanges; 701 729 } 702 730 … … 743 771 744 772 DecodeOrderSampleMap::MapType erasedSamples(removeDecodeStart, removeDecodeEnd); 745 RefPtr<TimeRanges>erasedRanges = removeSamplesFromTrackBuffer(erasedSamples, trackBuffer, this, "removeCodedFrames");773 PlatformTimeRanges erasedRanges = removeSamplesFromTrackBuffer(erasedSamples, trackBuffer, this, "removeCodedFrames"); 746 774 747 775 // Only force the TrackBuffer to re-enqueue if the removed ranges overlap with enqueued and possibly … … 749 777 if (currentMediaTime < trackBuffer.lastEnqueuedPresentationTime) { 750 778 PlatformTimeRanges possiblyEnqueuedRanges(currentMediaTime, trackBuffer.lastEnqueuedPresentationTime); 751 possiblyEnqueuedRanges.intersectWith(erasedRanges ->ranges());779 possiblyEnqueuedRanges.intersectWith(erasedRanges); 752 780 if (possiblyEnqueuedRanges.length()) 753 781 trackBuffer.needsReenqueueing = true; 754 782 } 755 783 756 erasedRanges ->invert();757 m_buffered-> intersectWith(*erasedRanges);784 erasedRanges.invert(); 785 m_buffered->ranges().intersectWith(erasedRanges); 758 786 setBufferedDirty(true); 759 787 … … 1533 1561 dependentSamples.insert(firstDecodeIter, nextSyncIter); 1534 1562 1535 RefPtr<TimeRanges>erasedRanges = removeSamplesFromTrackBuffer(dependentSamples, trackBuffer, this, "sourceBufferPrivateDidReceiveSample");1563 PlatformTimeRanges erasedRanges = removeSamplesFromTrackBuffer(dependentSamples, trackBuffer, this, "sourceBufferPrivateDidReceiveSample"); 1536 1564 1537 1565 // Only force the TrackBuffer to re-enqueue if the removed ranges overlap with enqueued and possibly … … 1540 1568 if (currentMediaTime < trackBuffer.lastEnqueuedPresentationTime) { 1541 1569 PlatformTimeRanges possiblyEnqueuedRanges(currentMediaTime, trackBuffer.lastEnqueuedPresentationTime); 1542 possiblyEnqueuedRanges.intersectWith(erasedRanges ->ranges());1570 possiblyEnqueuedRanges.intersectWith(erasedRanges); 1543 1571 if (possiblyEnqueuedRanges.length()) 1544 1572 trackBuffer.needsReenqueueing = true; 1545 1573 } 1546 1574 1547 erasedRanges ->invert();1548 m_buffered-> intersectWith(*erasedRanges);1575 erasedRanges.invert(); 1576 m_buffered->ranges().intersectWith(erasedRanges); 1549 1577 setBufferedDirty(true); 1550 1578 } … … 1586 1614 m_timestampOffset = frameEndTimestamp; 1587 1615 1588 m_buffered->ranges().add(presentationTimestamp, presentationTimestamp + frameDuration); 1616 // Eliminate small gaps between buffered ranges by coalescing 1617 // disjoint ranges separated by less than a "fudge factor". 1618 auto presentationEndTime = presentationTimestamp + frameDuration; 1619 auto nearestToPresentationStartTime = m_buffered->ranges().nearest(presentationTimestamp); 1620 if ((presentationTimestamp - nearestToPresentationStartTime).isBetween(MediaTime::zeroTime(), currentTimeFudgeFactor())) 1621 presentationTimestamp = nearestToPresentationStartTime; 1622 1623 auto nearestToPresentationEndTime = m_buffered->ranges().nearest(presentationEndTime); 1624 if ((nearestToPresentationEndTime - presentationEndTime).isBetween(MediaTime::zeroTime(), currentTimeFudgeFactor())) 1625 presentationEndTime = nearestToPresentationEndTime; 1626 1627 m_buffered->ranges().add(presentationTimestamp, presentationEndTime); 1589 1628 m_bufferedSinceLastMonitor += frameDuration.toDouble(); 1590 1629 setBufferedDirty(true);
Note: See TracChangeset
for help on using the changeset viewer.