Added new VideoFrameBuffer methods Data[YUV]() etc.
Eliminate most uses of the old methods. To continue on this path, once we agree the new methods make sense, the next step is to rename cricket::VideoFrame::GetVideoFrameBuffer --> video_frame_buffer, to match the name in webrtc::VideoFrame (if we think that name is ok?). And then start updating all code to access planes via the VideoFrameBuffer, and delete corresponding methods in both cricket::VideoFrame and webrtc::VideoFrame. BUG=webrtc:5682 Review URL: https://codereview.webrtc.org/1878623002 Cr-Commit-Position: refs/heads/master@{#12407}
This commit is contained in:
parent
d30a1117f8
commit
06176e49e2
@ -26,19 +26,28 @@ class PooledI420Buffer : public webrtc::VideoFrameBuffer {
|
||||
|
||||
int width() const override { return buffer_->width(); }
|
||||
int height() const override { return buffer_->height(); }
|
||||
const uint8_t* data(webrtc::PlaneType type) const override {
|
||||
return buffer_->data(type);
|
||||
}
|
||||
const uint8_t* DataY() const override { return buffer_->DataY(); }
|
||||
const uint8_t* DataU() const override { return buffer_->DataU(); }
|
||||
const uint8_t* DataV() const override { return buffer_->DataV(); }
|
||||
|
||||
bool IsMutable() { return HasOneRef(); }
|
||||
uint8_t* MutableData(webrtc::PlaneType type) override {
|
||||
// Make the HasOneRef() check here instead of in |buffer_|, because the pool
|
||||
// also has a reference to |buffer_|.
|
||||
// Make the IsMutable() check here instead of in |buffer_|, because the pool
|
||||
// also has a reference to |buffer_|.
|
||||
uint8_t* MutableDataY() override {
|
||||
RTC_DCHECK(IsMutable());
|
||||
return const_cast<uint8_t*>(buffer_->data(type));
|
||||
return const_cast<uint8_t*>(buffer_->DataY());
|
||||
}
|
||||
int stride(webrtc::PlaneType type) const override {
|
||||
return buffer_->stride(type);
|
||||
uint8_t* MutableDataU() override {
|
||||
RTC_DCHECK(IsMutable());
|
||||
return const_cast<uint8_t*>(buffer_->DataU());
|
||||
}
|
||||
uint8_t* MutableDataV() override {
|
||||
RTC_DCHECK(IsMutable());
|
||||
return const_cast<uint8_t*>(buffer_->DataV());
|
||||
}
|
||||
int StrideY() const override { return buffer_->StrideY(); }
|
||||
int StrideU() const override { return buffer_->StrideU(); }
|
||||
int StrideV() const override { return buffer_->StrideV(); }
|
||||
void* native_handle() const override { return nullptr; }
|
||||
|
||||
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override {
|
||||
|
||||
@ -21,16 +21,16 @@ TEST(TestI420BufferPool, SimpleFrameReuse) {
|
||||
EXPECT_EQ(16, buffer->width());
|
||||
EXPECT_EQ(16, buffer->height());
|
||||
// Extract non-refcounted pointers for testing.
|
||||
const uint8_t* y_ptr = buffer->data(kYPlane);
|
||||
const uint8_t* u_ptr = buffer->data(kUPlane);
|
||||
const uint8_t* v_ptr = buffer->data(kVPlane);
|
||||
const uint8_t* y_ptr = buffer->DataY();
|
||||
const uint8_t* u_ptr = buffer->DataU();
|
||||
const uint8_t* v_ptr = buffer->DataV();
|
||||
// Release buffer so that it is returned to the pool.
|
||||
buffer = nullptr;
|
||||
// Check that the memory is resued.
|
||||
buffer = pool.CreateBuffer(16, 16);
|
||||
EXPECT_EQ(y_ptr, buffer->data(kYPlane));
|
||||
EXPECT_EQ(u_ptr, buffer->data(kUPlane));
|
||||
EXPECT_EQ(v_ptr, buffer->data(kVPlane));
|
||||
EXPECT_EQ(y_ptr, buffer->DataY());
|
||||
EXPECT_EQ(u_ptr, buffer->DataU());
|
||||
EXPECT_EQ(v_ptr, buffer->DataV());
|
||||
EXPECT_EQ(16, buffer->width());
|
||||
EXPECT_EQ(16, buffer->height());
|
||||
}
|
||||
@ -39,16 +39,16 @@ TEST(TestI420BufferPool, FailToReuse) {
|
||||
I420BufferPool pool;
|
||||
rtc::scoped_refptr<VideoFrameBuffer> buffer = pool.CreateBuffer(16, 16);
|
||||
// Extract non-refcounted pointers for testing.
|
||||
const uint8_t* u_ptr = buffer->data(kUPlane);
|
||||
const uint8_t* v_ptr = buffer->data(kVPlane);
|
||||
const uint8_t* u_ptr = buffer->DataU();
|
||||
const uint8_t* v_ptr = buffer->DataV();
|
||||
// Release buffer so that it is returned to the pool.
|
||||
buffer = nullptr;
|
||||
// Check that the pool doesn't try to reuse buffers of incorrect size.
|
||||
buffer = pool.CreateBuffer(32, 16);
|
||||
EXPECT_EQ(32, buffer->width());
|
||||
EXPECT_EQ(16, buffer->height());
|
||||
EXPECT_NE(u_ptr, buffer->data(kUPlane));
|
||||
EXPECT_NE(v_ptr, buffer->data(kVPlane));
|
||||
EXPECT_NE(u_ptr, buffer->DataU());
|
||||
EXPECT_NE(v_ptr, buffer->DataV());
|
||||
}
|
||||
|
||||
TEST(TestI420BufferPool, ExclusiveOwner) {
|
||||
@ -68,7 +68,7 @@ TEST(TestI420BufferPool, FrameValidAfterPoolDestruction) {
|
||||
EXPECT_EQ(16, buffer->width());
|
||||
EXPECT_EQ(16, buffer->height());
|
||||
// Try to trigger use-after-free errors by writing to y-plane.
|
||||
memset(buffer->MutableData(kYPlane), 0xA5, 16 * buffer->stride(kYPlane));
|
||||
memset(buffer->MutableDataY(), 0xA5, 16 * buffer->StrideY());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -258,9 +258,9 @@ TEST(TestVideoFrame, TextureInitialValues) {
|
||||
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);
|
||||
memset(buf1->MutableDataY(), 1, 200);
|
||||
memset(buf1->MutableDataU(), 2, 50);
|
||||
memset(buf1->MutableDataV(), 3, 50);
|
||||
rtc::scoped_refptr<I420Buffer> buf2 = I420Buffer::Copy(buf1);
|
||||
EXPECT_TRUE(test::FrameBufsEqual(buf1, buf2));
|
||||
}
|
||||
|
||||
@ -50,16 +50,36 @@ class VideoFrameBuffer : public rtc::RefCountInterface {
|
||||
virtual int width() const = 0;
|
||||
virtual int height() const = 0;
|
||||
|
||||
// TODO(nisse): For the transition, we use default implementations
|
||||
// of the stride and data methods where the new methods calls the
|
||||
// old method, and the old method calls the new methods. Subclasses
|
||||
// must override either the new methods or the old method, to break
|
||||
// infinite recursion. And similarly for the strides. When
|
||||
// applications, in particular Chrome, are updated, delete the old
|
||||
// method and delete the default implementation of the new methods.
|
||||
|
||||
// Returns pointer to the pixel data for a given plane. The memory is owned by
|
||||
// the VideoFrameBuffer object and must not be freed by the caller.
|
||||
virtual const uint8_t* data(PlaneType type) const = 0;
|
||||
virtual const uint8_t* DataY() const;
|
||||
virtual const uint8_t* DataU() const;
|
||||
virtual const uint8_t* DataV() const;
|
||||
// Deprecated method.
|
||||
// TODO(nisse): Delete after all users are updated.
|
||||
virtual const uint8_t* data(PlaneType type) const;
|
||||
|
||||
// Non-const data access is disallowed by default. You need to make sure you
|
||||
// have exclusive access and a writable buffer before calling this function.
|
||||
// Non-const data access is allowed only if HasOneRef() is true.
|
||||
virtual uint8_t* MutableDataY();
|
||||
virtual uint8_t* MutableDataU();
|
||||
virtual uint8_t* MutableDataV();
|
||||
// Deprecated method. TODO(nisse): Delete after all users are updated.
|
||||
virtual uint8_t* MutableData(PlaneType type);
|
||||
|
||||
// Returns the number of bytes between successive rows for a given plane.
|
||||
virtual int stride(PlaneType type) const = 0;
|
||||
virtual int StrideY() const;
|
||||
virtual int StrideU() const;
|
||||
virtual int StrideV() const;
|
||||
// Deprecated method. TODO(nisse): Delete after all users are updated.
|
||||
virtual int stride(PlaneType type) const;
|
||||
|
||||
// Return the handle of the underlying video frame. This is used when the
|
||||
// frame is backed by a texture.
|
||||
@ -82,12 +102,19 @@ class I420Buffer : public VideoFrameBuffer {
|
||||
|
||||
int width() const override;
|
||||
int height() const override;
|
||||
const uint8_t* data(PlaneType type) const override;
|
||||
// Non-const data access is only allowed if HasOneRef() is true to protect
|
||||
const uint8_t* DataY() const override;
|
||||
const uint8_t* DataU() const override;
|
||||
const uint8_t* DataV() const override;
|
||||
// Non-const data access is only allowed if IsMutable() is true, to protect
|
||||
// against unexpected overwrites.
|
||||
bool IsMutable() override;
|
||||
uint8_t* MutableData(PlaneType type) override;
|
||||
int stride(PlaneType type) const override;
|
||||
uint8_t* MutableDataY() override;
|
||||
uint8_t* MutableDataU() override;
|
||||
uint8_t* MutableDataV() override;
|
||||
int StrideY() const override;
|
||||
int StrideU() const override;
|
||||
int StrideV() const override;
|
||||
|
||||
void* native_handle() const override;
|
||||
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override;
|
||||
|
||||
@ -117,8 +144,13 @@ class NativeHandleBuffer : public VideoFrameBuffer {
|
||||
|
||||
int width() const override;
|
||||
int height() const override;
|
||||
const uint8_t* data(PlaneType type) const override;
|
||||
int stride(PlaneType type) const override;
|
||||
const uint8_t* DataY() const override;
|
||||
const uint8_t* DataU() const override;
|
||||
const uint8_t* DataV() const override;
|
||||
int StrideY() const override;
|
||||
int StrideU() const override;
|
||||
int StrideV() const override;
|
||||
|
||||
void* native_handle() const override;
|
||||
bool IsMutable() override;
|
||||
|
||||
@ -144,9 +176,13 @@ class WrappedI420Buffer : public webrtc::VideoFrameBuffer {
|
||||
|
||||
bool IsMutable() override;
|
||||
|
||||
const uint8_t* data(PlaneType type) const override;
|
||||
const uint8_t* DataY() const override;
|
||||
const uint8_t* DataU() const override;
|
||||
const uint8_t* DataV() const override;
|
||||
int StrideY() const override;
|
||||
int StrideU() const override;
|
||||
int StrideV() const override;
|
||||
|
||||
int stride(PlaneType type) const override;
|
||||
void* native_handle() const override;
|
||||
|
||||
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override;
|
||||
|
||||
@ -27,10 +27,80 @@ int I420DataSize(int height, int stride_y, int stride_u, int stride_v) {
|
||||
|
||||
} // namespace
|
||||
|
||||
uint8_t* VideoFrameBuffer::MutableData(PlaneType type) {
|
||||
const uint8_t* VideoFrameBuffer::data(PlaneType type) const {
|
||||
switch (type) {
|
||||
case kYPlane:
|
||||
return DataY();
|
||||
case kUPlane:
|
||||
return DataU();
|
||||
case kVPlane:
|
||||
return DataV();
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t* VideoFrameBuffer::DataY() const {
|
||||
return data(kYPlane);
|
||||
}
|
||||
const uint8_t* VideoFrameBuffer::DataU() const {
|
||||
return data(kUPlane);
|
||||
}
|
||||
const uint8_t* VideoFrameBuffer::DataV() const {
|
||||
return data(kVPlane);
|
||||
}
|
||||
|
||||
int VideoFrameBuffer::stride(PlaneType type) const {
|
||||
switch (type) {
|
||||
case kYPlane:
|
||||
return StrideY();
|
||||
case kUPlane:
|
||||
return StrideU();
|
||||
case kVPlane:
|
||||
return StrideV();
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int VideoFrameBuffer::StrideY() const {
|
||||
return stride(kYPlane);
|
||||
}
|
||||
int VideoFrameBuffer::StrideU() const {
|
||||
return stride(kUPlane);
|
||||
}
|
||||
int VideoFrameBuffer::StrideV() const {
|
||||
return stride(kVPlane);
|
||||
}
|
||||
|
||||
uint8_t* VideoFrameBuffer::MutableDataY() {
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t* VideoFrameBuffer::MutableDataU() {
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t* VideoFrameBuffer::MutableDataV() {
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint8_t* VideoFrameBuffer::MutableData(PlaneType type) {
|
||||
switch (type) {
|
||||
case kYPlane:
|
||||
return MutableDataY();
|
||||
case kUPlane:
|
||||
return MutableDataU();
|
||||
case kVPlane:
|
||||
return MutableDataV();
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
VideoFrameBuffer::~VideoFrameBuffer() {}
|
||||
|
||||
@ -74,43 +144,41 @@ int I420Buffer::height() const {
|
||||
return height_;
|
||||
}
|
||||
|
||||
const uint8_t* I420Buffer::data(PlaneType type) const {
|
||||
switch (type) {
|
||||
case kYPlane:
|
||||
return data_.get();
|
||||
case kUPlane:
|
||||
return data_.get() + stride_y_ * height_;
|
||||
case kVPlane:
|
||||
return data_.get() + stride_y_ * height_ +
|
||||
stride_u_ * ((height_ + 1) / 2);
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
const uint8_t* I420Buffer::DataY() const {
|
||||
return data_.get();
|
||||
}
|
||||
const uint8_t* I420Buffer::DataU() const {
|
||||
return data_.get() + stride_y_ * height_;
|
||||
}
|
||||
const uint8_t* I420Buffer::DataV() const {
|
||||
return data_.get() + stride_y_ * height_ + stride_u_ * ((height_ + 1) / 2);
|
||||
}
|
||||
|
||||
bool I420Buffer::IsMutable() {
|
||||
return HasOneRef();
|
||||
}
|
||||
|
||||
uint8_t* I420Buffer::MutableData(PlaneType type) {
|
||||
uint8_t* I420Buffer::MutableDataY() {
|
||||
RTC_DCHECK(IsMutable());
|
||||
return const_cast<uint8_t*>(
|
||||
static_cast<const VideoFrameBuffer*>(this)->data(type));
|
||||
return const_cast<uint8_t*>(DataY());
|
||||
}
|
||||
uint8_t* I420Buffer::MutableDataU() {
|
||||
RTC_DCHECK(IsMutable());
|
||||
return const_cast<uint8_t*>(DataU());
|
||||
}
|
||||
uint8_t* I420Buffer::MutableDataV() {
|
||||
RTC_DCHECK(IsMutable());
|
||||
return const_cast<uint8_t*>(DataV());
|
||||
}
|
||||
|
||||
int I420Buffer::stride(PlaneType type) const {
|
||||
switch (type) {
|
||||
case kYPlane:
|
||||
return stride_y_;
|
||||
case kUPlane:
|
||||
return stride_u_;
|
||||
case kVPlane:
|
||||
return stride_v_;
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
int I420Buffer::StrideY() const {
|
||||
return stride_y_;
|
||||
}
|
||||
int I420Buffer::StrideU() const {
|
||||
return stride_u_;
|
||||
}
|
||||
int I420Buffer::StrideV() const {
|
||||
return stride_v_;
|
||||
}
|
||||
|
||||
void* I420Buffer::native_handle() const {
|
||||
@ -128,12 +196,12 @@ rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
|
||||
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),
|
||||
RTC_CHECK(libyuv::I420Copy(buffer->DataY(), buffer->StrideY(),
|
||||
buffer->DataU(), buffer->StrideU(),
|
||||
buffer->DataV(), buffer->StrideV(),
|
||||
copy->MutableDataY(), copy->StrideY(),
|
||||
copy->MutableDataU(), copy->StrideU(),
|
||||
copy->MutableDataV(), copy->StrideV(),
|
||||
width, height) == 0);
|
||||
|
||||
return copy;
|
||||
@ -160,12 +228,28 @@ int NativeHandleBuffer::height() const {
|
||||
return height_;
|
||||
}
|
||||
|
||||
const uint8_t* NativeHandleBuffer::data(PlaneType type) const {
|
||||
const uint8_t* NativeHandleBuffer::DataY() const {
|
||||
RTC_NOTREACHED(); // Should not be called.
|
||||
return nullptr;
|
||||
}
|
||||
const uint8_t* NativeHandleBuffer::DataU() const {
|
||||
RTC_NOTREACHED(); // Should not be called.
|
||||
return nullptr;
|
||||
}
|
||||
const uint8_t* NativeHandleBuffer::DataV() const {
|
||||
RTC_NOTREACHED(); // Should not be called.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int NativeHandleBuffer::stride(PlaneType type) const {
|
||||
int NativeHandleBuffer::StrideY() const {
|
||||
RTC_NOTREACHED(); // Should not be called.
|
||||
return 0;
|
||||
}
|
||||
int NativeHandleBuffer::StrideU() const {
|
||||
RTC_NOTREACHED(); // Should not be called.
|
||||
return 0;
|
||||
}
|
||||
int NativeHandleBuffer::StrideV() const {
|
||||
RTC_NOTREACHED(); // Should not be called.
|
||||
return 0;
|
||||
}
|
||||
@ -211,32 +295,24 @@ int WrappedI420Buffer::height() const {
|
||||
return height_;
|
||||
}
|
||||
|
||||
const uint8_t* WrappedI420Buffer::data(PlaneType type) const {
|
||||
switch (type) {
|
||||
case kYPlane:
|
||||
return y_plane_;
|
||||
case kUPlane:
|
||||
return u_plane_;
|
||||
case kVPlane:
|
||||
return v_plane_;
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
const uint8_t* WrappedI420Buffer::DataY() const {
|
||||
return y_plane_;
|
||||
}
|
||||
const uint8_t* WrappedI420Buffer::DataU() const {
|
||||
return u_plane_;
|
||||
}
|
||||
const uint8_t* WrappedI420Buffer::DataV() const {
|
||||
return v_plane_;
|
||||
}
|
||||
|
||||
int WrappedI420Buffer::stride(PlaneType type) const {
|
||||
switch (type) {
|
||||
case kYPlane:
|
||||
return y_stride_;
|
||||
case kUPlane:
|
||||
return u_stride_;
|
||||
case kVPlane:
|
||||
return v_stride_;
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
int WrappedI420Buffer::StrideY() const {
|
||||
return y_stride_;
|
||||
}
|
||||
int WrappedI420Buffer::StrideU() const {
|
||||
return u_stride_;
|
||||
}
|
||||
int WrappedI420Buffer::StrideV() const {
|
||||
return v_stride_;
|
||||
}
|
||||
|
||||
void* WrappedI420Buffer::native_handle() const {
|
||||
@ -265,17 +341,17 @@ rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop(
|
||||
const int offset_x = uv_offset_x * 2;
|
||||
const int offset_y = uv_offset_y * 2;
|
||||
|
||||
const uint8_t* y_plane = buffer->data(kYPlane) +
|
||||
buffer->stride(kYPlane) * offset_y + offset_x;
|
||||
const uint8_t* u_plane = buffer->data(kUPlane) +
|
||||
buffer->stride(kUPlane) * uv_offset_y + uv_offset_x;
|
||||
const uint8_t* v_plane = buffer->data(kVPlane) +
|
||||
buffer->stride(kVPlane) * uv_offset_y + uv_offset_x;
|
||||
const uint8_t* y_plane = buffer->DataY() +
|
||||
buffer->StrideY() * offset_y + offset_x;
|
||||
const uint8_t* u_plane = buffer->DataU() +
|
||||
buffer->StrideU() * uv_offset_y + uv_offset_x;
|
||||
const uint8_t* v_plane = buffer->DataV() +
|
||||
buffer->StrideV() * uv_offset_y + uv_offset_x;
|
||||
return new rtc::RefCountedObject<WrappedI420Buffer>(
|
||||
cropped_width, cropped_height,
|
||||
y_plane, buffer->stride(kYPlane),
|
||||
u_plane, buffer->stride(kUPlane),
|
||||
v_plane, buffer->stride(kVPlane),
|
||||
y_plane, buffer->StrideY(),
|
||||
u_plane, buffer->StrideU(),
|
||||
v_plane, buffer->StrideV(),
|
||||
rtc::KeepRefUntilDone(buffer));
|
||||
}
|
||||
|
||||
|
||||
@ -80,15 +80,15 @@ int WebRtcVideoFrame::height() const {
|
||||
}
|
||||
|
||||
const uint8_t* WebRtcVideoFrame::GetYPlane() const {
|
||||
return video_frame_buffer_ ? video_frame_buffer_->data(kYPlane) : nullptr;
|
||||
return video_frame_buffer_ ? video_frame_buffer_->DataY() : nullptr;
|
||||
}
|
||||
|
||||
const uint8_t* WebRtcVideoFrame::GetUPlane() const {
|
||||
return video_frame_buffer_ ? video_frame_buffer_->data(kUPlane) : nullptr;
|
||||
return video_frame_buffer_ ? video_frame_buffer_->DataU() : nullptr;
|
||||
}
|
||||
|
||||
const uint8_t* WebRtcVideoFrame::GetVPlane() const {
|
||||
return video_frame_buffer_ ? video_frame_buffer_->data(kVPlane) : nullptr;
|
||||
return video_frame_buffer_ ? video_frame_buffer_->DataV() : nullptr;
|
||||
}
|
||||
|
||||
uint8_t* WebRtcVideoFrame::GetYPlane() {
|
||||
@ -107,15 +107,15 @@ uint8_t* WebRtcVideoFrame::GetVPlane() {
|
||||
}
|
||||
|
||||
int32_t WebRtcVideoFrame::GetYPitch() const {
|
||||
return video_frame_buffer_ ? video_frame_buffer_->stride(kYPlane) : 0;
|
||||
return video_frame_buffer_ ? video_frame_buffer_->StrideY() : 0;
|
||||
}
|
||||
|
||||
int32_t WebRtcVideoFrame::GetUPitch() const {
|
||||
return video_frame_buffer_ ? video_frame_buffer_->stride(kUPlane) : 0;
|
||||
return video_frame_buffer_ ? video_frame_buffer_->StrideU() : 0;
|
||||
}
|
||||
|
||||
int32_t WebRtcVideoFrame::GetVPitch() const {
|
||||
return video_frame_buffer_ ? video_frame_buffer_->stride(kVPlane) : 0;
|
||||
return video_frame_buffer_ ? video_frame_buffer_->StrideV() : 0;
|
||||
}
|
||||
|
||||
bool WebRtcVideoFrame::IsExclusive() const {
|
||||
|
||||
@ -42,9 +42,9 @@ class FakeNativeHandleBuffer : public NativeHandleBuffer {
|
||||
new rtc::RefCountedObject<I420Buffer>(width_, height_));
|
||||
int half_height = (height_ + 1) / 2;
|
||||
int half_width = (width_ + 1) / 2;
|
||||
memset(buffer->MutableData(kYPlane), 0, height_ * width_);
|
||||
memset(buffer->MutableData(kUPlane), 0, half_height * half_width);
|
||||
memset(buffer->MutableData(kVPlane), 0, half_height * half_width);
|
||||
memset(buffer->MutableDataY(), 0, height_ * width_);
|
||||
memset(buffer->MutableDataU(), 0, half_height * half_width);
|
||||
memset(buffer->MutableDataV(), 0, half_height * half_width);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
@ -61,14 +61,14 @@ bool FrameBufsEqual(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& f1,
|
||||
}
|
||||
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), f2->stride(webrtc::kYPlane),
|
||||
return EqualPlane(f1->DataY(), f2->DataY(),
|
||||
f1->StrideY(), f2->StrideY(),
|
||||
f1->width(), f1->height()) &&
|
||||
EqualPlane(f1->data(webrtc::kUPlane), f2->data(webrtc::kUPlane),
|
||||
f1->stride(webrtc::kUPlane), f2->stride(webrtc::kUPlane),
|
||||
EqualPlane(f1->DataU(), f2->DataU(),
|
||||
f1->StrideU(), f2->StrideU(),
|
||||
half_width, half_height) &&
|
||||
EqualPlane(f1->data(webrtc::kVPlane), f2->data(webrtc::kVPlane),
|
||||
f1->stride(webrtc::kVPlane), f2->stride(webrtc::kVPlane),
|
||||
EqualPlane(f1->DataV(), f2->DataV(),
|
||||
f1->StrideV(), f2->StrideV(),
|
||||
half_width, half_height);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user