Make FrameBuffer be able to signal if it's trivially convertible to I420

Bug: chromium:930186,webrtc:10310
Change-Id: I7857c33d3616ac58738b22816f9c78fe9e6d1d3c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/134206
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27798}
diff --git a/api/video/video_frame_buffer.cc b/api/video/video_frame_buffer.cc
index 41276be..1e5320d 100644
--- a/api/video/video_frame_buffer.cc
+++ b/api/video/video_frame_buffer.cc
@@ -15,14 +15,20 @@
 namespace webrtc {
 
 rtc::scoped_refptr<I420BufferInterface> VideoFrameBuffer::GetI420() {
-  RTC_CHECK(type() == Type::kI420);
-  return static_cast<I420BufferInterface*>(this);
+  if (type() == Type::kI420 || type() == Type::kI420A) {
+    return static_cast<I420BufferInterface*>(this);
+  } else {
+    return nullptr;
+  }
 }
 
 rtc::scoped_refptr<const I420BufferInterface> VideoFrameBuffer::GetI420()
     const {
-  RTC_CHECK(type() == Type::kI420);
-  return static_cast<const I420BufferInterface*>(this);
+  if (type() == Type::kI420 || type() == Type::kI420A) {
+    return static_cast<const I420BufferInterface*>(this);
+  } else {
+    return nullptr;
+  }
 }
 
 I420ABufferInterface* VideoFrameBuffer::GetI420A() {
diff --git a/api/video/video_frame_buffer.h b/api/video/video_frame_buffer.h
index 7fb603e..af18e57 100644
--- a/api/video/video_frame_buffer.h
+++ b/api/video/video_frame_buffer.h
@@ -65,12 +65,19 @@
   // software encoders.
   virtual rtc::scoped_refptr<I420BufferInterface> ToI420() = 0;
 
-  // These functions should only be called if type() is of the correct type.
-  // Calling with a different type will result in a crash.
+  // GetI420() methods should return I420 buffer if conversion is trivial, i.e
+  // no change for binary data is needed. Otherwise these methods should return
+  // nullptr. One example of buffer with that property is
+  // WebrtcVideoFrameAdapter in Chrome - it's I420 buffer backed by a shared
+  // memory buffer. Therefore it must have type kNative. Yet, ToI420()
+  // doesn't affect binary data at all. Another example is any I420A buffer.
   // TODO(magjed): Return raw pointers for GetI420 once deprecated interface is
   // removed.
-  rtc::scoped_refptr<I420BufferInterface> GetI420();
-  rtc::scoped_refptr<const I420BufferInterface> GetI420() const;
+  virtual rtc::scoped_refptr<I420BufferInterface> GetI420();
+  virtual rtc::scoped_refptr<const I420BufferInterface> GetI420() const;
+
+  // These functions should only be called if type() is of the correct type.
+  // Calling with a different type will result in a crash.
   I420ABufferInterface* GetI420A();
   const I420ABufferInterface* GetI420A() const;
   I444BufferInterface* GetI444();