New method I420Buffer::Copy.
Needed to replace cricket::VideoFrame::MakeExclusive in chromium.
BUG=webrtc:5682
Review URL: https://codereview.webrtc.org/1822283002
Cr-Original-Commit-Position: refs/heads/master@{#12155}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 7cc9cc0460b9828fa5c139ecb79cf568824e6dac
diff --git a/common_video/i420_video_frame_unittest.cc b/common_video/i420_video_frame_unittest.cc
index 8273136..9b2bdd7 100644
--- a/common_video/i420_video_frame_unittest.cc
+++ b/common_video/i420_video_frame_unittest.cc
@@ -254,4 +254,14 @@
EXPECT_EQ(20, frame.render_time_ms());
}
+TEST(TestI420FrameBuffer, Copy) {
+ rtc::scoped_refptr<I420Buffer> buf1(
+ new rtc::RefCountedObject<I420Buffer>(20, 10));
+ memset(buf1->MutableData(kYPlane), 1, 200);
+ memset(buf1->MutableData(kUPlane), 2, 50);
+ memset(buf1->MutableData(kVPlane), 3, 50);
+ rtc::scoped_refptr<I420Buffer> buf2 = I420Buffer::Copy(buf1);
+ EXPECT_TRUE(test::FrameBufsEqual(buf1, buf2));
+}
+
} // namespace webrtc
diff --git a/common_video/include/video_frame_buffer.h b/common_video/include/video_frame_buffer.h
index 270f2d5..9cf57a4 100644
--- a/common_video/include/video_frame_buffer.h
+++ b/common_video/include/video_frame_buffer.h
@@ -81,6 +81,10 @@
void* native_handle() const override;
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override;
+ // Create a new buffer and copy the pixel data.
+ static rtc::scoped_refptr<I420Buffer> Copy(
+ const rtc::scoped_refptr<VideoFrameBuffer>& buffer);
+
protected:
~I420Buffer() override;
diff --git a/common_video/video_frame_buffer.cc b/common_video/video_frame_buffer.cc
index 19e44fe..6f49e8a 100644
--- a/common_video/video_frame_buffer.cc
+++ b/common_video/video_frame_buffer.cc
@@ -12,6 +12,7 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/keep_ref_until_done.h"
+#include "libyuv/convert.h"
// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
static const int kBufferAlignment = 64;
@@ -117,6 +118,23 @@
return nullptr;
}
+rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
+ const rtc::scoped_refptr<VideoFrameBuffer>& buffer) {
+ int width = buffer->width();
+ int height = buffer->height();
+ rtc::scoped_refptr<I420Buffer> copy =
+ new rtc::RefCountedObject<I420Buffer>(width, height);
+ RTC_CHECK(libyuv::I420Copy(buffer->data(kYPlane), buffer->stride(kYPlane),
+ buffer->data(kUPlane), buffer->stride(kUPlane),
+ buffer->data(kVPlane), buffer->stride(kVPlane),
+ copy->MutableData(kYPlane), copy->stride(kYPlane),
+ copy->MutableData(kUPlane), copy->stride(kUPlane),
+ copy->MutableData(kVPlane), copy->stride(kVPlane),
+ width, height) == 0);
+
+ return copy;
+}
+
NativeHandleBuffer::NativeHandleBuffer(void* native_handle,
int width,
int height)
diff --git a/test/frame_utils.cc b/test/frame_utils.cc
index 13f358a..0f41144 100644
--- a/test/frame_utils.cc
+++ b/test/frame_utils.cc
@@ -47,5 +47,23 @@
f1.stride(webrtc::kVPlane), half_width, half_height);
}
+bool FrameBufsEqual(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& f1,
+ const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& f2) {
+ if (f1->width() != f2->width() || f1->height() != f2->height() ||
+ f1->stride(webrtc::kYPlane) != f2->stride(webrtc::kYPlane) ||
+ f1->stride(webrtc::kUPlane) != f2->stride(webrtc::kUPlane) ||
+ f1->stride(webrtc::kVPlane) != f2->stride(webrtc::kVPlane)) {
+ return false;
+ }
+ const int half_width = (f1->width() + 1) / 2;
+ const int half_height = (f1->height() + 1) / 2;
+ return EqualPlane(f1->data(webrtc::kYPlane), f2->data(webrtc::kYPlane),
+ f1->stride(webrtc::kYPlane), f1->width(), f1->height()) &&
+ EqualPlane(f1->data(webrtc::kUPlane), f2->data(webrtc::kUPlane),
+ f1->stride(webrtc::kUPlane), half_width, half_height) &&
+ EqualPlane(f1->data(webrtc::kVPlane), f2->data(webrtc::kVPlane),
+ f1->stride(webrtc::kVPlane), half_width, half_height);
+}
+
} // namespace test
} // namespace webrtc
diff --git a/test/frame_utils.h b/test/frame_utils.h
index 42e2cba..668d999 100644
--- a/test/frame_utils.h
+++ b/test/frame_utils.h
@@ -11,9 +11,11 @@
#define WEBRTC_TEST_FRAME_UTILS_H_
#include "webrtc/base/basictypes.h"
+#include "webrtc/base/scoped_ref_ptr.h"
namespace webrtc {
class VideoFrame;
+class VideoFrameBuffer;
namespace test {
bool EqualPlane(const uint8_t* data1,
@@ -24,6 +26,9 @@
bool FramesEqual(const webrtc::VideoFrame& f1, const webrtc::VideoFrame& f2);
+bool FrameBufsEqual(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& f1,
+ const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& f2);
+
} // namespace test
} // namespace webrtc