Changeset 274154 in webkit
- Timestamp:
- Mar 9, 2021 9:38:47 AM (17 months ago)
- Location:
- trunk
- Files:
-
- 6 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/wpt/mediarecorder/pause-recording-expected.txt (modified) (1 diff)
-
LayoutTests/http/wpt/mediarecorder/pause-recording.html (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h (modified) (3 diffs)
-
Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r274150 r274154 1 2021-03-09 Youenn Fablet <youenn@apple.com> 2 3 MediaRecorder.requestData() not returning all captured media after a pause 4 https://bugs.webkit.org/show_bug.cgi?id=222285 5 <rdar://problem/74884561> 6 7 Reviewed by Eric Carlson. 8 9 * http/wpt/mediarecorder/pause-recording-expected.txt: 10 * http/wpt/mediarecorder/pause-recording.html: 11 1 12 2021-03-09 Philippe Normand <pnormand@igalia.com> 2 13 -
trunk/LayoutTests/http/wpt/mediarecorder/pause-recording-expected.txt
r268130 r274154 2 2 3 3 PASS Pausing and resuming the recording should impact the video duration 4 PASS Calling requestData once after pausing should lead to more than header data 4 5 -
trunk/LayoutTests/http/wpt/mediarecorder/pause-recording.html
r272722 r274154 41 41 }, "Pausing and resuming the recording should impact the video duration"); 42 42 43 promise_test(async (test) => { 44 const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true }); 45 46 const recorder = new MediaRecorder(stream); 47 const dataPromise = new Promise(resolve => recorder.ondataavailable = (e) => resolve(e.data)); 48 49 const startPromise = new Promise(resolve => recorder.onstart = resolve); 50 recorder.start(); 51 await startPromise; 52 53 await waitFor(1000); 54 recorder.pause(); 55 recorder.requestData(); 56 57 const blob = await dataPromise; 58 assert_greater_than(blob.size, 2000); 59 }, "Calling requestData once after pausing should lead to more than header data"); 60 61 43 62 </script> 44 63 </body> -
trunk/Source/WebCore/ChangeLog
r274150 r274154 1 2021-03-09 Youenn Fablet <youenn@apple.com> 2 3 MediaRecorder.requestData() not returning all captured media after a pause 4 https://bugs.webkit.org/show_bug.cgi?id=222285 5 <rdar://problem/74884561> 6 7 Reviewed by Eric Carlson. 8 9 Previously, when flushing, we are called on a background thread and we hop to the main thread to append data. 10 In some cases, we were resolving the completion handlers before appending all data. 11 To prevent this, we now append data from a background thread. 12 To do so, we lock when accessing m_data, either to append or take the data. 13 In addition, we cancel writing when clearing the writer. 14 This allows to clean the writer delegate without fearing that write operations are happening. 15 16 Covered by updated test. 17 18 * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h: 19 * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm: 20 (-[WebAVAssetWriterDelegate initWithWriter:]): 21 (-[WebAVAssetWriterDelegate assetWriter:didProduceFragmentedHeaderData:]): 22 (-[WebAVAssetWriterDelegate assetWriter:didProduceFragmentedMediaData:fragmentedMediaDataReport:]): 23 (WebCore::MediaRecorderPrivateWriter::initialize): 24 (WebCore::MediaRecorderPrivateWriter::clear): 25 (WebCore::MediaRecorderPrivateWriter::stopRecording): 26 (WebCore::MediaRecorderPrivateWriter::completeFetchData): 27 (WebCore::MediaRecorderPrivateWriter::appendData): 28 (WebCore::MediaRecorderPrivateWriter::takeData): 29 1 30 2021-03-09 Philippe Normand <pnormand@igalia.com> 2 31 -
trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h
r268363 r274154 77 77 78 78 void appendData(const char*, size_t); 79 void appendData(Ref<SharedBuffer>&&);80 79 81 80 const String& mimeType() const; … … 109 108 void finishedFlushingSamples(); 110 109 void completeFetchData(); 110 RefPtr<SharedBuffer> takeData(); 111 111 112 112 bool m_hasAudio { false }; … … 119 119 RetainPtr<AVAssetWriter> m_writer; 120 120 121 Lock m_dataLock; 121 122 RefPtr<SharedBuffer> m_data; 122 123 CompletionHandler<void(RefPtr<SharedBuffer>&&, double)> m_fetchDataCompletionHandler; -
trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm
r270158 r274154 51 51 52 52 @interface WebAVAssetWriterDelegate : NSObject <AVAssetWriterDelegate> { 53 We akPtr<WebCore::MediaRecorderPrivateWriter>m_writer;54 } 55 56 - (instancetype)initWithWriter:(WebCore::MediaRecorderPrivateWriter *)writer;53 WebCore::MediaRecorderPrivateWriter* m_writer; 54 } 55 56 - (instancetype)initWithWriter:(WebCore::MediaRecorderPrivateWriter&)writer; 57 57 - (void)close; 58 58 … … 62 62 }; 63 63 64 - (instancetype)initWithWriter:(WebCore::MediaRecorderPrivateWriter *)writer64 - (instancetype)initWithWriter:(WebCore::MediaRecorderPrivateWriter&)writer 65 65 { 66 66 ASSERT(isMainThread()); 67 67 self = [super init]; 68 68 if (self) 69 self->m_writer = makeWeakPtr(writer);69 self->m_writer = &writer; 70 70 71 71 return self; … … 75 75 { 76 76 UNUSED_PARAM(assetWriter); 77 if (!isMainThread()) { 78 if (auto size = [fragmentedHeaderData length]) { 79 callOnMainThread([protectedSelf = RetainPtr<WebAVAssetWriterDelegate>(self), buffer = WebCore::SharedBuffer::create(static_cast<const char*>([fragmentedHeaderData bytes]), size)]() mutable { 80 if (protectedSelf->m_writer) 81 protectedSelf->m_writer->appendData(WTFMove(buffer)); 82 }); 83 } 84 return; 85 } 86 87 if (m_writer) 88 m_writer->appendData(static_cast<const char*>([fragmentedHeaderData bytes]), [fragmentedHeaderData length]); 77 m_writer->appendData(static_cast<const char*>([fragmentedHeaderData bytes]), [fragmentedHeaderData length]); 89 78 } 90 79 … … 93 82 UNUSED_PARAM(assetWriter); 94 83 UNUSED_PARAM(fragmentedMediaDataReport); 95 if (!isMainThread()) { 96 if (auto size = [fragmentedMediaData length]) { 97 callOnMainThread([protectedSelf = RetainPtr<WebAVAssetWriterDelegate>(self), buffer = WebCore::SharedBuffer::create(static_cast<const char*>([fragmentedMediaData bytes]), size)]() mutable { 98 if (protectedSelf->m_writer) 99 protectedSelf->m_writer->appendData(WTFMove(buffer)); 100 }); 101 } 102 return; 103 } 104 105 if (m_writer) 106 m_writer->appendData(static_cast<const char*>([fragmentedMediaData bytes]), [fragmentedMediaData length]); 84 m_writer->appendData(static_cast<const char*>([fragmentedMediaData bytes]), [fragmentedMediaData length]); 107 85 } 108 86 … … 165 143 } 166 144 167 m_writerDelegate = adoptNS([[WebAVAssetWriterDelegate alloc] initWithWriter: this]);145 m_writerDelegate = adoptNS([[WebAVAssetWriterDelegate alloc] initWithWriter: *this]); 168 146 [m_writer.get() setDelegate:m_writerDelegate.get()]; 169 147 … … 397 375 m_pendingAudioSampleQueue.clear(); 398 376 m_pendingVideoSampleQueue.clear(); 399 if (m_writer) 377 if (m_writer) { 378 [m_writer cancelWriting]; 400 379 m_writer.clear(); 401 380 } 381 382 // At this pointer, we should no longer be writing any data, so it should be safe to close and nullify m_data without locking. 383 if (m_writerDelegate) 384 [m_writerDelegate close]; 402 385 m_data = nullptr; 386 403 387 if (auto completionHandler = WTFMove(m_fetchDataCompletionHandler)) 404 388 completionHandler(nullptr, 0); … … 489 473 m_hasStartedWriting = false; 490 474 491 if (m_writer) 475 if (m_writer) { 476 [m_writer cancelWriting]; 492 477 m_writer.clear(); 478 } 479 493 480 if (m_fetchDataCompletionHandler) 494 m_fetchDataCompletionHandler( std::exchange(m_data, nullptr), 0);481 m_fetchDataCompletionHandler(takeData(), 0); 495 482 }; 496 483 … … 552 539 m_timeCode = CMTimeGetSeconds(CMTimeAdd(sampleTime, m_currentVideoDuration)); 553 540 } 554 m_fetchDataCompletionHandler( std::exchange(m_data, nullptr), currentTimeCode);541 m_fetchDataCompletionHandler(takeData(), currentTimeCode); 555 542 } 556 543 557 544 void MediaRecorderPrivateWriter::appendData(const char* data, size_t size) 558 545 { 546 auto locker = holdLock(m_dataLock); 559 547 if (!m_data) { 560 548 m_data = SharedBuffer::create(data, size); … … 564 552 } 565 553 566 void MediaRecorderPrivateWriter::appendData(Ref<SharedBuffer>&& buffer) 567 { 568 if (!m_data) { 569 m_data = WTFMove(buffer); 570 return; 571 } 572 m_data->append(WTFMove(buffer)); 554 RefPtr<SharedBuffer> MediaRecorderPrivateWriter::takeData() 555 { 556 auto locker = holdLock(m_dataLock); 557 auto data = WTFMove(m_data); 558 return data; 573 559 } 574 560
Note: See TracChangeset
for help on using the changeset viewer.