Bug 131902

Summary: [Mac] don't ask for AVAssetTrack properties before they are available
Product: WebKit Reporter: Eric Carlson <eric.carlson>
Component: MediaAssignee: Eric Carlson <eric.carlson>
Status: REOPENED    
Severity: Normal CC: commit-queue, glenn, jer.noble, philipj, sergio, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 131993    
Bug Blocks:    
Attachments:
Description Flags
Proposed patch
none
Updated patch
bfulgham: review+
Patch for landing. none

Eric Carlson
Reported 2014-04-19 17:12:32 PDT
Like other AVFoundation object properties, asking for AVAssetTrack properties before they have are available will block until the data is available. AVAssetTrack implements statusOfValueForKey:error, so we should use that to ask it to load the properties we know we use, and not ask for them until they are available.
Attachments
Proposed patch (5.48 KB, patch)
2014-04-21 10:32 PDT, Eric Carlson
no flags
Updated patch (5.86 KB, patch)
2014-04-23 16:18 PDT, Eric Carlson
bfulgham: review+
Patch for landing. (5.83 KB, patch)
2014-04-24 14:10 PDT, Eric Carlson
no flags
Eric Carlson
Comment 1 2014-04-19 17:12:56 PDT
Eric Carlson
Comment 2 2014-04-21 10:32:05 PDT
Created attachment 229804 [details] Proposed patch
Jer Noble
Comment 3 2014-04-21 13:42:05 PDT
Comment on attachment 229804 [details] Proposed patch nice! r=me.
WebKit Commit Bot
Comment 4 2014-04-22 07:07:08 PDT
Comment on attachment 229804 [details] Proposed patch Clearing flags on attachment: 229804 Committed r167658: <http://trac.webkit.org/changeset/167658>
WebKit Commit Bot
Comment 5 2014-04-22 07:07:12 PDT
All reviewed patches have been landed. Closing bug.
Alexey Proskuryakov
Comment 6 2014-04-22 09:49:57 PDT
This caused many crashes on tests: 0 libobjc.A.dylib 0x00007fff93636250 objc_msgSend + 16 1 com.apple.WebCore 0x000000010e3d1344 ___ZN7WebCore34MediaPlayerPrivateAVFoundationObjC20beginLoadingMetadataEv_block_invoke97 + 52 (MediaPlayerPrivateAVFoundationObjC.mm:803) 2 libdispatch.dylib 0x00007fff9715cf01 _dispatch_call_block_and_release + 15 3 libdispatch.dylib 0x00007fff971590b6 _dispatch_client_callout + 8 4 libdispatch.dylib 0x00007fff9715e0c8 _dispatch_main_queue_callback_4CF + 275 5 com.apple.CoreFoundation 0x00007fff902b6b4c __CFRunLoopRun + 1644 6 com.apple.CoreFoundation 0x00007fff902b60e2 CFRunLoopRunSpecific + 290 7 DumpRenderTree 0x000000010aa9c335 runTest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 4853 (DumpRenderTree.mm:1822)
WebKit Commit Bot
Comment 7 2014-04-22 09:52:30 PDT
Re-opened since this is blocked by bug 131993
Eric Carlson
Comment 8 2014-04-23 16:18:42 PDT
Created attachment 230017 [details] Updated patch
Brent Fulgham
Comment 9 2014-04-24 09:10:41 PDT
Comment on attachment 230017 [details] Updated patch r=me
Darin Adler
Comment 10 2014-04-24 09:13:51 PDT
Comment on attachment 230017 [details] Updated patch View in context: https://bugs.webkit.org/attachment.cgi?id=230017&action=review > Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:809 > + dispatch_group_notify(metadataLoadingGroup, dispatch_get_main_queue(), ^{ > + callOnMainThread([weakThis, metadataLoadingGroup] { I’m a little puzzled about the combination of main queue and main thread here. Won’t something dispatched on the main queue already be on the main thread? > Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:813 > + dispatch_release(metadataLoadingGroup); What guarantees that this runs after the completion handler? It looks like we could release metadataLoadingGroup before we are done with it. Maybe that’s impossible because of the enter/leave calls above? > Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:1167 > + return m_cachedTotalBytes; Can this value ever total 0? If so, then we’ll keep recomputing it over and over again. Maybe the validity should be tracked separately rather than using "0" as a magic value? Or maybe the magic value could be -1? > Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:2465 > +NSArray* assetTrackMetadataKeyNames() > +{ > + static NSArray* keys; > + if (!keys) > + keys = [[NSArray alloc] initWithObjects:@"totalSampleDataLength", @"mediaType", nil]; > + > + return keys; > +} No need for the if statement. Depending on the minimum compiler version guaranteed this could be either: NSArray *assetTrackMetadataKeyNames() { static NSArray* keys = [[NSArray alloc] initWithObjects:@"totalSampleDataLength", @"mediaType", nil]; return keys; } or: NSArray *assetTrackMetadataKeyNames() { return @[@"totalSampleDataLength", @"mediaType"]; }
Jer Noble
Comment 11 2014-04-24 10:24:00 PDT
(In reply to comment #10) > (From update of attachment 230017 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=230017&action=review > > > Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:809 > > + dispatch_group_notify(metadataLoadingGroup, dispatch_get_main_queue(), ^{ > > + callOnMainThread([weakThis, metadataLoadingGroup] { > > I’m a little puzzled about the combination of main queue and main thread here. Won’t something dispatched on the main queue already be on the main thread? (Since this was my idea, I'll answer Darin's question.) On iOS, the main queue isn't on the web thread, and the (misnamed) callOnMainThread() will actually dispatch to the web thread, not the main thread. This became a problem because WeakPtr::get() will assert if called from a different thread than its creation thread. > > Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:813 > > + dispatch_release(metadataLoadingGroup); > > What guarantees that this runs after the completion handler? It looks like we could release metadataLoadingGroup before we are done with it. Maybe that’s impossible because of the enter/leave calls above? This is a good point. This notify handler will get called after the dispatch_group_leave() on line 805, not after all the dispatch_group_leave()s on line 799. The one on line 805 should be moved inside the callOnMainThread() block.
Eric Carlson
Comment 12 2014-04-24 14:07:18 PDT
(In reply to comment #10) > (From update of attachment 230017 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=230017&action=review > > > Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:1167 > > + return m_cachedTotalBytes; > > Can this value ever total 0? If so, then we’ll keep recomputing it over and over again. Maybe the validity should be tracked separately rather than using "0" as a magic value? Or maybe the magic value could be -1? > The total size should never be 0 once metaDataAvailable() returns true. > > Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:2465 > > +NSArray* assetTrackMetadataKeyNames() > > +{ > > + static NSArray* keys; > > + if (!keys) > > + keys = [[NSArray alloc] initWithObjects:@"totalSampleDataLength", @"mediaType", nil]; > > + > > + return keys; > > +} > > No need for the if statement. Depending on the minimum compiler version guaranteed this could be either: > Fixed.
Eric Carlson
Comment 13 2014-04-24 14:10:26 PDT
Created attachment 230104 [details] Patch for landing.
WebKit Commit Bot
Comment 14 2014-04-24 14:46:52 PDT
Comment on attachment 230104 [details] Patch for landing. Clearing flags on attachment: 230104 Committed r167776: <http://trac.webkit.org/changeset/167776>
Note You need to log in before you can comment on or make changes to this bug.