Modified: trunk/Source/WebCore/ChangeLog (264609 => 264610)
--- trunk/Source/WebCore/ChangeLog 2020-07-20 19:47:49 UTC (rev 264609)
+++ trunk/Source/WebCore/ChangeLog 2020-07-20 19:52:09 UTC (rev 264610)
@@ -1,3 +1,20 @@
+2020-07-20 Darin Adler <[email protected]>
+
+ [Cocoa] MediaSampleAVFObjC::createImageSample depends on function argument evaluation order
+ https://bugs.webkit.org/show_bug.cgi?id=214560
+
+ Reviewed by Anders Carlsson.
+
+ * platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
+ (WebCore::deallocateVectorBuffer): Renamed from releaseUint8Vector.
+ (WebCore::MediaSampleAVFObjC::createImageSample): Rearranged code so that we don't call both
+ data() and releaseBuffer() on the same vector in the same function call; that isn't safe because
+ the order of argument evaluation is not guaranteed, and so data() could be called after the
+ buffer is released. Also added code to deallocate the buffer if CVPixelBufferCreateWithBytes
+ fails. The old code would have leaked it in that case. Also made some style tweaks to use
+ adoptCF more consistently to handle reference counting, and slightly optimized a loop to
+ only get the array count once.
+
2020-07-20 Philippe Normand <[email protected]>
[GStreamer] Add support for canvas captureStream, tests failing since they were added in r213598
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm (264609 => 264610)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm 2020-07-20 19:47:49 UTC (rev 264609)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm 2020-07-20 19:52:09 UTC (rev 264610)
@@ -41,7 +41,7 @@
namespace WebCore {
-static inline void releaseUint8Vector(void *array, const void*)
+static void deallocateVectorBuffer(void* array, const void*)
{
WTF::VectorMalloc::free(array);
}
@@ -48,33 +48,33 @@
RefPtr<MediaSampleAVFObjC> MediaSampleAVFObjC::createImageSample(Vector<uint8_t>&& array, unsigned width, unsigned height)
{
- CVPixelBufferRef pixelBuffer = nullptr;
- auto status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, array.data(), width * 4, releaseUint8Vector, array.releaseBuffer().leakPtr(), NULL, &pixelBuffer);
- auto imageBuffer = adoptCF(pixelBuffer);
-
+ CVPixelBufferRef pixelBufferRaw = nullptr;
+ auto data = ""
+ auto status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, data, width * 4, deallocateVectorBuffer, data, nullptr, &pixelBufferRaw);
+ auto pixelBuffer = adoptCF(pixelBufferRaw);
+ if (!pixelBuffer) {
+ deallocateVectorBuffer(data, nullptr);
+ return nullptr;
+ }
ASSERT_UNUSED(status, !status);
- if (!imageBuffer)
- return nullptr;
- CMVideoFormatDescriptionRef formatDescription = nullptr;
- status = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, imageBuffer.get(), &formatDescription);
+ CMVideoFormatDescriptionRef formatDescriptionRaw = nullptr;
+ status = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer.get(), &formatDescriptionRaw);
ASSERT(!status);
+ auto formatDescription = adoptCF(formatDescriptionRaw);
CMSampleTimingInfo sampleTimingInformation = { kCMTimeInvalid, kCMTimeInvalid, kCMTimeInvalid };
-
- CMSampleBufferRef sampleBuffer;
- status = CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, imageBuffer.get(), formatDescription, &sampleTimingInformation, &sampleBuffer);
- CFRelease(formatDescription);
+ CMSampleBufferRef sampleBufferRaw = nullptr;
+ status = CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, pixelBuffer.get(), formatDescription.get(), &sampleTimingInformation, &sampleBufferRaw);
ASSERT(!status);
+ auto sampleBuffer = adoptCF(sampleBufferRaw);
- auto sample = adoptCF(sampleBuffer);
-
- CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sample.get(), true);
- for (CFIndex i = 0; i < CFArrayGetCount(attachmentsArray); ++i) {
+ CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer.get(), true);
+ for (CFIndex i = 0, count = CFArrayGetCount(attachmentsArray); i < count; ++i) {
CFMutableDictionaryRef attachments = checked_cf_cast<CFMutableDictionaryRef>(CFArrayGetValueAtIndex(attachmentsArray, i));
CFDictionarySetValue(attachments, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);
}
- return create(sample.get());
+ return create(sampleBuffer.get());
}
MediaTime MediaSampleAVFObjC::presentationTime() const