[WebRTC] RealtimOutgoingVideoSource should not need to do image conversion
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Feb 2017 16:29:10 +0000 (16:29 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Feb 2017 16:29:10 +0000 (16:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=168802

Patch by Youenn Fablet <youenn@apple.com> on 2017-02-27
Reviewed by Jon Lee.

Source/ThirdParty/libwebrtc:

Exporting new symbols.
Including headers in the project file.

* Source/webrtc/common_video/include/corevideo_frame_buffer.h:
* Source/webrtc/common_video/include/i420_buffer_pool.h:
* Source/webrtc/common_video/include/video_frame_buffer.h:
* libwebrtc.xcodeproj/project.pbxproj:

Source/WebCore:

Covered by manual testing as mock sources do not hit the same code path.

* platform/mediastream/mac/AVVideoCaptureSource.h:
* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::currentFrameCGImage):
* platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp:
(WebCore::RealtimeOutgoingVideoSource::sendFrame):
(WebCore::RealtimeOutgoingVideoSource::videoSampleAvailable):
* platform/mediastream/mac/RealtimeOutgoingVideoSource.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213066 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/ThirdParty/libwebrtc/ChangeLog
Source/ThirdParty/libwebrtc/Source/webrtc/common_video/include/corevideo_frame_buffer.h
Source/ThirdParty/libwebrtc/Source/webrtc/common_video/include/i420_buffer_pool.h
Source/ThirdParty/libwebrtc/Source/webrtc/common_video/include/video_frame_buffer.h
Source/ThirdParty/libwebrtc/libwebrtc.xcodeproj/project.pbxproj
Source/WebCore/ChangeLog
Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h
Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm
Source/WebCore/platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp
Source/WebCore/platform/mediastream/mac/RealtimeOutgoingVideoSource.h

index 16db246..fc1d638 100644 (file)
@@ -1,3 +1,18 @@
+2017-02-27  Youenn Fablet  <youenn@apple.com>
+
+        [WebRTC] RealtimOutgoingVideoSource should not need to do image conversion
+        https://bugs.webkit.org/show_bug.cgi?id=168802
+
+        Reviewed by Jon Lee.
+
+        Exporting new symbols.
+        Including headers in the project file.
+
+        * Source/webrtc/common_video/include/corevideo_frame_buffer.h:
+        * Source/webrtc/common_video/include/i420_buffer_pool.h:
+        * Source/webrtc/common_video/include/video_frame_buffer.h:
+        * libwebrtc.xcodeproj/project.pbxproj:
+
 2017-02-24  Alex Christensen  <achristensen@webkit.org>
 
         Remove unneeded protobuf tests directory.
index c925cbf..944a4b1 100644 (file)
@@ -19,7 +19,7 @@
 
 namespace webrtc {
 
-class CoreVideoFrameBuffer : public NativeHandleBuffer {
+class WEBRTC_EXPORT CoreVideoFrameBuffer : public NativeHandleBuffer {
  public:
   explicit CoreVideoFrameBuffer(CVPixelBufferRef pixel_buffer);
   CoreVideoFrameBuffer(CVPixelBufferRef pixel_buffer,
index f056263..0b049ab 100644 (file)
@@ -26,7 +26,7 @@ namespace webrtc {
 // changes, old buffers will be purged from the pool.
 // Note that CreateBuffer will crash if more than kMaxNumberOfFramesBeforeCrash
 // are created. This is to prevent memory leaks where frames are not returned.
-class I420BufferPool {
+class WEBRTC_EXPORT I420BufferPool {
  public:
   I420BufferPool()
       : I420BufferPool(false) {}
index 858a8e5..fab197e 100644 (file)
@@ -157,7 +157,7 @@ class WEBRTC_EXPORT I420Buffer : public VideoFrameBuffer {
 // This is used for convenience as most native-handle implementations can share
 // many VideoFrame implementations, but need to implement a few others (such
 // as their own destructors or conversion methods back to software I420).
-class NativeHandleBuffer : public VideoFrameBuffer {
+class WEBRTC_EXPORT NativeHandleBuffer : public VideoFrameBuffer {
  public:
   NativeHandleBuffer(void* native_handle, int width, int height);
 
index c1be459..7d3db3c 100644 (file)
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
+               41109AAC1E5FA19200C0955A /* corevideo_frame_buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 41109AA51E5FA19200C0955A /* corevideo_frame_buffer.h */; };
+               41109AAD1E5FA19200C0955A /* i420_buffer_pool.h in Headers */ = {isa = PBXBuildFile; fileRef = 41109AA61E5FA19200C0955A /* i420_buffer_pool.h */; };
+               41109AAE1E5FA19200C0955A /* video_frame_buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 41109AA71E5FA19200C0955A /* video_frame_buffer.h */; };
+               41109AAF1E5FA19200C0955A /* frame_callback.h in Headers */ = {isa = PBXBuildFile; fileRef = 41109AA81E5FA19200C0955A /* frame_callback.h */; };
+               41109AB01E5FA19200C0955A /* bitrate_adjuster.h in Headers */ = {isa = PBXBuildFile; fileRef = 41109AA91E5FA19200C0955A /* bitrate_adjuster.h */; };
+               41109AB11E5FA19200C0955A /* incoming_video_stream.h in Headers */ = {isa = PBXBuildFile; fileRef = 41109AAA1E5FA19200C0955A /* incoming_video_stream.h */; };
+               41109AB21E5FA19200C0955A /* video_image.h in Headers */ = {isa = PBXBuildFile; fileRef = 41109AAB1E5FA19200C0955A /* video_image.h */; };
                4140B8201E4E3383007409E6 /* audio_encoder_pcm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4140B8181E4E3383007409E6 /* audio_encoder_pcm.cc */; };
                4140B8211E4E3383007409E6 /* audio_encoder_pcm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4140B8191E4E3383007409E6 /* audio_encoder_pcm.h */; };
                4140B8221E4E3383007409E6 /* audio_decoder_pcm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4140B81A1E4E3383007409E6 /* audio_decoder_pcm.cc */; };
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+               41109AA51E5FA19200C0955A /* corevideo_frame_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = corevideo_frame_buffer.h; path = include/corevideo_frame_buffer.h; sourceTree = "<group>"; };
+               41109AA61E5FA19200C0955A /* i420_buffer_pool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = i420_buffer_pool.h; path = include/i420_buffer_pool.h; sourceTree = "<group>"; };
+               41109AA71E5FA19200C0955A /* video_frame_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = video_frame_buffer.h; path = include/video_frame_buffer.h; sourceTree = "<group>"; };
+               41109AA81E5FA19200C0955A /* frame_callback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = frame_callback.h; path = include/frame_callback.h; sourceTree = "<group>"; };
+               41109AA91E5FA19200C0955A /* bitrate_adjuster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bitrate_adjuster.h; path = include/bitrate_adjuster.h; sourceTree = "<group>"; };
+               41109AAA1E5FA19200C0955A /* incoming_video_stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = incoming_video_stream.h; path = include/incoming_video_stream.h; sourceTree = "<group>"; };
+               41109AAB1E5FA19200C0955A /* video_image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = video_image.h; path = include/video_image.h; sourceTree = "<group>"; };
                4140B8181E4E3383007409E6 /* audio_encoder_pcm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = audio_encoder_pcm.cc; path = g711/audio_encoder_pcm.cc; sourceTree = "<group>"; };
                4140B8191E4E3383007409E6 /* audio_encoder_pcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = audio_encoder_pcm.h; path = g711/audio_encoder_pcm.h; sourceTree = "<group>"; };
                4140B81A1E4E3383007409E6 /* audio_decoder_pcm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = audio_decoder_pcm.cc; path = g711/audio_decoder_pcm.cc; sourceTree = "<group>"; };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+               41109AA41E5FA18100C0955A /* include */ = {
+                       isa = PBXGroup;
+                       children = (
+                               41109AA51E5FA19200C0955A /* corevideo_frame_buffer.h */,
+                               41109AA61E5FA19200C0955A /* i420_buffer_pool.h */,
+                               41109AA71E5FA19200C0955A /* video_frame_buffer.h */,
+                               41109AA81E5FA19200C0955A /* frame_callback.h */,
+                               41109AA91E5FA19200C0955A /* bitrate_adjuster.h */,
+                               41109AAA1E5FA19200C0955A /* incoming_video_stream.h */,
+                               41109AAB1E5FA19200C0955A /* video_image.h */,
+                       );
+                       name = include;
+                       sourceTree = "<group>";
+               };
                4140B8161E4E335E007409E6 /* g711 */ = {
                        isa = PBXGroup;
                        children = (
                        isa = PBXGroup;
                        children = (
                                5CDD83411E43256400621E92 /* h264 */,
+                               41109AA41E5FA18100C0955A /* include */,
                                5CDD83651E4325C200621E92 /* libyuv */,
                                5C4B4C101E431F75002651C8 /* bitrate_adjuster.cc */,
                                5C4B4C111E431F75002651C8 /* corevideo_frame_buffer.cc */,
                                5CDD83CD1E439A6F00621E92 /* encoded_frame.h in Headers */,
                                5CDD85A01E43B5C000621E92 /* encoder_rtcp_feedback.h in Headers */,
                                5CDD8B991E43C2B500621E92 /* energy_inverse.h in Headers */,
+                               41109AAC1E5FA19200C0955A /* corevideo_frame_buffer.h in Headers */,
                                5CDD8B9B1E43C2B500621E92 /* enh_upsample.h in Headers */,
                                5CDD8B9F1E43C2B500621E92 /* enhancer.h in Headers */,
                                5CDD8B9D1E43C2B500621E92 /* enhancer_interface.h in Headers */,
                                5C4B48E41E42C1E3002651C8 /* hybriddataengine.h in Headers */,
                                5C63F8021E416288002CA531 /* ifaddrs_converter.h in Headers */,
                                5C63F8051E416288002CA531 /* ignore_wundef.h in Headers */,
+                               41109AAE1E5FA19200C0955A /* video_frame_buffer.h in Headers */,
                                5CDD8BB41E43C2B500621E92 /* ilbc.h in Headers */,
                                5CDD8BB61E43C2B500621E92 /* index_conv_dec.h in Headers */,
                                5CDD8BB81E43C2B500621E92 /* index_conv_enc.h in Headers */,
                                5C4B4C711E431F9C002651C8 /* lapped_transform.h in Headers */,
                                5CDD84201E439B2900621E92 /* legacy_encoded_audio_frame.h in Headers */,
                                5CDD90281E43CEDE00621E92 /* level_controller.h in Headers */,
+                               41109AB11E5FA19200C0955A /* incoming_video_stream.h in Headers */,
                                5CDD90251E43CEDE00621E92 /* level_controller_constants.h in Headers */,
                                5CDD84B91E43AF1300621E92 /* level_estimator_impl.h in Headers */,
                                5CDD84601E43AE2900621E92 /* level_indicator.h in Headers */,
                                5C63F8101E416288002CA531 /* logging.h in Headers */,
                                5C63F8121E416288002CA531 /* logsinks.h in Headers */,
                                5CDD87061E43BA7500621E92 /* loudness_histogram.h in Headers */,
+                               41109AB21E5FA19200C0955A /* video_image.h in Headers */,
                                5CDD87C61E43BC0500621E92 /* lpc_analysis.h in Headers */,
                                5CDD8BC21E43C2B500621E92 /* lpc_encode.h in Headers */,
                                5CDD87C81E43BC0500621E92 /* lpc_gain_swb_tables.h in Headers */,
                                5C63F8131E416288002CA531 /* maccocoathreadhelper.h in Headers */,
                                5C63F8161E416288002CA531 /* macconversion.h in Headers */,
                                5C63F8181E416288002CA531 /* macutils.h in Headers */,
+                               41109AB01E5FA19200C0955A /* bitrate_adjuster.h in Headers */,
                                5C63F81A1E416288002CA531 /* macwindowpicker.h in Headers */,
                                5C63F81B1E416288002CA531 /* mathutils.h in Headers */,
                                5CDD907E1E43D15C00621E92 /* matrix.h in Headers */,
                                5C63F8561E416288002CA531 /* race_checker.h in Headers */,
                                5C63F8581E416288002CA531 /* random.h in Headers */,
                                5CDD8A4B1E43BFB300621E92 /* random_vector.h in Headers */,
+                               41109AAF1E5FA19200C0955A /* frame_callback.h in Headers */,
                                5CDD895C1E43BF3A00621E92 /* rapid_resync_request.h in Headers */,
                                5C63F85A1E416288002CA531 /* rate_limiter.h in Headers */,
                                5C63F85C1E416288002CA531 /* rate_statistics.h in Headers */,
                                5CDD889B1E43BE3C00621E92 /* rtcp_receiver.h in Headers */,
                                5CDD889E1E43BE3C00621E92 /* rtcp_sender.h in Headers */,
                                5CDD88A11E43BE3C00621E92 /* rtcp_utility.h in Headers */,
+                               41109AAD1E5FA19200C0955A /* i420_buffer_pool.h in Headers */,
                                5C63F9651E41737B002CA531 /* rtcstatscollector.h in Headers */,
                                5CDD8AB71E43C00F00621E92 /* rtp_file_source.h in Headers */,
                                5CDD88B11E43BE3C00621E92 /* rtp_format.h in Headers */,
index ebcf134..f699465 100644 (file)
@@ -1,3 +1,20 @@
+2017-02-27  Youenn Fablet  <youenn@apple.com>
+
+        [WebRTC] RealtimOutgoingVideoSource should not need to do image conversion
+        https://bugs.webkit.org/show_bug.cgi?id=168802
+
+        Reviewed by Jon Lee.
+
+        Covered by manual testing as mock sources do not hit the same code path.
+
+        * platform/mediastream/mac/AVVideoCaptureSource.h:
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        (WebCore::AVVideoCaptureSource::currentFrameCGImage):
+        * platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp:
+        (WebCore::RealtimeOutgoingVideoSource::sendFrame):
+        (WebCore::RealtimeOutgoingVideoSource::videoSampleAvailable):
+        * platform/mediastream/mac/RealtimeOutgoingVideoSource.h:
+
 2017-02-27  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Downloads attributes tests are failing
index 20c0530..2431fb7 100644 (file)
@@ -41,7 +41,7 @@ namespace WebCore {
 
 class FloatRect;
 class GraphicsContext;
-class AVVideoSourcePreview;
+class PixelBufferConformerCV;
 
 class AVVideoCaptureSource : public AVMediaCaptureSource {
 public:
@@ -87,6 +87,8 @@ private:
     RetainPtr<CGImageRef> m_lastImage;
     RetainPtr<AVCaptureVideoDataOutput> m_videoOutput;
 
+    std::unique_ptr<PixelBufferConformerCV> m_pixelBufferConformer;
+
     Vector<Float64> m_videoFrameTimeStamps;
     Float64 m_frameRate { 0 };
     int32_t m_width { 0 };
index 72c9852..f08b3ae 100644 (file)
@@ -36,6 +36,7 @@
 #import "MediaConstraints.h"
 #import "MediaSampleAVFObjC.h"
 #import "NotImplemented.h"
+#import "PixelBufferConformerCV.h"
 #import "PlatformLayer.h"
 #import "RealtimeMediaSourceCenter.h"
 #import "RealtimeMediaSourceSettings.h"
@@ -102,7 +103,7 @@ using namespace WebCore;
 
 namespace WebCore {
 
-const OSType videoCaptureFormat = kCVPixelFormatType_32BGRA;
+const OSType videoCaptureFormat = kCVPixelFormatType_420YpCbCr8Planar;
 
 RefPtr<AVMediaCaptureSource> AVVideoCaptureSource::create(AVCaptureDeviceTypedef* device, const AtomicString& id, const MediaConstraints* constraints, String& invalidConstraint)
 {
@@ -462,16 +463,16 @@ RetainPtr<CGImageRef> AVVideoCaptureSource::currentFrameCGImage()
     CVPixelBufferRef pixelBuffer = static_cast<CVPixelBufferRef>(CMSampleBufferGetImageBuffer(m_buffer.get()));
     ASSERT(CVPixelBufferGetPixelFormatType(pixelBuffer) == videoCaptureFormat);
 
-    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
-    void *baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer);
-    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
-    size_t width = CVPixelBufferGetWidth(pixelBuffer);
-    size_t height = CVPixelBufferGetHeight(pixelBuffer);
-
-    RetainPtr<CGDataProviderRef> provider = adoptCF(CGDataProviderCreateWithData(NULL, baseAddress, bytesPerRow * height, NULL));
-    m_lastImage = adoptCF(CGImageCreate(width, height, 8, 32, bytesPerRow, sRGBColorSpaceRef(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, provider.get(), NULL, true, kCGRenderingIntentDefault));
+    if (!m_pixelBufferConformer) {
+#if USE(VIDEOTOOLBOX)
+        NSDictionary *attributes = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA) };
+#else
+        NSDictionary *attributes = nil;
+#endif
+        m_pixelBufferConformer = std::make_unique<PixelBufferConformerCV>((CFDictionaryRef)attributes);
+    }
 
-    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
+    m_lastImage = m_pixelBufferConformer->createImageFromPixelBuffer(pixelBuffer);
 
     return m_lastImage;
 }
index b138e46..169b417 100644 (file)
@@ -31,6 +31,7 @@
 
 #if USE(LIBWEBRTC)
 
+#include <webrtc/common_video/include/corevideo_frame_buffer.h>
 #include <webrtc/common_video/libyuv/include/webrtc_libyuv.h>
 #include <webrtc/media/base/videoframe.h>
 
@@ -72,45 +73,49 @@ void RealtimeOutgoingVideoSource::RemoveSink(rtc::VideoSinkInterface<webrtc::Vid
     m_sinks.removeFirst(sink);
 }
 
+void RealtimeOutgoingVideoSource::sendFrame(rtc::scoped_refptr<webrtc::VideoFrameBuffer>&& buffer)
+{
+    webrtc::VideoFrame frame(buffer, 0, 0, webrtc::kVideoRotation_0);
+    for (auto* sink : m_sinks)
+        sink->OnFrame(frame);
+}
+
 void RealtimeOutgoingVideoSource::videoSampleAvailable(MediaSample& sample)
 {
     if (!m_sinks.size())
         return;
 
-
     // FIXME: Shouldn't we use RealtimeMediaSource::size()
     const auto& settings = m_videoSource->settings();
 
-    // FIXME: We should not need to allocate one buffer per frame.
-    auto dest = webrtc::I420Buffer::Create(settings.width(), settings.height());
-
-    if (!m_muted && m_enabled) {
-        ASSERT(sample.platformSample().type == PlatformSample::CMSampleBufferType);
-        auto pixelBuffer = static_cast<CVPixelBufferRef>(CMSampleBufferGetImageBuffer(sample.platformSample().sample.cmSampleBuffer));
-        auto pixelFormatType = CVPixelBufferGetPixelFormatType(pixelBuffer);
-
-        CVPixelBufferLockBaseAddress(pixelBuffer, 0);
-        uint8_t* src = reinterpret_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0));
-
-        if (pixelFormatType == kCVPixelFormatType_420YpCbCr8Planar) {
-            // We probably can memcpy the data directly
-            webrtc::ConvertToI420(webrtc::kI420, src, 0, 0, settings.width(), settings.height(), 0, webrtc::kVideoRotation_0, dest);
-        } else if (pixelFormatType == kCVPixelFormatType_32BGRA)
-            webrtc::ConvertToI420(webrtc::kARGB, src, 0, 0, settings.width(), settings.height(), 0, webrtc::kVideoRotation_0, dest);
-        else {
-            // FIXME: Mock source conversion works with kBGRA while regular camera works with kARGB
-            ASSERT(pixelFormatType == kCVPixelFormatType_32ARGB);
-            webrtc::ConvertToI420(webrtc::kBGRA, src, 0, 0, settings.width(), settings.height(), 0, webrtc::kVideoRotation_0, dest);
-        }
-
-        CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
-    } else {
-        dest->SetToBlack();
+    if (m_muted || !m_enabled) {
+        auto blackBuffer = m_bufferPool.CreateBuffer(settings.width(), settings.height());
+        blackBuffer->SetToBlack();
+        sendFrame(WTFMove(blackBuffer));
     }
 
-    webrtc::VideoFrame frame(dest, 0, 0,  webrtc::kVideoRotation_0);
-    for (auto* sink : m_sinks)
-        sink->OnFrame(frame);
+    ASSERT(sample.platformSample().type == PlatformSample::CMSampleBufferType);
+    auto pixelBuffer = static_cast<CVPixelBufferRef>(CMSampleBufferGetImageBuffer(sample.platformSample().sample.cmSampleBuffer));
+    auto pixelFormatType = CVPixelBufferGetPixelFormatType(pixelBuffer);
+
+    if (pixelFormatType == kCVPixelFormatType_420YpCbCr8Planar) {
+        sendFrame(new rtc::RefCountedObject<webrtc::CoreVideoFrameBuffer>(pixelBuffer));
+        return;
+    }
+
+    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
+    auto* source = reinterpret_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0));
+
+    auto newBuffer = m_bufferPool.CreateBuffer(settings.width(), settings.height());
+    if (pixelFormatType == kCVPixelFormatType_32BGRA)
+        webrtc::ConvertToI420(webrtc::kARGB, source, 0, 0, settings.width(), settings.height(), 0, webrtc::kVideoRotation_0, newBuffer);
+    else {
+        // FIXME: Mock source conversion works with kBGRA while regular camera works with kARGB
+        ASSERT(pixelFormatType == kCVPixelFormatType_32ARGB);
+        webrtc::ConvertToI420(webrtc::kBGRA, source, 0, 0, settings.width(), settings.height(), 0, webrtc::kVideoRotation_0, newBuffer);
+    }
+    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
+    sendFrame(WTFMove(newBuffer));
 }
 
 } // namespace WebCore
index 4c6dc71..257310c 100644 (file)
@@ -34,6 +34,7 @@
 #include "RealtimeMediaSource.h"
 #include <webrtc/api/mediastreaminterface.h>
 #include <webrtc/base/optional.h>
+#include <webrtc/common_video/include/i420_buffer_pool.h>
 #include <webrtc/media/base/videosinkinterface.h>
 
 namespace WebCore {
@@ -48,6 +49,8 @@ public:
 private:
     RealtimeOutgoingVideoSource(Ref<RealtimeMediaSource>&&);
 
+    void sendFrame(rtc::scoped_refptr<webrtc::VideoFrameBuffer>&&);
+
     // Notifier API
     void RegisterObserver(webrtc::ObserverInterface*) final { }
     void UnregisterObserver(webrtc::ObserverInterface*) final { }
@@ -71,6 +74,7 @@ private:
     void videoSampleAvailable(MediaSample&) final;
 
     Vector<rtc::VideoSinkInterface<webrtc::VideoFrame>*> m_sinks;
+    webrtc::I420BufferPool m_bufferPool;
     Ref<RealtimeMediaSource> m_videoSource;
     bool m_enabled { true };
     bool m_muted { false };