Revert "Remove extra copy in VideoCaptureImpl::IncomingFrameI420"

This reverts commit 99f9743fe39066ba93b41f2b0a417696cbbd06fb.

Revert while build breakage is fixed.

BUG=None
TBR=niklas.emblom@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/3249004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5069 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
sheu@chromium.org 2013-10-31 21:20:15 +00:00
parent 1a4ed0d70c
commit d705649edf
11 changed files with 57 additions and 157 deletions

View File

@ -58,23 +58,6 @@ int I420VideoFrame::CreateFrame(int size_y, const uint8_t* buffer_y,
return 0; return 0;
} }
int I420VideoFrame::AliasBuffers(int size_y, uint8_t* buffer_y,
int size_u, uint8_t* buffer_u,
int size_v, uint8_t* buffer_v,
int width, int height,
int stride_y, int stride_u, int stride_v) {
if (size_y < 1 || size_u < 1 || size_v < 1)
return -1;
if (CheckDimensions(width, height, stride_y, stride_u, stride_v) < 0)
return -1;
y_plane_.Alias(size_y, stride_y, buffer_y);
u_plane_.Alias(size_u, stride_u, buffer_u);
v_plane_.Alias(size_v, stride_v, buffer_v);
width_ = width;
height_ = height;
return 0;
}
int I420VideoFrame::CopyFrame(const I420VideoFrame& videoFrame) { int I420VideoFrame::CopyFrame(const I420VideoFrame& videoFrame) {
int ret = CreateFrame(videoFrame.allocated_size(kYPlane), int ret = CreateFrame(videoFrame.allocated_size(kYPlane),
videoFrame.buffer(kYPlane), videoFrame.buffer(kYPlane),

View File

@ -118,7 +118,7 @@ TEST(TestI420VideoFrame, CopyFrame) {
EXPECT_TRUE(EqualFrames(frame1, frame2)); EXPECT_TRUE(EqualFrames(frame1, frame2));
} }
TEST(TestI420VideoFrame, CreateFrame) { TEST(TestI420VideoFrame, CopyBuffer) {
I420VideoFrame frame1, frame2; I420VideoFrame frame1, frame2;
int width = 15; int width = 15;
int height = 15; int height = 15;
@ -148,34 +148,6 @@ TEST(TestI420VideoFrame, CreateFrame) {
EXPECT_LE(kSizeUv, frame2.allocated_size(kVPlane)); EXPECT_LE(kSizeUv, frame2.allocated_size(kVPlane));
} }
TEST(TestI420VideoFrame, AliasBuffers) {
I420VideoFrame frame;
int width = 15;
int height = 15;
int stride_y = 15;
int stride_uv = 10;
const int kSizeY = 225;
const int kSizeUv = 80;
EXPECT_EQ(
0, frame.CreateEmptyFrame(width, height, stride_y, stride_uv, stride_uv));
uint8_t buffer_y[kSizeY];
uint8_t buffer_u[kSizeUv];
uint8_t buffer_v[kSizeUv];
memset(buffer_y, 16, kSizeY);
memset(buffer_u, 8, kSizeUv);
memset(buffer_v, 4, kSizeUv);
frame.AliasBuffers(kSizeY, buffer_y,
kSizeUv, buffer_u,
kSizeUv, buffer_v,
width, height, stride_y, stride_uv, stride_uv);
EXPECT_EQ(buffer_y, frame.buffer(kYPlane));
EXPECT_EQ(buffer_u, frame.buffer(kUPlane));
EXPECT_EQ(buffer_v, frame.buffer(kVPlane));
EXPECT_EQ(0, frame.allocated_size(kYPlane));
EXPECT_EQ(0, frame.allocated_size(kUPlane));
EXPECT_EQ(0, frame.allocated_size(kVPlane));
}
TEST(TestI420VideoFrame, FrameSwap) { TEST(TestI420VideoFrame, FrameSwap) {
I420VideoFrame frame1, frame2; I420VideoFrame frame1, frame2;
uint32_t timestamp1 = 1; uint32_t timestamp1 = 1;

View File

@ -62,15 +62,6 @@ class I420VideoFrame {
int width, int height, int width, int height,
int stride_y, int stride_u, int stride_v); int stride_y, int stride_u, int stride_v);
// AliasBuffers: Sets the frame's members and buffers from a set of buffers.
// The buffers are not copied, only the pointers, and the frame does not take
// ownership of the buffers (i.e.: the buffers must outlive the frame).
virtual int AliasBuffers(int size_y, uint8_t* buffer_y,
int size_u, uint8_t* buffer_u,
int size_v, uint8_t* buffer_v,
int width, int height,
int stride_y, int stride_u, int stride_v);
// Copy frame: If required size is bigger than allocated one, new buffers of // Copy frame: If required size is bigger than allocated one, new buffers of
// adequate size will be allocated. // adequate size will be allocated.
// Return value: 0 on success ,-1 on error. // Return value: 0 on success ,-1 on error.

View File

@ -48,17 +48,6 @@ class TextureVideoFrame : public I420VideoFrame {
int stride_y, int stride_y,
int stride_u, int stride_u,
int stride_v) OVERRIDE; int stride_v) OVERRIDE;
virtual int AliasBuffers(int size_y,
uint8_t* buffer_y,
int size_u,
uint8_t* buffer_u,
int size_v,
uint8_t* buffer_v,
int width,
int height,
int stride_y,
int stride_u,
int stride_v) OVERRIDE;
virtual int CopyFrame(const I420VideoFrame& videoFrame) OVERRIDE; virtual int CopyFrame(const I420VideoFrame& videoFrame) OVERRIDE;
virtual void SwapFrame(I420VideoFrame* videoFrame) OVERRIDE; virtual void SwapFrame(I420VideoFrame* videoFrame) OVERRIDE;
virtual uint8_t* buffer(PlaneType type) OVERRIDE; virtual uint8_t* buffer(PlaneType type) OVERRIDE;

View File

@ -17,75 +17,65 @@
namespace webrtc { namespace webrtc {
// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
static const size_t kBufferAlignment = 64; static const int kBufferAlignment = 64;
Plane::Plane() Plane::Plane()
: pointer_(NULL), : buffer_(NULL),
allocation_(NULL),
allocated_size_(0), allocated_size_(0),
plane_size_(0), plane_size_(0),
stride_(0) {} stride_(0) {}
Plane::~Plane() {} Plane::~Plane() {}
int Plane::CreateEmptyPlane(size_t allocated_size, int Plane::CreateEmptyPlane(int allocated_size, int stride, int plane_size) {
size_t stride,
size_t plane_size) {
if (allocated_size < 1 || stride < 1 || plane_size < 1) if (allocated_size < 1 || stride < 1 || plane_size < 1)
return -1; return -1;
stride_ = stride; stride_ = stride;
if (Reallocate(allocated_size) < 0) if (MaybeResize(allocated_size) < 0)
return -1; return -1;
plane_size_ = plane_size; plane_size_ = plane_size;
return 0; return 0;
} }
int Plane::Reallocate(size_t new_size) { int Plane::MaybeResize(int new_size) {
if (new_size <= 0) if (new_size <= 0)
return -1; return -1;
if (new_size <= allocated_size_) if (new_size <= allocated_size_)
return 0; return 0;
Allocator<uint8_t>::scoped_ptr_aligned new_buffer( Allocator<uint8_t>::scoped_ptr_aligned new_buffer(
AlignedMalloc<uint8_t>(new_size, kBufferAlignment)); AlignedMalloc<uint8_t>(new_size, kBufferAlignment));
allocation_.reset(new_buffer.release()); if (buffer_.get()) {
pointer_ = allocation_.get(); memcpy(new_buffer.get(), buffer_.get(), plane_size_);
}
buffer_.reset(new_buffer.release());
allocated_size_ = new_size; allocated_size_ = new_size;
return 0; return 0;
} }
int Plane::Copy(const Plane& plane) { int Plane::Copy(const Plane& plane) {
if (Reallocate(plane.allocated_size_) < 0) if (MaybeResize(plane.allocated_size_) < 0)
return -1; return -1;
if (plane.pointer_) if (plane.buffer_.get())
memcpy(pointer_, plane.pointer_, plane.plane_size_); memcpy(buffer_.get(), plane.buffer_.get(), plane.plane_size_);
stride_ = plane.stride_; stride_ = plane.stride_;
plane_size_ = plane.plane_size_; plane_size_ = plane.plane_size_;
return 0; return 0;
} }
int Plane::Copy(size_t size, size_t stride, const uint8_t* buffer) { int Plane::Copy(int size, int stride, const uint8_t* buffer) {
if (Reallocate(size) < 0) if (MaybeResize(size) < 0)
return -1; return -1;
memcpy(pointer_, buffer, size); memcpy(buffer_.get(), buffer, size);
plane_size_ = size; plane_size_ = size;
stride_ = stride; stride_ = stride;
return 0; return 0;
} }
void Plane::Alias(size_t size, size_t stride, uint8_t* buffer) {
allocation_.reset();
allocated_size_ = 0;
pointer_ = buffer;
stride_ = stride;
plane_size_ = size;
}
void Plane::Swap(Plane& plane) { void Plane::Swap(Plane& plane) {
std::swap(pointer_, plane.pointer_); std::swap(stride_, plane.stride_);
allocation_.swap(plane.allocation_);
std::swap(allocated_size_, plane.allocated_size_); std::swap(allocated_size_, plane.allocated_size_);
std::swap(plane_size_, plane.plane_size_); std::swap(plane_size_, plane.plane_size_);
std::swap(stride_, plane.stride_); buffer_.swap(plane.buffer_);
} }
} // namespace webrtc } // namespace webrtc

View File

@ -25,26 +25,23 @@ class Plane {
// CreateEmptyPlane - set allocated size, actual plane size and stride: // CreateEmptyPlane - set allocated size, actual plane size and stride:
// If current size is smaller than current size, then a buffer of sufficient // If current size is smaller than current size, then a buffer of sufficient
// size will be allocated. // size will be allocated.
// Return value: 0 on success, -1 on error. // Return value: 0 on success ,-1 on error.
int CreateEmptyPlane(size_t allocated_size, size_t stride, size_t plane_size); int CreateEmptyPlane(int allocated_size, int stride, int plane_size);
// Copy the entire plane data. // Copy the entire plane data.
// Return value: 0 on success, -1 on error. // Return value: 0 on success ,-1 on error.
int Copy(const Plane& plane); int Copy(const Plane& plane);
// Copy buffer: If current size is smaller // Copy buffer: If current size is smaller
// than current size, then a buffer of sufficient size will be allocated. // than current size, then a buffer of sufficient size will be allocated.
// Return value: 0 on success, -1 on error. // Return value: 0 on success ,-1 on error.
int Copy(size_t size, size_t stride, const uint8_t* buffer); int Copy(int size, int stride, const uint8_t* buffer);
// Make this plane refer to a memory buffer. Plane will not own buffer.
void Alias(size_t size, size_t stride, uint8_t* buffer);
// Swap plane data. // Swap plane data.
void Swap(Plane& plane); void Swap(Plane& plane);
// Get allocated size. // Get allocated size.
size_t allocated_size() const { return allocated_size_; } int allocated_size() const {return allocated_size_;}
// Set actual size. // Set actual size.
void ResetSize() {plane_size_ = 0;} void ResetSize() {plane_size_ = 0;}
@ -53,24 +50,23 @@ class Plane {
bool IsZeroSize() const {return plane_size_ == 0;} bool IsZeroSize() const {return plane_size_ == 0;}
// Get stride value. // Get stride value.
size_t stride() const { return stride_; } int stride() const {return stride_;}
// Return data pointer. // Return data pointer.
const uint8_t* buffer() const { return pointer_; } const uint8_t* buffer() const {return buffer_.get();}
// Overloading with non-const. // Overloading with non-const.
uint8_t* buffer() { return pointer_; } uint8_t* buffer() {return buffer_.get();}
private: private:
// Reallocate when needed: If current allocated size is less than new_size, // Resize when needed: If current allocated size is less than new_size, buffer
// buffer will be updated. In any case, old data becomes undefined. // will be updated. Old data will be copied to new buffer.
// Return value: 0 on success, -1 on error. // Return value: 0 on success ,-1 on error.
int Reallocate(size_t new_size); int MaybeResize(int new_size);
uint8_t* pointer_; Allocator<uint8_t>::scoped_ptr_aligned buffer_;
Allocator<uint8_t>::scoped_ptr_aligned allocation_; int allocated_size_;
size_t allocated_size_; int plane_size_;
size_t plane_size_; int stride_;
size_t stride_;
}; // Plane }; // Plane
} // namespace webrtc } // namespace webrtc

View File

@ -19,9 +19,9 @@ namespace webrtc {
TEST(TestPlane, CreateEmptyPlaneValues) { TEST(TestPlane, CreateEmptyPlaneValues) {
Plane plane; Plane plane;
size_t size, stride; int size, stride;
EXPECT_EQ(0U, plane.allocated_size()); EXPECT_EQ(0, plane.allocated_size());
EXPECT_EQ(0U, plane.stride()); EXPECT_EQ(0, plane.stride());
EXPECT_TRUE(plane.IsZeroSize()); EXPECT_TRUE(plane.IsZeroSize());
size = 0; size = 0;
stride = 20; stride = 20;
@ -40,8 +40,8 @@ TEST(TestPlane, CreateEmptyPlaneValues) {
TEST(TestPlane, ResetSize) { TEST(TestPlane, ResetSize) {
Plane plane; Plane plane;
EXPECT_TRUE(plane.IsZeroSize()); EXPECT_TRUE(plane.IsZeroSize());
size_t allocated_size, plane_size, stride; int allocated_size, plane_size, stride;
EXPECT_EQ(0U, plane.allocated_size()); EXPECT_EQ(0, plane.allocated_size());
allocated_size = 30; allocated_size = 30;
plane_size = 20; plane_size = 20;
stride = 10; stride = 10;
@ -56,11 +56,11 @@ TEST(TestPlane, PlaneCopy) {
Plane plane1, plane2; Plane plane1, plane2;
// Copy entire plane. // Copy entire plane.
plane1.CreateEmptyPlane(100, 10, 100); plane1.CreateEmptyPlane(100, 10, 100);
size_t size1 = plane1.allocated_size(); int size1 = plane1.allocated_size();
size_t size2 = 30; int size2 = 30;
plane2.CreateEmptyPlane(50, 15, size2); plane2.CreateEmptyPlane(50, 15, size2);
size_t stride1 = plane1.stride(); int stride1 = plane1.stride();
size_t stride2 = plane2.stride(); int stride2 = plane2.stride();
plane1.Copy(plane2); plane1.Copy(plane2);
// Smaller size - keep buffer size as is. // Smaller size - keep buffer size as is.
EXPECT_EQ(size1, plane1.allocated_size()); EXPECT_EQ(size1, plane1.allocated_size());
@ -78,18 +78,9 @@ TEST(TestPlane, PlaneCopy) {
EXPECT_EQ(0, memcmp(buffer1, plane2.buffer(), size1)); EXPECT_EQ(0, memcmp(buffer1, plane2.buffer(), size1));
} }
TEST(TestPlane, PlaneAlias) {
Plane plane;
plane.CreateEmptyPlane(100, 10, 100);
uint8_t buffer[256];
plane.Alias(sizeof(buffer), sizeof(buffer) / 16, buffer);
EXPECT_EQ(buffer, plane.buffer());
EXPECT_EQ(0U, plane.allocated_size());
}
TEST(TestPlane, PlaneSwap) { TEST(TestPlane, PlaneSwap) {
Plane plane1, plane2; Plane plane1, plane2;
size_t size1, size2, stride1, stride2; int size1, size2, stride1, stride2;
plane1.CreateEmptyPlane(100, 10, 100); plane1.CreateEmptyPlane(100, 10, 100);
plane2.CreateEmptyPlane(50, 15, 50); plane2.CreateEmptyPlane(50, 15, 50);
size1 = plane1.allocated_size(); size1 = plane1.allocated_size();

View File

@ -60,21 +60,6 @@ int TextureVideoFrame::CreateFrame(int size_y,
return -1; return -1;
} }
int TextureVideoFrame::AliasBuffers(int size_y,
uint8_t* buffer_y,
int size_u,
uint8_t* buffer_u,
int size_v,
uint8_t* buffer_v,
int width,
int height,
int stride_y,
int stride_u,
int stride_v) {
NOTREACHED();
return -1;
}
int TextureVideoFrame::CopyFrame(const I420VideoFrame& videoFrame) { int TextureVideoFrame::CopyFrame(const I420VideoFrame& videoFrame) {
NOTREACHED(); NOTREACHED();
return -1; return -1;

View File

@ -314,9 +314,10 @@ int32_t VideoCaptureImpl::IncomingFrame(
// Setting absolute height (in case it was negative). // Setting absolute height (in case it was negative).
// In Windows, the image starts bottom left, instead of top left. // In Windows, the image starts bottom left, instead of top left.
// Setting a negative source height, inverts the image (within LibYuv). // Setting a negative source height, inverts the image (within LibYuv).
I420VideoFrame captureFrame; int ret = _captureFrame.CreateEmptyFrame(target_width,
int ret = captureFrame.CreateEmptyFrame( abs(target_height),
target_width, abs(target_height), stride_y, stride_uv, stride_uv); stride_y,
stride_uv, stride_uv);
if (ret < 0) if (ret < 0)
{ {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
@ -329,7 +330,7 @@ int32_t VideoCaptureImpl::IncomingFrame(
width, height, width, height,
videoFrameLength, videoFrameLength,
_rotateFrame, _rotateFrame,
&captureFrame); &_captureFrame);
if (conversionResult < 0) if (conversionResult < 0)
{ {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
@ -337,7 +338,7 @@ int32_t VideoCaptureImpl::IncomingFrame(
frameInfo.rawType); frameInfo.rawType);
return -1; return -1;
} }
DeliverCapturedFrame(captureFrame, captureTime); DeliverCapturedFrame(_captureFrame, captureTime);
} }
else // Encoded format else // Encoded format
{ {
@ -364,8 +365,8 @@ int32_t VideoCaptureImpl::IncomingFrameI420(
int size_y = video_frame.height * video_frame.y_pitch; int size_y = video_frame.height * video_frame.y_pitch;
int size_u = video_frame.u_pitch * ((video_frame.height + 1) / 2); int size_u = video_frame.u_pitch * ((video_frame.height + 1) / 2);
int size_v = video_frame.v_pitch * ((video_frame.height + 1) / 2); int size_v = video_frame.v_pitch * ((video_frame.height + 1) / 2);
I420VideoFrame captureFrame; // TODO(mikhal): Can we use Swap here? This will do a memcpy.
int ret = captureFrame.AliasBuffers(size_y, video_frame.y_plane, int ret = _captureFrame.CreateFrame(size_y, video_frame.y_plane,
size_u, video_frame.u_plane, size_u, video_frame.u_plane,
size_v, video_frame.v_plane, size_v, video_frame.v_plane,
video_frame.width, video_frame.height, video_frame.width, video_frame.height,
@ -373,11 +374,11 @@ int32_t VideoCaptureImpl::IncomingFrameI420(
video_frame.v_pitch); video_frame.v_pitch);
if (ret < 0) { if (ret < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
"Failed to alias I420VideoFrame"); "Failed to create I420VideoFrame");
return -1; return -1;
} }
DeliverCapturedFrame(captureFrame, captureTime); DeliverCapturedFrame(_captureFrame, captureTime);
return 0; return 0;
} }

View File

@ -134,6 +134,7 @@ private:
TickTime _incomingFrameTimes[kFrameRateCountHistorySize];// timestamp for local captured frames TickTime _incomingFrameTimes[kFrameRateCountHistorySize];// timestamp for local captured frames
VideoRotationMode _rotateFrame; //Set if the frame should be rotated by the capture module. VideoRotationMode _rotateFrame; //Set if the frame should be rotated by the capture module.
I420VideoFrame _captureFrame;
VideoFrame _capture_encoded_frame; VideoFrame _capture_encoded_frame;
// Used to make sure incoming timestamp is increasing for every frame. // Used to make sure incoming timestamp is increasing for every frame.

View File

@ -18,6 +18,7 @@
#define WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_IMAGE_PROCESS_H_ #define WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_IMAGE_PROCESS_H_
#include "webrtc/common_types.h" #include "webrtc/common_types.h"
#include "webrtc/common_video/interface/i420_video_frame.h"
namespace webrtc { namespace webrtc {