Reland: Add Alpha Channel Support For WebRTC Unity Plugin

This CL make webrtc unity plugin compatible with alpha channel support.

TBR=gyzhou@chromium.org,magjed@webrtc.org

Bug: webrtc:8645
Change-Id: Ic1c11f8c82f8244b84b8ab67c623ad2002b940e8
Reviewed-on: https://webrtc-review.googlesource.com/35421
Reviewed-by: George Zhou <gyzhou@chromium.org>
Reviewed-by: Qiang Chen <qiangchen@chromium.org>
Commit-Queue: Qiang Chen <qiangchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#21398}
diff --git a/examples/unityplugin/OWNERS b/examples/unityplugin/OWNERS
index 61ea9a9..343f860 100644
--- a/examples/unityplugin/OWNERS
+++ b/examples/unityplugin/OWNERS
@@ -1 +1,2 @@
 gyzhou@chromium.org
+qiangchen@chromium.org
diff --git a/examples/unityplugin/simple_peer_connection.cc b/examples/unityplugin/simple_peer_connection.cc
index 2ea8227..71d4265 100644
--- a/examples/unityplugin/simple_peer_connection.cc
+++ b/examples/unityplugin/simple_peer_connection.cc
@@ -16,8 +16,16 @@
 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
 #include "api/test/fakeconstraints.h"
 #include "api/videosourceproxy.h"
+#include "media/engine/internaldecoderfactory.h"
+#include "media/engine/internalencoderfactory.h"
+#include "media/engine/stereocodecfactory.h"
 #include "media/engine/webrtcvideocapturerfactory.h"
+#include "media/engine/webrtcvideodecoderfactory.h"
+#include "media/engine/webrtcvideoencoderfactory.h"
+#include "modules/audio_device/include/audio_device.h"
+#include "modules/audio_processing/include/audio_processing.h"
 #include "modules/video_capture/video_capture_factory.h"
+#include "rtc_base/ptr_util.h"
 
 #if defined(WEBRTC_ANDROID)
 #include "examples/unityplugin/classreferenceholder.h"
@@ -94,7 +102,14 @@
     g_peer_connection_factory = webrtc::CreatePeerConnectionFactory(
         g_worker_thread.get(), g_worker_thread.get(), g_signaling_thread.get(),
         nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
-        webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, nullptr);
+        webrtc::CreateBuiltinAudioDecoderFactory(),
+        std::unique_ptr<webrtc::VideoEncoderFactory>(
+            new webrtc::StereoEncoderFactory(
+                rtc::MakeUnique<webrtc::InternalEncoderFactory>())),
+        std::unique_ptr<webrtc::VideoDecoderFactory>(
+            new webrtc::StereoDecoderFactory(
+                rtc::MakeUnique<webrtc::InternalDecoderFactory>())),
+        nullptr, nullptr);
   }
   if (!g_peer_connection_factory.get()) {
     DeletePeerConnection();
diff --git a/examples/unityplugin/unity_plugin_apis.cc b/examples/unityplugin/unity_plugin_apis.cc
index ae98a83..34c28d9 100644
--- a/examples/unityplugin/unity_plugin_apis.cc
+++ b/examples/unityplugin/unity_plugin_apis.cc
@@ -24,12 +24,13 @@
 int CreatePeerConnection(const char** turn_urls,
                          const int no_of_urls,
                          const char* username,
-                         const char* credential) {
+                         const char* credential,
+                         bool mandatory_receive_video) {
   g_peer_connection_map[g_peer_connection_id] =
       new rtc::RefCountedObject<SimplePeerConnection>();
 
   if (!g_peer_connection_map[g_peer_connection_id]->InitializePeerConnection(
-          turn_urls, no_of_urls, username, credential, false))
+          turn_urls, no_of_urls, username, credential, mandatory_receive_video))
     return -1;
 
   return g_peer_connection_id++;
diff --git a/examples/unityplugin/unity_plugin_apis.h b/examples/unityplugin/unity_plugin_apis.h
index 814b967..b32f9e2 100644
--- a/examples/unityplugin/unity_plugin_apis.h
+++ b/examples/unityplugin/unity_plugin_apis.h
@@ -19,9 +19,11 @@
 typedef void (*I420FRAMEREADY_CALLBACK)(const uint8_t* data_y,
                                         const uint8_t* data_u,
                                         const uint8_t* data_v,
+                                        const uint8_t* data_a,
                                         int stride_y,
                                         int stride_u,
                                         int stride_v,
+                                        int stride_a,
                                         uint32_t width,
                                         uint32_t height);
 typedef void (*LOCALDATACHANNELREADY_CALLBACK)();
@@ -47,7 +49,8 @@
 WEBRTC_PLUGIN_API int CreatePeerConnection(const char** turn_urls,
                                            const int no_of_urls,
                                            const char* username,
-                                           const char* credential);
+                                           const char* credential,
+                                           bool mandatory_receive_video);
 // Close a peerconnection.
 WEBRTC_PLUGIN_API bool ClosePeerConnection(int peer_connection_id);
 // Add a audio stream. If audio_only is true, the stream only has an audio
diff --git a/examples/unityplugin/video_observer.cc b/examples/unityplugin/video_observer.cc
index 821acd6..a78ef57 100644
--- a/examples/unityplugin/video_observer.cc
+++ b/examples/unityplugin/video_observer.cc
@@ -17,11 +17,28 @@
 
 void VideoObserver::OnFrame(const webrtc::VideoFrame& frame) {
   std::unique_lock<std::mutex> lock(mutex);
-  rtc::scoped_refptr<webrtc::PlanarYuvBuffer> buffer(
-      frame.video_frame_buffer()->ToI420());
-  if (OnI420FrameReady) {
-    OnI420FrameReady(buffer->DataY(), buffer->DataU(), buffer->DataV(),
-                     buffer->StrideY(), buffer->StrideU(), buffer->StrideV(),
+  if (!OnI420FrameReady)
+    return;
+
+  rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
+      frame.video_frame_buffer());
+
+  if (buffer->type() != webrtc::VideoFrameBuffer::Type::kI420A) {
+    rtc::scoped_refptr<webrtc::I420BufferInterface> i420_buffer =
+        buffer->ToI420();
+    OnI420FrameReady(i420_buffer->DataY(), i420_buffer->DataU(),
+                     i420_buffer->DataV(), nullptr, i420_buffer->StrideY(),
+                     i420_buffer->StrideU(), i420_buffer->StrideV(), 0,
+                     frame.width(), frame.height());
+
+  } else {
+    // The buffer has alpha channel.
+    webrtc::I420ABufferInterface* i420a_buffer = buffer->GetI420A();
+
+    OnI420FrameReady(i420a_buffer->DataY(), i420a_buffer->DataU(),
+                     i420a_buffer->DataV(), i420a_buffer->DataA(),
+                     i420a_buffer->StrideY(), i420a_buffer->StrideU(),
+                     i420a_buffer->StrideV(), i420a_buffer->StrideA(),
                      frame.width(), frame.height());
   }
 }