Changeset 255347 in webkit
- Timestamp:
- Jan 29, 2020 2:35:27 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r255345 r255347 1 2020-01-29 youenn fablet <youenn@apple.com> 2 3 Blob media loading does not work with GPUProcess 4 https://bugs.webkit.org/show_bug.cgi?id=206824 5 <rdar://problem/58917596> 6 7 Reviewed by Eric Carlson. 8 9 * gpu-process/TestExpectations: 10 1 11 2020-01-29 youenn fablet <youenn@apple.com> 2 12 -
trunk/LayoutTests/gpu-process/TestExpectations
r255253 r255347 183 183 media/media-preload-no-delay-loadevent.html [ Pass ] 184 184 media/video-src.html [ Pass ] 185 media/video-src-blob-using-open-panel.html [ Pass ] 185 186 media/video-source.html [ Pass ] 186 187 media/audio-as-video-fullscreen.html [ Pass ] -
trunk/Source/WebCore/ChangeLog
r255345 r255347 1 2020-01-29 youenn fablet <youenn@apple.com> 2 3 Blob media loading does not work with GPUProcess 4 https://bugs.webkit.org/show_bug.cgi?id=206824 5 <rdar://problem/58917596> 6 7 Reviewed by Eric Carlson. 8 9 GPU process is using WebCoreAVFResourceLoader for various loads, including blob loads. 10 In GPU process, loads will fail since this loader expects a CachedResource, which only WebProcess can have. 11 For that reason, move the CachedResource loader part of WebCoreAVFResourceLoader to a dedicated class CachedResourceMediaLoader. 12 If load cannot happen with a CachedResource, use a new class PlatformResourceMediaLoader, which uses a loader from MediaPlayer::createResourceLoader. 13 This allows using the loading path in GPUProcess used for HTTP loads, which works for blob loads as well. 14 15 Covered by existing and enabled tests. 16 17 * platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.h: 18 * platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm: 19 (WebCore::CachedResourceMediaLoader::~CachedResourceMediaLoader): 20 (WebCore::CachedResourceMediaLoader::create): 21 (WebCore::CachedResourceMediaLoader::CachedResourceMediaLoader): 22 (WebCore::CachedResourceMediaLoader::stop): 23 (WebCore::CachedResourceMediaLoader::responseReceived): 24 (WebCore::CachedResourceMediaLoader::notifyFinished): 25 (WebCore::CachedResourceMediaLoader::dataReceived): 26 (WebCore::PlatformResourceMediaLoader::~PlatformResourceMediaLoader): 27 (WebCore::PlatformResourceMediaLoader::create): 28 (WebCore::PlatformResourceMediaLoader::PlatformResourceMediaLoader): 29 (WebCore::PlatformResourceMediaLoader::stop): 30 (WebCore::PlatformResourceMediaLoader::responseReceived): 31 (WebCore::PlatformResourceMediaLoader::loadFailed): 32 (WebCore::PlatformResourceMediaLoader::loadFinished): 33 (WebCore::PlatformResourceMediaLoader::dataReceived): 34 (WebCore::WebCoreAVFResourceLoader::startLoading): 35 (WebCore::WebCoreAVFResourceLoader::stopLoading): 36 (WebCore::WebCoreAVFResourceLoader::responseReceived): 37 (WebCore::WebCoreAVFResourceLoader::loadFailed): 38 (WebCore::WebCoreAVFResourceLoader::loadFinished): 39 (WebCore::WebCoreAVFResourceLoader::newDataStoredInSharedBuffer): 40 1 41 2020-01-29 youenn fablet <youenn@apple.com> 2 42 -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.h
r255253 r255347 28 28 #if ENABLE(VIDEO) && USE(AVFOUNDATION) && HAVE(AVFOUNDATION_LOADER_DELEGATE) 29 29 30 #include "CachedRawResourceClient.h"31 #include "CachedResourceHandle.h"32 30 #include <wtf/Noncopyable.h> 33 31 #include <wtf/Ref.h> 34 32 #include <wtf/RefCounted.h> 35 33 #include <wtf/RetainPtr.h> 34 #include <wtf/WeakPtr.h> 36 35 37 36 OBJC_CLASS AVAssetResourceLoadingRequest; … … 39 38 namespace WebCore { 40 39 41 class CachedRawResource; 42 class CachedResourceLoader; 40 class CachedResourceMediaLoader; 43 41 class MediaPlayerPrivateAVFoundationObjC; 42 class PlatformResourceMediaLoader; 43 class ResourceError; 44 class ResourceResponse; 45 class SharedBuffer; 44 46 45 class WebCoreAVFResourceLoader : public RefCounted<WebCoreAVFResourceLoader> , CachedRawResourceClient{47 class WebCoreAVFResourceLoader : public RefCounted<WebCoreAVFResourceLoader> { 46 48 WTF_MAKE_NONCOPYABLE(WebCoreAVFResourceLoader); WTF_MAKE_FAST_ALLOCATED; 47 49 public: … … 53 55 void invalidate(); 54 56 55 CachedRawResource* resource(); 57 private: 58 WebCoreAVFResourceLoader(MediaPlayerPrivateAVFoundationObjC* parent, AVAssetResourceLoadingRequest *); 56 59 57 private: 58 // CachedResourceClient 59 void responseReceived(CachedResource&, const ResourceResponse&, CompletionHandler<void()>&&) override; 60 void dataReceived(CachedResource&, const char*, int) override; 61 void notifyFinished(CachedResource&) override; 60 friend class CachedResourceMediaLoader; 61 friend class PlatformResourceMediaLoader; 62 62 63 void fulfillRequestWithResource(CachedResource&); 63 void responseReceived(const ResourceResponse&); 64 void loadFailed(const ResourceError&); 65 void loadFinished(); 66 void newDataStoredInSharedBuffer(SharedBuffer&); 64 67 65 WebCoreAVFResourceLoader(MediaPlayerPrivateAVFoundationObjC* parent, AVAssetResourceLoadingRequest *);66 68 MediaPlayerPrivateAVFoundationObjC* m_parent; 67 69 RetainPtr<AVAssetResourceLoadingRequest> m_avRequest; 68 CachedResourceHandle<CachedRawResource> m_resource; 70 std::unique_ptr<CachedResourceMediaLoader> m_resourceMediaLoader; 71 WeakPtr<PlatformResourceMediaLoader> m_platformMediaLoader; 72 size_t m_responseOffset { 0 }; 69 73 }; 70 74 -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm
r255253 r255347 43 43 namespace WebCore { 44 44 45 Ref<WebCoreAVFResourceLoader> WebCoreAVFResourceLoader::create(MediaPlayerPrivateAVFoundationObjC* parent, AVAssetResourceLoadingRequest *avRequest) 46 { 47 ASSERT(avRequest); 48 ASSERT(parent); 49 return adoptRef(*new WebCoreAVFResourceLoader(parent, avRequest)); 50 } 51 52 WebCoreAVFResourceLoader::WebCoreAVFResourceLoader(MediaPlayerPrivateAVFoundationObjC* parent, AVAssetResourceLoadingRequest *avRequest) 53 : m_parent(parent) 54 , m_avRequest(avRequest) 55 { 56 } 57 58 WebCoreAVFResourceLoader::~WebCoreAVFResourceLoader() 59 { 60 stopLoading(); 61 } 62 63 void WebCoreAVFResourceLoader::startLoading() 64 { 65 if (m_resource || !m_parent) 66 return; 67 68 NSURLRequest *nsRequest = [m_avRequest.get() request]; 69 70 ResourceRequest resourceRequest(nsRequest); 71 resourceRequest.setPriority(ResourceLoadPriority::Low); 72 45 class CachedResourceMediaLoader final : CachedRawResourceClient { 46 WTF_MAKE_FAST_ALLOCATED; 47 public: 48 static std::unique_ptr<CachedResourceMediaLoader> create(WebCoreAVFResourceLoader&, CachedResourceLoader&, ResourceRequest&&); 49 ~CachedResourceMediaLoader() { stop(); } 50 51 private: 52 CachedResourceMediaLoader(WebCoreAVFResourceLoader&, CachedResourceHandle<CachedRawResource>&&); 53 54 void stop(); 55 56 // CachedRawResourceClient 57 void responseReceived(CachedResource&, const ResourceResponse&, CompletionHandler<void()>&&) final; 58 void dataReceived(CachedResource&, const char*, int) final; 59 void notifyFinished(CachedResource&) final; 60 61 void fulfillRequestWithResource(CachedResource&); 62 63 WebCoreAVFResourceLoader& m_parent; 64 CachedResourceHandle<CachedRawResource> m_resource; 65 }; 66 67 std::unique_ptr<CachedResourceMediaLoader> CachedResourceMediaLoader::create(WebCoreAVFResourceLoader& parent, CachedResourceLoader& loader, ResourceRequest&& resourceRequest) 68 { 73 69 // FIXME: Skip Content Security Policy check if the element that inititated this request 74 70 // is in a user-agent shadow tree. See <https://bugs.webkit.org/show_bug.cgi?id=173498>. … … 86 82 DefersLoadingPolicy::AllowDefersLoading, 87 83 CachingPolicy::DisallowCaching)); 88 if (auto* loader = m_parent->player()->cachedResourceLoader()) 89 m_resource = loader->requestMedia(WTFMove(request)).value_or(nullptr); 90 91 if (m_resource) 92 m_resource->addClient(*this); 93 else { 94 LOG_ERROR("Failed to start load for media at url %s", [[[nsRequest URL] absoluteString] UTF8String]); 95 [m_avRequest.get() finishLoadingWithError:0]; 96 } 84 85 auto resource = loader.requestMedia(WTFMove(request)).value_or(nullptr); 86 if (!resource) 87 return nullptr; 88 return std::unique_ptr<CachedResourceMediaLoader>(new CachedResourceMediaLoader { parent, WTFMove(resource) }); 89 } 90 91 CachedResourceMediaLoader::CachedResourceMediaLoader(WebCoreAVFResourceLoader& parent, CachedResourceHandle<CachedRawResource>&& resource) 92 : m_parent(parent) 93 , m_resource(WTFMove(resource)) 94 { 95 m_resource->addClient(*this); 96 } 97 98 void CachedResourceMediaLoader::stop() 99 { 100 if (!m_resource) 101 return; 102 103 m_resource->removeClient(*this); 104 m_resource = nullptr; 105 } 106 107 void CachedResourceMediaLoader::responseReceived(CachedResource& resource, const ResourceResponse& response, CompletionHandler<void()>&& completionHandler) 108 { 109 ASSERT_UNUSED(resource, &resource == m_resource); 110 CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler)); 111 112 m_parent.responseReceived(response); 113 } 114 115 void CachedResourceMediaLoader::notifyFinished(CachedResource& resource) 116 { 117 if (resource.loadFailedOrCanceled()) { 118 m_parent.loadFailed(resource.resourceError()); 119 return; 120 } 121 m_parent.loadFinished(); 122 } 123 124 void CachedResourceMediaLoader::dataReceived(CachedResource& resource, const char*, int) 125 { 126 ASSERT(&resource == m_resource); 127 if (auto* data = resource.resourceBuffer()) 128 m_parent.newDataStoredInSharedBuffer(*data); 129 } 130 131 class PlatformResourceMediaLoader final : public PlatformMediaResourceClient, public CanMakeWeakPtr<PlatformResourceMediaLoader> { 132 WTF_MAKE_FAST_ALLOCATED; 133 public: 134 static WeakPtr<PlatformResourceMediaLoader> create(WebCoreAVFResourceLoader&, PlatformMediaResourceLoader&, ResourceRequest&&); 135 ~PlatformResourceMediaLoader() { stop(); } 136 137 void stop(); 138 139 private: 140 PlatformResourceMediaLoader(WebCoreAVFResourceLoader&, Ref<PlatformMediaResource>&&); 141 142 void loadFailed(const ResourceError&); 143 void loadFinished(); 144 145 // PlatformMediaResourceClient 146 void responseReceived(PlatformMediaResource&, const ResourceResponse&, CompletionHandler<void(PolicyChecker::ShouldContinue)>&&) final; 147 void redirectReceived(PlatformMediaResource&, ResourceRequest&& request, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&& completionHandler) final { completionHandler(WTFMove(request)); } 148 bool shouldCacheResponse(PlatformMediaResource&, const ResourceResponse&) final { return false; } 149 void dataSent(PlatformMediaResource&, unsigned long long, unsigned long long) final { } 150 void dataReceived(PlatformMediaResource&, const char*, int) final; 151 void accessControlCheckFailed(PlatformMediaResource&, const ResourceError& error) final { loadFailed(error); } 152 void loadFailed(PlatformMediaResource&, const ResourceError& error) final { loadFailed(error); } 153 void loadFinished(PlatformMediaResource&) final { loadFinished(); } 154 155 WebCoreAVFResourceLoader& m_parent; 156 RefPtr<PlatformMediaResource> m_resource; 157 RefPtr<SharedBuffer> m_buffer; 158 }; 159 160 WeakPtr<PlatformResourceMediaLoader> PlatformResourceMediaLoader::create(WebCoreAVFResourceLoader& parent, PlatformMediaResourceLoader& loader, ResourceRequest&& request) 161 { 162 auto resource = loader.requestResource(WTFMove(request), PlatformMediaResourceLoader::LoadOption::DisallowCaching); 163 if (!resource) 164 return nullptr; 165 auto* resourcePointer = resource.get(); 166 auto client = std::unique_ptr<PlatformResourceMediaLoader>(new PlatformResourceMediaLoader { parent, resource.releaseNonNull() }); 167 auto result = makeWeakPtr(client.get()); 168 169 resourcePointer->setClient(WTFMove(client)); 170 return result; 171 } 172 173 PlatformResourceMediaLoader::PlatformResourceMediaLoader(WebCoreAVFResourceLoader& parent, Ref<PlatformMediaResource>&& resource) 174 : m_parent(parent) 175 , m_resource(WTFMove(resource)) 176 { 177 } 178 179 void PlatformResourceMediaLoader::stop() 180 { 181 if (!m_resource) 182 return; 183 184 auto resource = WTFMove(m_resource); 185 resource->stop(); 186 resource->setClient(nullptr); 187 } 188 189 void PlatformResourceMediaLoader::responseReceived(PlatformMediaResource&, const ResourceResponse& response, CompletionHandler<void(PolicyChecker::ShouldContinue)>&& completionHandler) 190 { 191 m_parent.responseReceived(response); 192 completionHandler(PolicyChecker::ShouldContinue::Yes); 193 } 194 195 void PlatformResourceMediaLoader::loadFailed(const ResourceError& error) 196 { 197 m_parent.loadFailed(error); 198 } 199 200 void PlatformResourceMediaLoader::loadFinished() 201 { 202 m_parent.loadFinished(); 203 } 204 205 void PlatformResourceMediaLoader::dataReceived(PlatformMediaResource&, const char* data, int size) 206 { 207 if (!m_buffer) 208 m_buffer = SharedBuffer::create(data, size); 209 else 210 m_buffer->append(data, size); 211 m_parent.newDataStoredInSharedBuffer(*m_buffer); 212 } 213 214 Ref<WebCoreAVFResourceLoader> WebCoreAVFResourceLoader::create(MediaPlayerPrivateAVFoundationObjC* parent, AVAssetResourceLoadingRequest *avRequest) 215 { 216 ASSERT(avRequest); 217 ASSERT(parent); 218 return adoptRef(*new WebCoreAVFResourceLoader(parent, avRequest)); 219 } 220 221 WebCoreAVFResourceLoader::WebCoreAVFResourceLoader(MediaPlayerPrivateAVFoundationObjC* parent, AVAssetResourceLoadingRequest *avRequest) 222 : m_parent(parent) 223 , m_avRequest(avRequest) 224 { 225 } 226 227 WebCoreAVFResourceLoader::~WebCoreAVFResourceLoader() 228 { 229 stopLoading(); 230 } 231 232 void WebCoreAVFResourceLoader::startLoading() 233 { 234 if (m_resourceMediaLoader || m_platformMediaLoader || !m_parent) 235 return; 236 237 NSURLRequest *nsRequest = [m_avRequest.get() request]; 238 239 ResourceRequest request(nsRequest); 240 request.setPriority(ResourceLoadPriority::Low); 241 242 if (auto* loader = m_parent->player()->cachedResourceLoader()) { 243 m_resourceMediaLoader = CachedResourceMediaLoader::create(*this, *loader, WTFMove(request)); 244 if (m_resourceMediaLoader) 245 return; 246 } 247 248 if (auto loader = m_parent->player()->createResourceLoader()) { 249 m_platformMediaLoader = PlatformResourceMediaLoader::create(*this, *loader, WTFMove(request)); 250 if (m_platformMediaLoader) 251 return; 252 } 253 254 LOG_ERROR("Failed to start load for media at url %s", [[[nsRequest URL] absoluteString] UTF8String]); 255 [m_avRequest.get() finishLoadingWithError:0]; 97 256 } 98 257 99 258 void WebCoreAVFResourceLoader::stopLoading() 100 259 { 101 if (!m_resource)102 return; 103 104 m_resource->removeClient(*this);105 m_resource = 0;106 260 m_resourceMediaLoader = nullptr; 261 262 if (m_platformMediaLoader) { 263 m_platformMediaLoader->stop(); 264 m_platformMediaLoader = nullptr; 265 } 107 266 if (m_parent && m_avRequest) 108 267 m_parent->didStopLoadingRequest(m_avRequest.get()); … … 121 280 } 122 281 123 void WebCoreAVFResourceLoader::responseReceived(CachedResource& resource, const ResourceResponse& response, CompletionHandler<void()>&& completionHandler) 124 { 125 ASSERT_UNUSED(resource, &resource == m_resource); 126 CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler)); 127 282 void WebCoreAVFResourceLoader::responseReceived(const ResourceResponse& response) 283 { 128 284 int status = response.httpStatusCode(); 129 285 if (status && (status < 200 || status > 299)) { … … 132 288 } 133 289 290 auto& contentRange = response.contentRange(); 291 if (contentRange.isValid()) 292 m_responseOffset = static_cast<NSUInteger>(contentRange.firstBytePosition()); 293 134 294 if (AVAssetResourceLoadingContentInformationRequest* contentInfo = [m_avRequest.get() contentInformationRequest]) { 135 295 String uti = UTIFromMIMEType(response.mimeType()); … … 137 297 [contentInfo setContentType:uti]; 138 298 139 const ParsedContentRange& contentRange = m_resource->response().contentRange();140 299 [contentInfo setContentLength:contentRange.isValid() ? contentRange.instanceLength() : response.expectedContentLength()]; 141 300 [contentInfo setByteRangeAccessSupported:YES]; … … 148 307 } 149 308 150 void WebCoreAVFResourceLoader::dataReceived(CachedResource& resource, const char*, int) 151 { 152 fulfillRequestWithResource(resource); 153 } 154 155 void WebCoreAVFResourceLoader::notifyFinished(CachedResource& resource) 156 { 157 if (resource.loadFailedOrCanceled()) { 158 // <rdar://problem/13987417> Set the contentType of the contentInformationRequest to an empty 159 // string to trigger AVAsset's playable value to complete loading. 160 if ([m_avRequest.get() contentInformationRequest] && ![[m_avRequest.get() contentInformationRequest] contentType]) 161 [[m_avRequest.get() contentInformationRequest] setContentType:@""]; 162 163 NSError* error = resource.errorOccurred() ? resource.resourceError().nsError() : nil; 164 [m_avRequest.get() finishLoadingWithError:error]; 165 } else { 166 fulfillRequestWithResource(resource); 167 [m_avRequest.get() finishLoading]; 168 } 309 void WebCoreAVFResourceLoader::loadFailed(const ResourceError& error) 310 { 311 // <rdar://problem/13987417> Set the contentType of the contentInformationRequest to an empty 312 // string to trigger AVAsset's playable value to complete loading. 313 if ([m_avRequest.get() contentInformationRequest] && ![[m_avRequest.get() contentInformationRequest] contentType]) 314 [[m_avRequest.get() contentInformationRequest] setContentType:@""]; 315 316 [m_avRequest.get() finishLoadingWithError:error.nsError()]; 169 317 stopLoading(); 170 318 } 171 319 172 void WebCoreAVFResourceLoader::fulfillRequestWithResource(CachedResource& resource) 173 { 174 ASSERT_UNUSED(resource, &resource == m_resource); 320 void WebCoreAVFResourceLoader::loadFinished() 321 { 322 [m_avRequest.get() finishLoading]; 323 stopLoading(); 324 } 325 326 void WebCoreAVFResourceLoader::newDataStoredInSharedBuffer(SharedBuffer& data) 327 { 175 328 AVAssetResourceLoadingDataRequest* dataRequest = [m_avRequest dataRequest]; 176 329 if (!dataRequest) 177 330 return; 178 179 SharedBuffer* data = m_resource->resourceBuffer();180 if (!data)181 return;182 183 NSUInteger responseOffset = 0;184 const ParsedContentRange& contentRange = m_resource->response().contentRange();185 if (contentRange.isValid())186 responseOffset = static_cast<NSUInteger>(contentRange.firstBytePosition());187 331 188 332 // Check for possible unsigned overflow. … … 192 336 NSUInteger remainingLength = dataRequest.requestedLength - static_cast<NSUInteger>(dataRequest.currentOffset - dataRequest.requestedOffset); 193 337 194 auto bytesToSkip = dataRequest.currentOffset - responseOffset;195 RetainPtr<NSArray> array = data->createNSDataArray();338 auto bytesToSkip = dataRequest.currentOffset - m_responseOffset; 339 auto array = data.createNSDataArray(); 196 340 for (NSData *segment in array.get()) { 197 341 if (bytesToSkip) {
Note: See TracChangeset
for help on using the changeset viewer.