Title: [227631] trunk
Revision
227631
Author
[email protected]
Date
2018-01-25 14:29:55 -0800 (Thu, 25 Jan 2018)

Log Message

Move ImageDecoderAVFObjC from using AVSampleBufferGenerator to AVAssetReaderOutput for parsing
https://bugs.webkit.org/show_bug.cgi?id=182091

Reviewed by Eric Carlson.

Source/WebCore:

No new tests; should be covered by existing tests.

AVSampleBufferGenerator is not available on iOS, so in order to enable ImageDecoderAVFObjC there,
we must adopt a similar API which is available both on iOS and macOS: AVAssetReaderOutput. Unlike
the generator, AVAssetReaderOutput doesn't necessarily generate samples in decode order, so we'll
repurpose the SampleMap from EME to hold the decoded samples as well as their generated images.

* Modules/mediasource/SampleMap.cpp:
* Modules/mediasource/SampleMap.h:
(WebCore::SampleMap::size const):
* platform/MIMETypeRegistry.cpp:
(WebCore::MIMETypeRegistry::isSupportedImageVideoOrSVGMIMEType):
* platform/MediaSample.h:
(WebCore::MediaSample::hasAlpha const):
* platform/graphics/ImageDecoder.cpp:
(WebCore::ImageDecoder::create):
(WebCore::ImageDecoder::supportsMediaType):
* platform/graphics/avfoundation/MediaSampleAVFObjC.h: Make non-final.
(WebCore::MediaSampleAVFObjC::sampleBuffer const):
(WebCore::MediaSampleAVFObjC::MediaSampleAVFObjC):
* platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.h:
* platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm:
(WebCore::ImageDecoderAVFObjCSample::create):
(WebCore::ImageDecoderAVFObjCSample::sampleBuffer const):
(WebCore::ImageDecoderAVFObjCSample::image const):
(WebCore::ImageDecoderAVFObjCSample::setImage):
(WebCore::ImageDecoderAVFObjCSample::ImageDecoderAVFObjCSample):
(WebCore::ImageDecoderAVFObjCSample::cacheMetadata):
(WebCore::toSample):
(WebCore::ImageDecoderAVFObjC::readSamples):
(WebCore::ImageDecoderAVFObjC::storeSampleBuffer):
(WebCore::ImageDecoderAVFObjC::advanceCursor):
(WebCore::ImageDecoderAVFObjC::setTrack):
(WebCore::ImageDecoderAVFObjC::encodedDataStatus const):
(WebCore::ImageDecoderAVFObjC::repetitionCount const):
(WebCore::ImageDecoderAVFObjC::frameIsCompleteAtIndex const):
(WebCore::ImageDecoderAVFObjC::frameDurationAtIndex const):
(WebCore::ImageDecoderAVFObjC::frameHasAlphaAtIndex const):
(WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex):
(WebCore::ImageDecoderAVFObjC::setData):
(WebCore::ImageDecoderAVFObjC::clearFrameBufferCache):
(WebCore::ImageDecoderAVFObjC::sampleAtIndex const):
(WebCore::ImageDecoderAVFObjC::readSampleMetadata): Deleted.

Source/WTF:

* wtf/Platform.h:

LayoutTests:

* platform/ios/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/update-the-source-set-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (227630 => 227631)


--- trunk/LayoutTests/ChangeLog	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/LayoutTests/ChangeLog	2018-01-25 22:29:55 UTC (rev 227631)
@@ -1,3 +1,12 @@
+2018-01-25  Jer Noble  <[email protected]>
+
+        Move ImageDecoderAVFObjC from using AVSampleBufferGenerator to AVAssetReaderOutput for parsing
+        https://bugs.webkit.org/show_bug.cgi?id=182091
+
+        Reviewed by Eric Carlson.
+
+        * platform/ios/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/update-the-source-set-expected.txt: Added.
+
 2018-01-25  Antoine Quint  <[email protected]>
 
         [Web Animations] Account for provided easings when computing progress and resolving keyframe effect values

Added: trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/update-the-source-set-expected.txt (0 => 227631)


--- trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/update-the-source-set-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/update-the-source-set-expected.txt	2018-01-25 22:29:55 UTC (rev 227631)
@@ -0,0 +1,180 @@
+
+PASS <img data-expect=""> 
+FAIL <img src="" data-expect=""> assert_equals: expected "" but got "http://localhost:8800/html/semantics/embedded-content/the-img-element/update-the-source-set.html"
+PASS <img src="" data-expect="data:,a"> 
+PASS <img srcset="" src="" data-expect="data:,a"> 
+PASS <img srcset="data:,b" src="" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b" data-expect="data:,b"><!-- srcset after src --> 
+PASS <img src="" srcset="data:,b 1x" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b 1.0x" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b 1e0x" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b 10000w" sizes="1px" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b 10000w, data:,c 10000x" sizes="1px" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b 10000x, data:,c 10000w" sizes="1px" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b 1w" sizes="10000px" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b 1w, data:,c 0.0001x" sizes="10000px" data-expect="data:,b"> 
+PASS <img src="" srcset="data:,b 0.0001x, data:,c 1w" sizes="10000px" data-expect="data:,b"> 
+PASS <img srcset="data:,a" data-expect="data:,a"> 
+PASS <picture>foo<img src="" data-expect="data:,a"></picture> 
+PASS <picture><!--foo--><img src="" data-expect="data:,a"></picture> 
+PASS <picture><br><img src="" data-expect="data:,a"></picture> 
+PASS <picture><p></p><img src="" data-expect="data:,a"></picture> 
+PASS <picture><video><source srcset="data:,b"></video><img src="" data-expect="data:,a"></picture> 
+PASS <picture><span><source srcset="data:,b"></span><img src="" data-expect="data:,a"></picture> 
+PASS <picture><svg><source srcset="data:,b"></source></svg><img src="" data-expect="data:,a"></picture> 
+PASS <picture><svg></svg><source srcset="data:,b"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><svg><font></font><source srcset="data:,b"></source></svg><img src="" data-expect="data:,a"></picture> 
+PASS <picture><svg><!--<font face> tag breaks out of svg--></svg><font face=""></font><source srcset="data:,b"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><img src="" src="" data-expect="data:,b"></picture> 
+PASS <picture><source><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source src="" src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset=""><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset=", ,"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b 1x 1x"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" media=""><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" media="all"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" media="all and (min-width:0)"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" media="all and !"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" media="all and (!)"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" media="not all"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" media="not all and (min-width:0)"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" media="not all and (max-width:0)"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" media="not all and !"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" media="not all and (!)"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" media="all, !"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" media=","><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" media=", all"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type=""><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type=" "><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/gif"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type=" image/gif"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/gif "><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/gif;"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/gif;encodings"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/gif;encodings="><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/gif;encodings=foobar"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/png"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/jpeg"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/svg+xml"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="image/x-icon"><img src="" data-expect="data:,b"></picture> 
+PASS <picture><source srcset="data:,b" type="text/xml"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="text/html"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="text/plain"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="text/css"><img src="" data-expect="data:,a"></picture> 
+FAIL <picture><source srcset="data:,b" type="video/mp4"><img src="" data-expect="data:,a"></picture> assert_equals: expected "data:,a" but got "data:,b"
+PASS <picture><source srcset="data:,b" type="video/ogg"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="video/webm"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="unknown/unknown"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="application/octet-stream"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="application/x-shockwave-flash"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="image\gif"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="gif"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type=".gif"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="*"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="*/*"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="image/*"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type=","><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="image/gif, image/png"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="image/gif image/png"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><source srcset="data:,b" type="image/foobarbaz"><img src="" data-expect="data:,a"></picture> 
+PASS <picture><img src="" data-expect="data:,a">foo</picture> 
+PASS <picture><img src="" data-expect="data:,a"><br></picture> 
+PASS <picture><img src="" data-expect="data:,a"><!--foo--></picture> 
+PASS <picture><img src="" data-expect="data:,a"><img src="" 
+PASS <picture><img data-expect=""><img src="" 
+PASS <picture><img src="" data-expect="data:,a"><source srcset="data:,b"></picture> 
+PASS <picture><img data-expect=""><source srcset="data:,b"></picture> 
+PASS <picture><span><source srcset="data:,b"><img data-expect=""></span></picture> 
+PASS <picture><span><source srcset="data:,b"><img src="" data-expect="data:,a"></span></picture> 
+PASS <picture><source srcset="data:,b"><span><img src="" data-expect="data:,a"></span></picture> 
+PASS <picture><source srcset="data:,b"><img data-expect="data:,b"></picture> 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+foo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+foo
+
+
+
+
+
+
+
+
+
+

Modified: trunk/Source/WTF/ChangeLog (227630 => 227631)


--- trunk/Source/WTF/ChangeLog	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WTF/ChangeLog	2018-01-25 22:29:55 UTC (rev 227631)
@@ -1,3 +1,12 @@
+2018-01-25  Jer Noble  <[email protected]>
+
+        Move ImageDecoderAVFObjC from using AVSampleBufferGenerator to AVAssetReaderOutput for parsing
+        https://bugs.webkit.org/show_bug.cgi?id=182091
+
+        Reviewed by Eric Carlson.
+
+        * wtf/Platform.h:
+
 2018-01-25  Mark Lam  <[email protected]>
 
         Rename the Poisoned::isPoisoned constant to Poisoned::isPoisonedType.

Modified: trunk/Source/WTF/wtf/Platform.h (227630 => 227631)


--- trunk/Source/WTF/wtf/Platform.h	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WTF/wtf/Platform.h	2018-01-25 22:29:55 UTC (rev 227631)
@@ -1166,8 +1166,8 @@
 #define USE_INSERTION_UNDO_GROUPING 1
 #endif
 
-#if PLATFORM(MAC)
-#define HAVE_AVSAMPLEBUFFERGENERATOR 1
+#if PLATFORM(MAC) || PLATFORM(IOS)
+#define HAVE_AVASSETREADER 1
 #endif
 
 #if PLATFORM(COCOA)

Modified: trunk/Source/WebCore/ChangeLog (227630 => 227631)


--- trunk/Source/WebCore/ChangeLog	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/ChangeLog	2018-01-25 22:29:55 UTC (rev 227631)
@@ -1,3 +1,54 @@
+2018-01-25  Jer Noble  <[email protected]>
+
+        Move ImageDecoderAVFObjC from using AVSampleBufferGenerator to AVAssetReaderOutput for parsing
+        https://bugs.webkit.org/show_bug.cgi?id=182091
+
+        Reviewed by Eric Carlson.
+
+        No new tests; should be covered by existing tests.
+
+        AVSampleBufferGenerator is not available on iOS, so in order to enable ImageDecoderAVFObjC there,
+        we must adopt a similar API which is available both on iOS and macOS: AVAssetReaderOutput. Unlike
+        the generator, AVAssetReaderOutput doesn't necessarily generate samples in decode order, so we'll
+        repurpose the SampleMap from EME to hold the decoded samples as well as their generated images.
+
+        * Modules/mediasource/SampleMap.cpp:
+        * Modules/mediasource/SampleMap.h:
+        (WebCore::SampleMap::size const):
+        * platform/MIMETypeRegistry.cpp:
+        (WebCore::MIMETypeRegistry::isSupportedImageVideoOrSVGMIMEType):
+        * platform/MediaSample.h:
+        (WebCore::MediaSample::hasAlpha const):
+        * platform/graphics/ImageDecoder.cpp:
+        (WebCore::ImageDecoder::create):
+        (WebCore::ImageDecoder::supportsMediaType):
+        * platform/graphics/avfoundation/MediaSampleAVFObjC.h: Make non-final.
+        (WebCore::MediaSampleAVFObjC::sampleBuffer const):
+        (WebCore::MediaSampleAVFObjC::MediaSampleAVFObjC):
+        * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.h:
+        * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm:
+        (WebCore::ImageDecoderAVFObjCSample::create):
+        (WebCore::ImageDecoderAVFObjCSample::sampleBuffer const):
+        (WebCore::ImageDecoderAVFObjCSample::image const):
+        (WebCore::ImageDecoderAVFObjCSample::setImage):
+        (WebCore::ImageDecoderAVFObjCSample::ImageDecoderAVFObjCSample):
+        (WebCore::ImageDecoderAVFObjCSample::cacheMetadata):
+        (WebCore::toSample):
+        (WebCore::ImageDecoderAVFObjC::readSamples):
+        (WebCore::ImageDecoderAVFObjC::storeSampleBuffer):
+        (WebCore::ImageDecoderAVFObjC::advanceCursor):
+        (WebCore::ImageDecoderAVFObjC::setTrack):
+        (WebCore::ImageDecoderAVFObjC::encodedDataStatus const):
+        (WebCore::ImageDecoderAVFObjC::repetitionCount const):
+        (WebCore::ImageDecoderAVFObjC::frameIsCompleteAtIndex const):
+        (WebCore::ImageDecoderAVFObjC::frameDurationAtIndex const):
+        (WebCore::ImageDecoderAVFObjC::frameHasAlphaAtIndex const):
+        (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex):
+        (WebCore::ImageDecoderAVFObjC::setData):
+        (WebCore::ImageDecoderAVFObjC::clearFrameBufferCache):
+        (WebCore::ImageDecoderAVFObjC::sampleAtIndex const):
+        (WebCore::ImageDecoderAVFObjC::readSampleMetadata): Deleted.
+
 2018-01-25  Youenn Fablet  <[email protected]>
 
         DocumentThreadableLoader should ensure service worker is not reused if redirection comes from the network

Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp (227630 => 227631)


--- trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp	2018-01-25 22:29:55 UTC (rev 227631)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "SampleMap.h"
 
-#if ENABLE(MEDIA_SOURCE)
-
 #include "MediaSample.h"
 
 namespace WebCore {
@@ -310,5 +308,3 @@
 }
 
 }
-
-#endif

Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.h (227630 => 227631)


--- trunk/Source/WebCore/Modules/mediasource/SampleMap.h	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.h	2018-01-25 22:29:55 UTC (rev 227631)
@@ -25,8 +25,6 @@
 
 #pragma once
 
-#if ENABLE(MEDIA_SOURCE)
-
 #include <map>
 #include <wtf/MediaTime.h>
 #include <wtf/RefPtr.h>
@@ -45,6 +43,7 @@
     typedef MapType::reverse_iterator reverse_iterator;
     typedef MapType::const_reverse_iterator const_reverse_iterator;
     typedef std::pair<iterator, iterator> iterator_range;
+    typedef MapType::value_type value_type;
 
     iterator begin() { return m_samples.begin(); }
     const_iterator begin() const { return m_samples.begin(); }
@@ -79,6 +78,7 @@
     typedef MapType::reverse_iterator reverse_iterator;
     typedef MapType::const_reverse_iterator const_reverse_iterator;
     typedef std::pair<reverse_iterator, reverse_iterator> reverse_iterator_range;
+    typedef MapType::value_type value_type;
 
     iterator begin() { return m_samples.begin(); }
     const_iterator begin() const { return m_samples.begin(); }
@@ -107,6 +107,7 @@
     SampleMap() = default;
 
     WEBCORE_EXPORT bool empty() const;
+    size_t size() const { return m_decodeOrder.m_samples.size(); }
     WEBCORE_EXPORT void clear();
     WEBCORE_EXPORT void addSample(MediaSample&);
     WEBCORE_EXPORT void removeSample(MediaSample*);
@@ -133,5 +134,3 @@
 }
 
 } // namespace WebCore
-
-#endif // ENABLE(MEDIA_SOURCE)

Modified: trunk/Source/WebCore/platform/MIMETypeRegistry.cpp (227630 => 227631)


--- trunk/Source/WebCore/platform/MIMETypeRegistry.cpp	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/platform/MIMETypeRegistry.cpp	2018-01-25 22:29:55 UTC (rev 227631)
@@ -55,7 +55,7 @@
 #include "ArchiveFactory.h"
 #endif
 
-#if HAVE(AVSAMPLEBUFFERGENERATOR)
+#if HAVE(AVASSETREADER)
 #include "ContentType.h"
 #include "ImageDecoderAVFObjC.h"
 #endif
@@ -460,7 +460,7 @@
     if (isSupportedImageMIMEType(mimeType) || equalLettersIgnoringASCIICase(mimeType, "image/svg+xml"))
         return true;
 
-#if HAVE(AVSAMPLEBUFFERGENERATOR)
+#if HAVE(AVASSETREADER)
     if (ImageDecoderAVFObjC::supportsContentType(ContentType(mimeType)))
         return true;
 #endif

Modified: trunk/Source/WebCore/platform/MediaSample.h (227630 => 227631)


--- trunk/Source/WebCore/platform/MediaSample.h	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/platform/MediaSample.h	2018-01-25 22:29:55 UTC (rev 227631)
@@ -79,6 +79,7 @@
         None = 0,
         IsSync = 1 << 0,
         IsNonDisplaying = 1 << 1,
+        HasAlpha = 1 << 2,
     };
     virtual SampleFlags flags() const = 0;
     virtual PlatformSample platformSample() = 0;
@@ -94,6 +95,7 @@
 
     bool isSync() const { return flags() & IsSync; }
     bool isNonDisplaying() const { return flags() & IsNonDisplaying; }
+    bool hasAlpha() const { return flags() & HasAlpha; }
 
     virtual void dump(PrintStream&) const = 0;
 };

Modified: trunk/Source/WebCore/platform/graphics/ImageDecoder.cpp (227630 => 227631)


--- trunk/Source/WebCore/platform/graphics/ImageDecoder.cpp	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/platform/graphics/ImageDecoder.cpp	2018-01-25 22:29:55 UTC (rev 227631)
@@ -34,7 +34,7 @@
 #include "ScalableImageDecoder.h"
 #endif
 
-#if HAVE(AVSAMPLEBUFFERGENERATOR)
+#if HAVE(AVASSETREADER)
 #include "ImageDecoderAVFObjC.h"
 #endif
 
@@ -42,7 +42,7 @@
 
 RefPtr<ImageDecoder> ImageDecoder::create(SharedBuffer& data, const String& mimeType, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
 {
-#if HAVE(AVSAMPLEBUFFERGENERATOR)
+#if HAVE(AVASSETREADER)
     if (ImageDecoderAVFObjC::canDecodeType(mimeType))
         return ImageDecoderAVFObjC::create(data, mimeType, alphaOption, gammaAndColorProfileOption);
 #else
@@ -61,7 +61,7 @@
 bool ImageDecoder::supportsMediaType(MediaType type)
 {
     bool supports = false;
-#if HAVE(AVSAMPLEBUFFERGENERATOR)
+#if HAVE(AVASSETREADER)
     if (ImageDecoderAVFObjC::supportsMediaType(type))
         supports = true;
 #endif

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaSampleAVFObjC.h (227630 => 227631)


--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaSampleAVFObjC.h	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaSampleAVFObjC.h	2018-01-25 22:29:55 UTC (rev 227631)
@@ -33,7 +33,7 @@
 
 namespace WebCore {
     
-class MediaSampleAVFObjC final : public MediaSample {
+class MediaSampleAVFObjC : public MediaSample {
 public:
     static Ref<MediaSampleAVFObjC> create(CMSampleBufferRef sample, int trackID) { return adoptRef(*new MediaSampleAVFObjC(sample, trackID)); }
     static Ref<MediaSampleAVFObjC> create(CMSampleBufferRef sample, AtomicString trackID) { return adoptRef(*new MediaSampleAVFObjC(sample, trackID)); }
@@ -41,9 +41,39 @@
     static RefPtr<MediaSampleAVFObjC> createImageSample(Ref<JSC::Uint8ClampedArray>&&, unsigned long width, unsigned long height);
     static RefPtr<MediaSampleAVFObjC> createImageSample(Vector<uint8_t>&&, unsigned long width, unsigned long height);
 
-    RefPtr<JSC::Uint8ClampedArray> getRGBAImageData() const final;
+    RefPtr<JSC::Uint8ClampedArray> getRGBAImageData() const override;
 
-private:
+    MediaTime presentationTime() const override;
+    MediaTime outputPresentationTime() const override;
+    MediaTime decodeTime() const override;
+    MediaTime duration() const override;
+    MediaTime outputDuration() const override;
+
+    AtomicString trackID() const override { return m_id; }
+    void setTrackID(const String& id) override { m_id = id; }
+
+    size_t sizeInBytes() const override;
+    FloatSize presentationSize() const override;
+
+    SampleFlags flags() const override;
+    PlatformSample platformSample() override;
+    void dump(PrintStream&) const override;
+    void offsetTimestampsBy(const MediaTime&) override;
+    void setTimestamps(const MediaTime&, const MediaTime&) override;
+    bool isDivisable() const override;
+    std::pair<RefPtr<MediaSample>, RefPtr<MediaSample>> divide(const MediaTime& presentationTime) override;
+    Ref<MediaSample> createNonDisplayingCopy() const override;
+
+    VideoRotation videoRotation() const override { return m_rotation; }
+    bool videoMirrored() const override { return m_mirrored; }
+
+    CMSampleBufferRef sampleBuffer() const { return m_sample.get(); }
+
+protected:
+    MediaSampleAVFObjC(RetainPtr<CMSampleBufferRef>&& sample)
+        : m_sample(WTFMove(sample))
+    {
+    }
     MediaSampleAVFObjC(CMSampleBufferRef sample)
         : m_sample(sample)
     {
@@ -66,31 +96,6 @@
     }
 
     virtual ~MediaSampleAVFObjC() = default;
-
-    MediaTime presentationTime() const override;
-    MediaTime outputPresentationTime() const override;
-    MediaTime decodeTime() const override;
-    MediaTime duration() const override;
-    MediaTime outputDuration() const override;
-
-    AtomicString trackID() const override { return m_id; }
-    void setTrackID(const String& id) override { m_id = id; }
-
-    size_t sizeInBytes() const override;
-    FloatSize presentationSize() const override;
-
-    SampleFlags flags() const override;
-    PlatformSample platformSample() override;
-    void dump(PrintStream&) const override;
-    void offsetTimestampsBy(const MediaTime&) override;
-    void setTimestamps(const MediaTime&, const MediaTime&) override;
-    bool isDivisable() const override;
-    std::pair<RefPtr<MediaSample>, RefPtr<MediaSample>> divide(const MediaTime& presentationTime) override;
-    Ref<MediaSample> createNonDisplayingCopy() const override;
-
-    VideoRotation videoRotation() const final { return m_rotation; }
-    bool videoMirrored() const final { return m_mirrored; }
-
     RetainPtr<CMSampleBufferRef> m_sample;
     AtomicString m_id;
     VideoRotation m_rotation { VideoRotation::None };

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.h (227630 => 227631)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.h	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.h	2018-01-25 22:29:55 UTC (rev 227631)
@@ -25,9 +25,10 @@
 
 #pragma once
 
-#if HAVE(AVSAMPLEBUFFERGENERATOR)
+#if HAVE(AVASSETREADER)
 
 #include "ImageDecoder.h"
+#include "SampleMap.h"
 #include <map>
 #include <wtf/Lock.h>
 #include <wtf/Vector.h>
@@ -34,8 +35,8 @@
 #include <wtf/text/WTFString.h>
 
 OBJC_CLASS AVAssetTrack;
-OBJC_CLASS AVSampleBufferGenerator;
-OBJC_CLASS AVSampleCursor;
+OBJC_CLASS AVAssetReader;
+OBJC_CLASS AVAssetReaderTrackOutput;
 OBJC_CLASS AVURLAsset;
 OBJC_CLASS WebCoreSharedBufferResourceLoaderDelegate;
 typedef struct opaqueCMSampleBuffer* CMSampleBufferRef;
@@ -49,6 +50,7 @@
 namespace WebCore {
 
 class ContentType;
+class ImageDecoderAVFObjCSample;
 class PixelBufferConformerCV;
 class WebCoreDecompressionSession;
 
@@ -101,26 +103,25 @@
     ImageDecoderAVFObjC(SharedBuffer&, const String& mimeType, AlphaOption, GammaAndColorProfileOption);
 
     AVAssetTrack *firstEnabledTrack();
-    void readSampleMetadata();
+    void readSamples();
     void readTrackMetadata();
     bool storeSampleBuffer(CMSampleBufferRef);
     void advanceCursor();
     void setTrack(AVAssetTrack *);
 
+    const ImageDecoderAVFObjCSample* sampleAtIndex(size_t) const;
+
     String m_mimeType;
     String m_uti;
     RetainPtr<AVURLAsset> m_asset;
     RetainPtr<AVAssetTrack> m_track;
-    RetainPtr<AVSampleCursor> m_cursor;
-    RetainPtr<AVSampleBufferGenerator> m_generator;
     RetainPtr<WebCoreSharedBufferResourceLoaderDelegate> m_loader;
     RetainPtr<VTImageRotationSessionRef> m_rotationSession;
     RetainPtr<CVPixelBufferPoolRef> m_rotationPool;
     Ref<WebCoreDecompressionSession> m_decompressionSession;
 
-    struct SampleData;
-    std::map<WTF::MediaTime, size_t> m_presentationTimeToIndex;
-    Vector<SampleData> m_sampleData;
+    SampleMap m_sampleData;
+    DecodeOrderSampleMap::iterator m_cursor;
     Lock m_sampleGeneratorLock;
     bool m_isAllDataReceived { false };
     std::optional<IntSize> m_size;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm (227630 => 227631)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm	2018-01-25 22:27:27 UTC (rev 227630)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm	2018-01-25 22:29:55 UTC (rev 227631)
@@ -26,7 +26,7 @@
 #import "config.h"
 #import "ImageDecoderAVFObjC.h"
 
-#if HAVE(AVSAMPLEBUFFERGENERATOR)
+#if HAVE(AVASSETREADER)
 
 #import "AVFoundationMIMETypeCache.h"
 #import "AffineTransform.h"
@@ -36,14 +36,15 @@
 #import "FloatSize.h"
 #import "Logging.h"
 #import "MIMETypeRegistry.h"
+#import "MediaSampleAVFObjC.h"
 #import "SharedBuffer.h"
 #import "UTIUtilities.h"
 #import "WebCoreDecompressionSession.h"
 #import <AVFoundation/AVAsset.h>
+#import <AVFoundation/AVAssetReader.h>
+#import <AVFoundation/AVAssetReaderOutput.h>
 #import <AVFoundation/AVAssetResourceLoader.h>
 #import <AVFoundation/AVAssetTrack.h>
-#import <AVFoundation/AVSampleBufferGenerator.h>
-#import <AVFoundation/AVSampleCursor.h>
 #import <AVFoundation/AVTime.h>
 #import <VideoToolbox/VTUtilities.h>
 #import <map>
@@ -56,6 +57,7 @@
 #import <wtf/Vector.h>
 
 #import <pal/cf/CoreMediaSoftLink.h>
+#import "CoreVideoSoftLink.h"
 #import "VideoToolboxSoftLink.h"
 
 #pragma mark - Soft Linking
@@ -62,8 +64,8 @@
 
 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVURLAsset)
-SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferGenerator)
-SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferRequest)
+SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVAssetReader)
+SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVAssetReaderTrackOutput)
 SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVMediaCharacteristicVisual, NSString *)
 SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVURLAssetReferenceRestrictionsKey, NSString *)
 SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVURLAssetUsesNoPersistentCacheKey, NSString *)
@@ -267,16 +269,52 @@
     return rotation;
 }
 
-struct ImageDecoderAVFObjC::SampleData {
-    Seconds duration { 0 };
-    bool hasAlpha { false };
-    IntSize frameSize;
-    RetainPtr<CMSampleBufferRef> sample;
-    RetainPtr<CGImageRef> image;
-    MediaTime decodeTime;
-    MediaTime presentationTime;
+class ImageDecoderAVFObjCSample : public MediaSampleAVFObjC {
+public:
+    static Ref<ImageDecoderAVFObjCSample> create(RetainPtr<CMSampleBufferRef>&& sampleBuffer)
+    {
+        return adoptRef(*new ImageDecoderAVFObjCSample(WTFMove(sampleBuffer)));
+    }
+
+    CGImageRef image() const { return m_image.get(); }
+    void setImage(RetainPtr<CGImageRef>&& image)
+    {
+        m_image = WTFMove(image);
+        if (!m_image) {
+            m_hasAlpha = false;
+            return;
+        }
+
+        auto alphaInfo = CGImageGetAlphaInfo(m_image.get());
+        m_hasAlpha = alphaInfo != kCGImageAlphaNone && alphaInfo != kCGImageAlphaNoneSkipLast && alphaInfo != kCGImageAlphaNoneSkipFirst;
+    }
+
+    SampleFlags flags() const override
+    {
+        return (SampleFlags)(MediaSampleAVFObjC::flags() | (m_hasAlpha ? HasAlpha : 0));
+    }
+
+private:
+    ImageDecoderAVFObjCSample(RetainPtr<CMSampleBufferRef>&& sample)
+        : MediaSampleAVFObjC(WTFMove(sample))
+    {
+    }
+
+    RetainPtr<CGImageRef> m_image;
+    bool m_hasAlpha { false };
 };
 
+static ImageDecoderAVFObjCSample* toSample(PresentationOrderSampleMap::value_type pair)
+{
+    return (ImageDecoderAVFObjCSample*)pair.second.get();
+}
+
+template <typename Iterator>
+ImageDecoderAVFObjCSample* toSample(Iterator iter)
+{
+    return (ImageDecoderAVFObjCSample*)iter->second.get();
+}
+
 #pragma mark - ImageDecoderAVFObjC
 
 RefPtr<ImageDecoderAVFObjC> ImageDecoderAVFObjC::create(SharedBuffer& data, const String& mimeType, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
@@ -348,37 +386,24 @@
     return [videoTracks objectAtIndex:firstEnabledIndex];
 }
 
-void ImageDecoderAVFObjC::readSampleMetadata()
+void ImageDecoderAVFObjC::readSamples()
 {
-    if (!m_sampleData.isEmpty())
+    if (!m_sampleData.empty())
         return;
 
-    // NOTE: there is no API to return the number of samples in the sample table. Instead,
-    // simply increment the sample in decode order by an arbitrarily large number.
-    RetainPtr<AVSampleCursor> cursor = [m_track makeSampleCursorAtFirstSampleInDecodeOrder];
-    int64_t sampleCount = 0;
-    if (cursor)
-        sampleCount = 1 + [cursor stepInDecodeOrderByCount:std::numeric_limits<int32_t>::max()];
+    auto assetReader = adoptNS([allocAVAssetReaderInstance() initWithAsset:m_asset.get() error:nil]);
+    auto assetReaderOutput = adoptNS([allocAVAssetReaderTrackOutputInstance() initWithTrack:m_track.get() outputSettings:nil]);
 
-    // NOTE: there is no API to return the first sample cursor in presentation order. Instead,
-    // simply decrement sample in presentation order by an arbitrarily large number.
-    [cursor stepInPresentationOrderByCount:std::numeric_limits<int32_t>::min()];
+    assetReaderOutput.get().alwaysCopiesSampleData = NO;
+    [assetReader addOutput:assetReaderOutput.get()];
+    [assetReader startReading];
 
-    ASSERT(sampleCount >= 0);
-    m_sampleData.resize(static_cast<size_t>(sampleCount));
-
-    if (!m_generator)
-        m_generator = adoptNS([allocAVSampleBufferGeneratorInstance() initWithAsset:m_asset.get() timebase:nil]);
-
-    for (size_t index = 0; index < static_cast<size_t>(sampleCount); ++index) {
-        auto& sampleData = m_sampleData[index];
-        sampleData.duration = Seconds(PAL::CMTimeGetSeconds([cursor currentSampleDuration]));
-        sampleData.decodeTime = PAL::toMediaTime([cursor decodeTimeStamp]);
-        sampleData.presentationTime = PAL::toMediaTime([cursor presentationTimeStamp]);
-        auto request = adoptNS([allocAVSampleBufferRequestInstance() initWithStartCursor:cursor.get()]);
-        sampleData.sample = adoptCF([m_generator createSampleBufferForRequest:request.get()]);
-        m_presentationTimeToIndex.insert(std::make_pair(sampleData.presentationTime, index));
-        [cursor stepInPresentationOrderByCount:1];
+    while (auto sampleBuffer = adoptCF([assetReaderOutput copyNextSampleBuffer])) {
+        // NOTE: Some samples emitted by the AVAssetReader simply denote the boundary of edits
+        // and do not carry media data.
+        if (!(PAL::CMSampleBufferGetNumSamples(sampleBuffer.get())))
+            continue;
+        m_sampleData.addSample(ImageDecoderAVFObjCSample::create(WTFMove(sampleBuffer)).get());
     }
 }
 
@@ -406,7 +431,7 @@
     }
 
     auto presentationTime = PAL::toMediaTime(PAL::CMSampleBufferGetPresentationTimeStamp(sampleBuffer));
-    auto indexIter = m_presentationTimeToIndex.find(presentationTime);
+    auto iter = m_sampleData.presentationOrder().findSampleWithPresentationTime(presentationTime);
 
     if (m_rotation && !m_rotation.value().isIdentity()) {
         auto& rotation = m_rotation.value();
@@ -447,21 +472,16 @@
         return false;
     }
 
-    ASSERT(indexIter->second < m_sampleData.size());
-    auto& sampleData = m_sampleData[indexIter->second];
-    sampleData.image = adoptCF(rawImage);
-    sampleData.sample = nullptr;
+    ASSERT(iter != m_sampleData.presentationOrder().end());
+    toSample(iter)->setImage(adoptCF(rawImage));
 
-    auto alphaInfo = CGImageGetAlphaInfo(rawImage);
-    sampleData.hasAlpha = (alphaInfo != kCGImageAlphaNone && alphaInfo != kCGImageAlphaNoneSkipLast && alphaInfo != kCGImageAlphaNoneSkipFirst);
-
     return true;
 }
 
 void ImageDecoderAVFObjC::advanceCursor()
 {
-    if (![m_cursor stepInDecodeOrderByCount:1])
-        m_cursor = [m_track makeSampleCursorAtFirstSampleInDecodeOrder];
+    if (m_cursor == m_sampleData.decodeOrder().end() || ++m_cursor == m_sampleData.decodeOrder().end())
+        m_cursor = m_sampleData.decodeOrder().begin();
 }
 
 void ImageDecoderAVFObjC::setTrack(AVAssetTrack *track)
@@ -474,14 +494,13 @@
     m_sampleData.clear();
     m_size.reset();
     m_rotation.reset();
-    m_cursor = nullptr;
-    m_generator = nullptr;
+    m_cursor = m_sampleData.decodeOrder().end();
     m_rotationSession = nullptr;
 
     [track loadValuesAsynchronouslyForKeys:@[@"naturalSize", @"preferredTransform"] completionHandler:[protectedThis = makeRefPtr(this)] () mutable {
         callOnMainThread([protectedThis = WTFMove(protectedThis)] {
             protectedThis->readTrackMetadata();
-            protectedThis->readSampleMetadata();
+            protectedThis->readSamples();
         });
     }];
 }
@@ -488,7 +507,7 @@
 
 EncodedDataStatus ImageDecoderAVFObjC::encodedDataStatus() const
 {
-    if (m_sampleData.isEmpty())
+    if (m_sampleData.empty())
         return EncodedDataStatus::Unknown;
     return EncodedDataStatus::Complete;
 }
@@ -510,7 +529,7 @@
     // In the absence of instructions to the contrary, assume all media formats repeat infinitely.
     // FIXME: Future media formats may embed repeat count information, and when that is available
     // through AVAsset, account for it here.
-    return RepetitionCountInfinite;
+    return frameCount() > 1 ? RepetitionCountInfinite : RepetitionCountNone;
 }
 
 String ImageDecoderAVFObjC::uti() const
@@ -530,14 +549,11 @@
 
 bool ImageDecoderAVFObjC::frameIsCompleteAtIndex(size_t index) const
 {
-    if (index >= m_sampleData.size())
+    auto* sampleData = sampleAtIndex(index);
+    if (!sampleData)
         return false;
 
-    auto sampleData = m_sampleData[index];
-    if (!sampleData.sample)
-        return false;
-
-    return PAL::CMSampleBufferDataIsReady(sampleData.sample.get());
+    return PAL::CMSampleBufferDataIsReady(sampleData->sampleBuffer());
 }
 
 ImageOrientation ImageDecoderAVFObjC::frameOrientationAtIndex(size_t) const
@@ -547,16 +563,17 @@
 
 Seconds ImageDecoderAVFObjC::frameDurationAtIndex(size_t index) const
 {
-    if (index < m_sampleData.size())
-        return m_sampleData[index].duration;
-    return { };
+    auto* sampleData = sampleAtIndex(index);
+    if (!sampleData)
+        return { };
+
+    return Seconds(sampleData->duration().toDouble());
 }
 
 bool ImageDecoderAVFObjC::frameHasAlphaAtIndex(size_t index) const
 {
-    if (index < m_sampleData.size())
-        return m_sampleData[index].hasAlpha;
-    return false;
+    auto* sampleData = sampleAtIndex(index);
+    return sampleData ? sampleData->hasAlpha() : false;
 }
 
 bool ImageDecoderAVFObjC::frameAllowSubsamplingAtIndex(size_t index) const
@@ -577,57 +594,42 @@
 {
     LockHolder holder { m_sampleGeneratorLock };
 
-    if (index >= m_sampleData.size())
+    auto* sampleData = sampleAtIndex(index);
+    if (!sampleData)
         return nullptr;
 
-    auto& sampleData = m_sampleData[index];
-    if (sampleData.image)
-        return sampleData.image;
+    if (auto image = sampleData->image())
+        return image;
 
-    if (!m_cursor)
-        m_cursor = [m_track makeSampleCursorAtFirstSampleInDecodeOrder];
+    if (m_cursor == m_sampleData.decodeOrder().end())
+        m_cursor = m_sampleData.decodeOrder().begin();
 
-    auto frameCursor = [m_track makeSampleCursorWithPresentationTimeStamp:PAL::toCMTime(sampleData.presentationTime)];
-    if ([frameCursor comparePositionInDecodeOrderWithPositionOfCursor:m_cursor.get()] == NSOrderedAscending)  {
+    auto decodeTime = sampleData->decodeTime();
+
+    if (decodeTime < m_cursor->second->decodeTime()) {
         // Rewind cursor to the last sync sample to begin decoding
-        m_cursor = adoptNS([frameCursor copy]);
+        m_cursor = m_sampleData.decodeOrder().findSampleWithDecodeKey({decodeTime, sampleData->presentationTime()});
         do {
-            if ([m_cursor currentSampleSyncInfo].sampleIsFullSync)
+            if (m_cursor->second->isSync())
                 break;
-        } while ([m_cursor stepInDecodeOrderByCount:-1] == -1);
-
+        } while (--m_cursor != m_sampleData.decodeOrder().begin());
     }
 
-    if (!m_generator)
-        m_generator = adoptNS([allocAVSampleBufferGeneratorInstance() initWithAsset:m_asset.get() timebase:nil]);
-
     RetainPtr<CGImageRef> image;
     while (true) {
-        if ([frameCursor comparePositionInDecodeOrderWithPositionOfCursor:m_cursor.get()] == NSOrderedAscending)
+        if (decodeTime < m_cursor->second->decodeTime())
             return nullptr;
 
-        auto presentationTime = PAL::toMediaTime(m_cursor.get().presentationTimeStamp);
-        auto indexIter = m_presentationTimeToIndex.find(presentationTime);
-
-        if (indexIter == m_presentationTimeToIndex.end())
+        auto cursorSample = toSample(m_cursor)->sampleBuffer();
+        if (!cursorSample)
             break;
 
-        auto& cursorSampleData = m_sampleData[indexIter->second];
-
-        if (!cursorSampleData.sample) {
-            auto request = adoptNS([allocAVSampleBufferRequestInstance() initWithStartCursor:m_cursor.get()]);
-            cursorSampleData.sample = adoptCF([m_generator createSampleBufferForRequest:request.get()]);
-        }
-
-        if (!cursorSampleData.sample)
+        if (!storeSampleBuffer(cursorSample))
             break;
 
-        if (!storeSampleBuffer(cursorSampleData.sample.get()))
-            break;
-
         advanceCursor();
-        if (sampleData.image)
-            return sampleData.image;
+        if (auto image = sampleData->image())
+            return image;
     }
 
     advanceCursor();
@@ -649,17 +651,39 @@
         if (!m_track)
             setTrack(firstEnabledTrack());
 
+        if (!m_track)
+            return;
+
         readTrackMetadata();
-        readSampleMetadata();
+        readSamples();
     }
 }
 
 void ImageDecoderAVFObjC::clearFrameBufferCache(size_t index)
 {
-    for (size_t i = 0; i < index; ++i)
-        m_sampleData[i].image = nullptr;
+    size_t i = 0;
+    for (auto& samplePair : m_sampleData.presentationOrder()) {
+        toSample(samplePair)->setImage(nullptr);
+        if (++i > index)
+            break;
+    }
 }
 
+const ImageDecoderAVFObjCSample* ImageDecoderAVFObjC::sampleAtIndex(size_t index) const
+{
+    if (index >= m_sampleData.size())
+        return nullptr;
+
+    // FIXME: std::map is not random-accessible; this can get expensive if callers repeatedly call
+    // with monotonically increasing indexes. Investigate adding an O(1) side structure to make this
+    // style of access faster.
+    auto iter = m_sampleData.presentationOrder().begin();
+    for (size_t i = 0; i != index; ++i)
+        ++iter;
+    
+    return toSample(iter);
 }
 
+}
+
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to