New method I420Buffer::Copy.

Needed to replace cricket::VideoFrame::MakeExclusive in chromium.

BUG=webrtc:5682

Review URL: https://codereview.webrtc.org/1822283002

Cr-Commit-Position: refs/heads/master@{#12155}
This commit is contained in:
nisse 2016-03-29 23:44:19 -07:00 committed by Commit bot
parent cc411c0599
commit 7cc9cc0460
5 changed files with 55 additions and 0 deletions

View File

@ -254,4 +254,14 @@ TEST(TestVideoFrame, TextureInitialValues) {
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

View File

@ -81,6 +81,10 @@ class I420Buffer : public VideoFrameBuffer {
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;

View File

@ -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 @@ rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::NativeToI420Buffer() {
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)

View File

@ -47,5 +47,23 @@ bool FramesEqual(const webrtc::VideoFrame& f1, const webrtc::VideoFrame& f2) {
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

View File

@ -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 EqualPlane(const uint8_t* data1,
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