Add I420Buffer::Copy method taking plane pointers as input.
BUG=None. Review-Url: https://codereview.webrtc.org/2528153002 Cr-Commit-Position: refs/heads/master@{#15259}
This commit is contained in:
parent
e441bdb744
commit
2f58ec82fc
@ -151,16 +151,12 @@ TEST(TestVideoFrame, ShallowCopy) {
|
||||
memset(buffer_y, 16, kSizeY);
|
||||
memset(buffer_u, 8, kSizeU);
|
||||
memset(buffer_v, 4, kSizeV);
|
||||
// TODO(nisse): This new + Copy looks quite awkward. Consider adding
|
||||
// an alternative I420Buffer::Create method.
|
||||
|
||||
VideoFrame frame1(
|
||||
I420Buffer::Copy(*rtc::scoped_refptr<VideoFrameBuffer>(
|
||||
new rtc::RefCountedObject<webrtc::WrappedI420Buffer>(
|
||||
width, height,
|
||||
buffer_y, stride_y,
|
||||
buffer_u, stride_u,
|
||||
buffer_v, stride_v,
|
||||
rtc::Callback0<void>([](){})))),
|
||||
I420Buffer::Copy(width, height,
|
||||
buffer_y, stride_y,
|
||||
buffer_u, stride_u,
|
||||
buffer_v, stride_v),
|
||||
kRotation, 0);
|
||||
frame1.set_timestamp(timestamp);
|
||||
frame1.set_ntp_time_ms(ntp_time_ms);
|
||||
|
||||
@ -58,9 +58,6 @@ class VideoFrameBuffer : public rtc::RefCountInterface {
|
||||
// Plain I420 buffer in standard memory.
|
||||
class I420Buffer : public VideoFrameBuffer {
|
||||
public:
|
||||
I420Buffer(int width, int height);
|
||||
I420Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
|
||||
|
||||
static rtc::scoped_refptr<I420Buffer> Create(int width, int height);
|
||||
static rtc::scoped_refptr<I420Buffer> Create(int width,
|
||||
int height,
|
||||
@ -68,6 +65,24 @@ class I420Buffer : public VideoFrameBuffer {
|
||||
int stride_u,
|
||||
int stride_v);
|
||||
|
||||
// Create a new buffer and copy the pixel data.
|
||||
static rtc::scoped_refptr<I420Buffer> Copy(const VideoFrameBuffer& buffer);
|
||||
|
||||
static rtc::scoped_refptr<I420Buffer> Copy(
|
||||
int width, int height,
|
||||
const uint8_t* data_y, int stride_y,
|
||||
const uint8_t* data_u, int stride_u,
|
||||
const uint8_t* data_v, int stride_v);
|
||||
|
||||
// Returns a rotated versions of |src|. Native buffers are not
|
||||
// supported. The reason this function doesn't return an I420Buffer,
|
||||
// is that it returns |src| unchanged in case |rotation| is zero.
|
||||
// TODO(nisse): Consider dropping the special handling of zero
|
||||
// rotation, and leave any optimizing that case to the caller.
|
||||
static rtc::scoped_refptr<VideoFrameBuffer> Rotate(
|
||||
rtc::scoped_refptr<VideoFrameBuffer> src,
|
||||
VideoRotation rotation);
|
||||
|
||||
// Sets all three planes to all zeros. Used to work around for
|
||||
// quirks in memory checkers
|
||||
// (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and
|
||||
@ -95,9 +110,6 @@ 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 VideoFrameBuffer& buffer);
|
||||
|
||||
// Scale the cropped area of |src| to the size of |this| buffer, and
|
||||
// write the result into |this|.
|
||||
void CropAndScaleFrom(const VideoFrameBuffer& src,
|
||||
@ -133,14 +145,10 @@ class I420Buffer : public VideoFrameBuffer {
|
||||
ScaleFrom(*src);
|
||||
}
|
||||
|
||||
// Returns a rotated versions of |src|. Native buffers are not
|
||||
// supported. The reason this function doesn't return an I420Buffer,
|
||||
// is that it returns |src| unchanged in case |rotation| is zero.
|
||||
static rtc::scoped_refptr<VideoFrameBuffer> Rotate(
|
||||
rtc::scoped_refptr<VideoFrameBuffer> src,
|
||||
VideoRotation rotation);
|
||||
|
||||
protected:
|
||||
I420Buffer(int width, int height);
|
||||
I420Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
|
||||
|
||||
~I420Buffer() override;
|
||||
|
||||
private:
|
||||
|
||||
@ -61,10 +61,12 @@ I420Buffer::I420Buffer(int width,
|
||||
I420Buffer::~I420Buffer() {
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<I420Buffer> I420Buffer::Create(int width, int height) {
|
||||
return new rtc::RefCountedObject<I420Buffer>(width, height);
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<I420Buffer> I420Buffer::Create(int width,
|
||||
int height,
|
||||
int stride_y,
|
||||
@ -74,6 +76,67 @@ rtc::scoped_refptr<I420Buffer> I420Buffer::Create(int width,
|
||||
width, height, stride_y, stride_u, stride_v);
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
|
||||
const VideoFrameBuffer& source) {
|
||||
return Copy(source.width(), source.height(),
|
||||
source.DataY(), source.StrideY(),
|
||||
source.DataU(), source.StrideU(),
|
||||
source.DataV(), source.StrideV());
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
|
||||
int width, int height,
|
||||
const uint8_t* data_y, int stride_y,
|
||||
const uint8_t* data_u, int stride_u,
|
||||
const uint8_t* data_v, int stride_v) {
|
||||
// Note: May use different strides than the input data.
|
||||
rtc::scoped_refptr<I420Buffer> buffer = Create(width, height);
|
||||
RTC_CHECK_EQ(0, libyuv::I420Copy(data_y, stride_y,
|
||||
data_u, stride_u,
|
||||
data_v, stride_v,
|
||||
buffer->MutableDataY(), buffer->StrideY(),
|
||||
buffer->MutableDataU(), buffer->StrideU(),
|
||||
buffer->MutableDataV(), buffer->StrideV(),
|
||||
width, height));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::Rotate(
|
||||
rtc::scoped_refptr<VideoFrameBuffer> src,
|
||||
VideoRotation rotation) {
|
||||
RTC_CHECK(src->DataY());
|
||||
RTC_CHECK(src->DataU());
|
||||
RTC_CHECK(src->DataV());
|
||||
|
||||
if (rotation == webrtc::kVideoRotation_0) {
|
||||
return src;
|
||||
}
|
||||
|
||||
int rotated_width = src->width();
|
||||
int rotated_height = src->height();
|
||||
if (rotation == webrtc::kVideoRotation_90 ||
|
||||
rotation == webrtc::kVideoRotation_270) {
|
||||
std::swap(rotated_width, rotated_height);
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::I420Buffer> buffer =
|
||||
I420Buffer::Create(rotated_width, rotated_height);
|
||||
|
||||
RTC_CHECK_EQ(0, libyuv::I420Rotate(
|
||||
src->DataY(), src->StrideY(),
|
||||
src->DataU(), src->StrideU(),
|
||||
src->DataV(), src->StrideV(),
|
||||
buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataU(),
|
||||
buffer->StrideU(), buffer->MutableDataV(), buffer->StrideV(),
|
||||
src->width(), src->height(),
|
||||
static_cast<libyuv::RotationMode>(rotation)));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void I420Buffer::InitializeData() {
|
||||
memset(data_.get(), 0,
|
||||
I420DataSize(height_, stride_y_, stride_u_, stride_v_));
|
||||
@ -126,23 +189,6 @@ rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::NativeToI420Buffer() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
|
||||
const VideoFrameBuffer& source) {
|
||||
int width = source.width();
|
||||
int height = source.height();
|
||||
rtc::scoped_refptr<I420Buffer> target = I420Buffer::Create(width, height);
|
||||
RTC_CHECK(libyuv::I420Copy(source.DataY(), source.StrideY(),
|
||||
source.DataU(), source.StrideU(),
|
||||
source.DataV(), source.StrideV(),
|
||||
target->MutableDataY(), target->StrideY(),
|
||||
target->MutableDataU(), target->StrideU(),
|
||||
target->MutableDataV(), target->StrideV(),
|
||||
width, height) == 0);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void I420Buffer::SetToBlack() {
|
||||
RTC_CHECK(libyuv::I420Rect(MutableDataY(), StrideY(),
|
||||
MutableDataU(), StrideU(),
|
||||
@ -205,41 +251,6 @@ void I420Buffer::ScaleFrom(const VideoFrameBuffer& src) {
|
||||
CropAndScaleFrom(src, 0, 0, src.width(), src.height());
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::Rotate(
|
||||
rtc::scoped_refptr<VideoFrameBuffer> src,
|
||||
VideoRotation rotation) {
|
||||
RTC_DCHECK(src->DataY());
|
||||
RTC_DCHECK(src->DataU());
|
||||
RTC_DCHECK(src->DataV());
|
||||
|
||||
if (rotation == webrtc::kVideoRotation_0) {
|
||||
return src;
|
||||
}
|
||||
|
||||
int rotated_width = src->width();
|
||||
int rotated_height = src->height();
|
||||
if (rotation == webrtc::kVideoRotation_90 ||
|
||||
rotation == webrtc::kVideoRotation_270) {
|
||||
std::swap(rotated_width, rotated_height);
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::I420Buffer> buffer =
|
||||
I420Buffer::Create(rotated_width, rotated_height);
|
||||
|
||||
int res = libyuv::I420Rotate(
|
||||
src->DataY(), src->StrideY(),
|
||||
src->DataU(), src->StrideU(),
|
||||
src->DataV(), src->StrideV(),
|
||||
buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataU(),
|
||||
buffer->StrideU(), buffer->MutableDataV(), buffer->StrideV(),
|
||||
src->width(), src->height(),
|
||||
static_cast<libyuv::RotationMode>(rotation));
|
||||
RTC_DCHECK_EQ(res, 0);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
NativeHandleBuffer::NativeHandleBuffer(void* native_handle,
|
||||
int width,
|
||||
int height)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user