Reland "Fix CVO in androidvideocapturer".

This cl was originally revieved in https://webrtc-codereview.appspot.com/40759004/

Patchset 2 adds a unittest for VideoFrame::Reset with and without the apply_rotation flag set.

BUG=4145
R=pthatcher@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#8564}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8564 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
perkj@webrtc.org
2015-03-03 06:44:06 +00:00
parent c9ce07ed87
commit 1d82813961
7 changed files with 91 additions and 35 deletions

View File

@@ -85,7 +85,7 @@ class AndroidVideoCapturer::FrameFactory : public cricket::VideoFrameFactory {
// Check that captured_frame is actually our frame.
DCHECK(captured_frame == &captured_frame_);
scoped_ptr<WebRtcVideoFrame> frame(new WebRtcVideoFrame());
frame->Init(captured_frame, dst_width, dst_height);
frame->Init(captured_frame, dst_width, dst_height, apply_rotation_);
return frame.release();
}

View File

@@ -100,7 +100,7 @@ class VideoAdapterTest : public testing::Test {
const CapturedFrame* captured_frame) {
WebRtcVideoFrame temp_i420;
EXPECT_TRUE(temp_i420.Init(captured_frame,
captured_frame->width, abs(captured_frame->height)));
captured_frame->width, abs(captured_frame->height), true));
VideoFrame* out_frame = NULL;
rtc::CritScope lock(&crit_);
EXPECT_TRUE(video_adapter_->AdaptFrame(&temp_i420, &out_frame));

View File

@@ -62,7 +62,8 @@ class VideoFrame {
size_t pixel_height,
int64_t elapsed_time,
int64_t time_stamp,
webrtc::VideoRotation rotation) {
webrtc::VideoRotation rotation,
bool apply_rotation) {
return false;
}
@@ -80,7 +81,7 @@ class VideoFrame {
int rotation) {
return Reset(fourcc, w, h, dw, dh, sample, sample_size, pixel_width,
pixel_height, elapsed_time, time_stamp,
static_cast<webrtc::VideoRotation>(rotation));
static_cast<webrtc::VideoRotation>(rotation), true);
}
// Basic accessors.
@@ -123,8 +124,6 @@ class VideoFrame {
virtual webrtc::VideoRotation GetVideoRotation() const {
return webrtc::kVideoRotation_0;
}
// TODO(guoweis): Remove the skeleton implementation once chrome is updated.
virtual void SetRotation(webrtc::VideoRotation rotation) {}
// Make a shallow copy of the frame. The frame buffer itself is not copied.
// Both the current and new VideoFrame will share a single reference-counted

View File

@@ -1415,7 +1415,7 @@ class VideoFrameTest : public testing::Test {
}
// Tests re-initing an existing image.
void Reset() {
void Reset(webrtc::VideoRotation rotation, bool apply_rotation) {
T frame1, frame2;
rtc::scoped_ptr<rtc::MemoryStream> ms(
LoadSample(kImageFilename));
@@ -1428,11 +1428,34 @@ class VideoFrameTest : public testing::Test {
EXPECT_TRUE(IsEqual(frame1, frame2, 0));
EXPECT_TRUE(frame1.Reset(cricket::FOURCC_I420, kWidth, kHeight, kWidth,
kHeight, reinterpret_cast<uint8*>(ms->GetBuffer()),
data_size, 1, 1, 0, 0, webrtc::kVideoRotation_0));
data_size, 1, 1, 0, 0, rotation,
apply_rotation));
if (apply_rotation)
EXPECT_EQ(webrtc::kVideoRotation_0, frame1.GetVideoRotation());
else
EXPECT_EQ(rotation, frame1.GetVideoRotation());
// Swapp width and height if the frame is rotated 90 or 270 degrees.
if (apply_rotation && (rotation == webrtc::kVideoRotation_90
|| rotation == webrtc::kVideoRotation_270)) {
EXPECT_TRUE(kHeight == frame1.GetWidth());
EXPECT_TRUE(kWidth == frame1.GetHeight());
} else {
EXPECT_TRUE(kWidth == frame1.GetWidth());
EXPECT_TRUE(kHeight == frame1.GetHeight());
}
EXPECT_FALSE(IsBlack(frame1));
EXPECT_FALSE(IsEqual(frame1, frame2, 0));
}
void ResetAndApplyRotation() {
Reset(webrtc::kVideoRotation_90, true);
}
void ResetAndDontApplyRotation() {
Reset(webrtc::kVideoRotation_90, false);
}
//////////////////////
// Conversion tests //
//////////////////////

View File

@@ -112,7 +112,8 @@ const webrtc::VideoFrame* WebRtcVideoFrame::FrameBuffer::frame() const {
}
WebRtcVideoFrame::WebRtcVideoFrame()
: video_buffer_(new RefCountedBuffer()) {}
: video_buffer_(new RefCountedBuffer()),
rotation_(webrtc::kVideoRotation_0) {}
WebRtcVideoFrame::~WebRtcVideoFrame() {}
@@ -129,14 +130,18 @@ bool WebRtcVideoFrame::Init(uint32 format,
int64_t time_stamp,
webrtc::VideoRotation rotation) {
return Reset(format, w, h, dw, dh, sample, sample_size, pixel_width,
pixel_height, elapsed_time, time_stamp, rotation);
pixel_height, elapsed_time, time_stamp, rotation,
true /*apply_rotation*/);
}
bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh) {
bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh,
bool apply_rotation) {
return Reset(frame->fourcc, frame->width, frame->height, dw, dh,
static_cast<uint8*>(frame->data), frame->data_size,
frame->pixel_width, frame->pixel_height, frame->elapsed_time,
frame->time_stamp, frame->GetRotation());
frame->time_stamp,
frame->GetRotation(),
apply_rotation);
}
bool WebRtcVideoFrame::Alias(const CapturedFrame* frame,
@@ -148,7 +153,7 @@ bool WebRtcVideoFrame::Alias(const CapturedFrame* frame,
frame->GetRotation() != webrtc::kVideoRotation_0) ||
frame->width != dw || frame->height != dh) {
// TODO(fbarchard): Enable aliasing of more formats.
return Init(frame, dw, dh);
return Init(frame, dw, dh, apply_rotation);
} else {
Alias(static_cast<uint8*>(frame->data), frame->data_size, frame->width,
frame->height, frame->pixel_width, frame->pixel_height,
@@ -310,7 +315,8 @@ bool WebRtcVideoFrame::Reset(uint32 format,
size_t pixel_height,
int64_t elapsed_time,
int64_t time_stamp,
webrtc::VideoRotation rotation) {
webrtc::VideoRotation rotation,
bool apply_rotation) {
if (!Validate(format, w, h, sample, sample_size)) {
return false;
}
@@ -327,7 +333,8 @@ bool WebRtcVideoFrame::Reset(uint32 format,
// TODO(fbarchard): Support lazy allocation.
int new_width = dw;
int new_height = dh;
if (rotation == 90 || rotation == 270) { // If rotated swap width, height.
// If rotated swap width, height.
if (apply_rotation && (rotation == 90 || rotation == 270)) {
new_width = dh;
new_height = dw;
}
@@ -341,7 +348,8 @@ bool WebRtcVideoFrame::Reset(uint32 format,
// Since the libyuv::ConvertToI420 will handle the rotation, so the
// new frame's rotation should always be 0.
Attach(video_buffer.get(), desired_size, new_width, new_height, pixel_width,
pixel_height, elapsed_time, time_stamp, webrtc::kVideoRotation_0);
pixel_height, elapsed_time, time_stamp,
apply_rotation ? webrtc::kVideoRotation_0 : rotation);
}
int horiz_crop = ((w - dw) / 2) & ~1;
@@ -358,7 +366,9 @@ bool WebRtcVideoFrame::Reset(uint32 format,
int v_stride = GetVPitch();
int r = libyuv::ConvertToI420(
sample, sample_size, y, y_stride, u, u_stride, v, v_stride, horiz_crop,
vert_crop, w, h, dw, idh, static_cast<libyuv::RotationMode>(rotation),
vert_crop, w, h, dw, idh,
static_cast<libyuv::RotationMode>(
apply_rotation ? rotation : webrtc::kVideoRotation_0),
format);
if (r) {
LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format)
@@ -415,7 +425,8 @@ bool WebRtcVideoRenderFrame::Reset(uint32 fourcc,
size_t pixel_height,
int64_t elapsed_time,
int64_t time_stamp,
webrtc::VideoRotation rotation) {
webrtc::VideoRotation rotation,
bool apply_rotation) {
UNIMPLEMENTED;
return false;
}

View File

@@ -65,7 +65,7 @@ class WebRtcVideoFrame : public VideoFrame {
int64_t time_stamp,
webrtc::VideoRotation rotation);
bool Init(const CapturedFrame* frame, int dw, int dh);
bool Init(const CapturedFrame* frame, int dw, int dh, bool apply_rotation);
void InitToEmptyBuffer(int w, int h, size_t pixel_width, size_t pixel_height,
int64_t elapsed_time, int64_t time_stamp);
@@ -107,7 +107,8 @@ class WebRtcVideoFrame : public VideoFrame {
size_t pixel_height,
int64_t elapsed_time,
int64_t time_stamp,
webrtc::VideoRotation rotation);
webrtc::VideoRotation rotation,
bool apply_rotation);
virtual size_t GetWidth() const;
virtual size_t GetHeight() const;
@@ -132,9 +133,6 @@ class WebRtcVideoFrame : public VideoFrame {
virtual void SetTimeStamp(int64_t time_stamp) { time_stamp_ = time_stamp; }
virtual webrtc::VideoRotation GetVideoRotation() const { return rotation_; }
virtual void SetRotation(webrtc::VideoRotation rotation) {
rotation_ = rotation;
}
virtual VideoFrame* Copy() const;
virtual bool IsExclusive() const;
@@ -195,7 +193,8 @@ class WebRtcVideoRenderFrame : public VideoFrame {
size_t pixel_height,
int64_t elapsed_time,
int64_t time_stamp,
webrtc::VideoRotation rotation) OVERRIDE;
webrtc::VideoRotation rotation,
bool apply_rotation) OVERRIDE;
virtual size_t GetWidth() const OVERRIDE;
virtual size_t GetHeight() const OVERRIDE;
virtual const uint8* GetYPlane() const OVERRIDE;

View File

@@ -33,7 +33,9 @@ class WebRtcVideoFrameTest : public VideoFrameTest<cricket::WebRtcVideoFrame> {
WebRtcVideoFrameTest() {
}
void TestInit(int cropped_width, int cropped_height) {
void TestInit(int cropped_width, int cropped_height,
webrtc::VideoRotation frame_rotation,
bool apply_rotation) {
const int frame_width = 1920;
const int frame_height = 1080;
@@ -44,7 +46,7 @@ class WebRtcVideoFrameTest : public VideoFrameTest<cricket::WebRtcVideoFrame> {
captured_frame.pixel_height = 1;
captured_frame.elapsed_time = 1234;
captured_frame.time_stamp = 5678;
captured_frame.rotation = webrtc::kVideoRotation_0;
captured_frame.rotation = frame_rotation;
captured_frame.width = frame_width;
captured_frame.height = frame_height;
captured_frame.data_size = (frame_width * frame_height) +
@@ -55,17 +57,30 @@ class WebRtcVideoFrameTest : public VideoFrameTest<cricket::WebRtcVideoFrame> {
// Create the new frame from the CapturedFrame.
cricket::WebRtcVideoFrame frame;
EXPECT_TRUE(frame.Init(&captured_frame, cropped_width, cropped_height));
EXPECT_TRUE(
frame.Init(&captured_frame, cropped_width, cropped_height,
apply_rotation));
// Verify the new frame.
EXPECT_EQ(1u, frame.GetPixelWidth());
EXPECT_EQ(1u, frame.GetPixelHeight());
EXPECT_EQ(1234, frame.GetElapsedTime());
EXPECT_EQ(5678, frame.GetTimeStamp());
EXPECT_EQ(webrtc::kVideoRotation_0, frame.GetRotation());
if (apply_rotation)
EXPECT_EQ(webrtc::kVideoRotation_0, frame.GetRotation());
else
EXPECT_EQ(frame_rotation, frame.GetRotation());
// The size of the new frame should have been cropped to multiple of 4.
EXPECT_EQ(static_cast<size_t>(cropped_width & ~3), frame.GetWidth());
EXPECT_EQ(static_cast<size_t>(cropped_height & ~3), frame.GetHeight());
// If |apply_rotation| and the frame rotation is 90 or 270, width and
// height are flipped.
if (apply_rotation && (frame_rotation == webrtc::kVideoRotation_90
|| frame_rotation == webrtc::kVideoRotation_270)) {
EXPECT_EQ(static_cast<size_t>(cropped_width & ~3), frame.GetHeight());
EXPECT_EQ(static_cast<size_t>(cropped_height & ~3), frame.GetWidth() );
} else {
EXPECT_EQ(static_cast<size_t>(cropped_width & ~3), frame.GetWidth());
EXPECT_EQ(static_cast<size_t>(cropped_height & ~3), frame.GetHeight());
}
}
};
@@ -152,7 +167,8 @@ TEST_WEBRTCVIDEOFRAME(ValidateI420HugeSize)
// Re-evaluate once WebRTC switches to libyuv
// TEST_WEBRTCVIDEOFRAME(ConstructYuy2AllSizes)
// TEST_WEBRTCVIDEOFRAME(ConstructARGBAllSizes)
TEST_WEBRTCVIDEOFRAME(Reset)
TEST_WEBRTCVIDEOFRAME(ResetAndApplyRotation)
TEST_WEBRTCVIDEOFRAME(ResetAndDontApplyRotation)
TEST_WEBRTCVIDEOFRAME(ConvertToABGRBuffer)
TEST_WEBRTCVIDEOFRAME(ConvertToABGRBufferStride)
TEST_WEBRTCVIDEOFRAME(ConvertToABGRBufferInverted)
@@ -274,17 +290,25 @@ TEST_F(WebRtcVideoFrameTest, Alias) {
// Tests the Init function with different cropped size.
TEST_F(WebRtcVideoFrameTest, InitEvenSize) {
TestInit(640, 360);
TestInit(640, 360, webrtc::kVideoRotation_0, true);
}
TEST_F(WebRtcVideoFrameTest, InitOddWidth) {
TestInit(601, 480);
TestInit(601, 480, webrtc::kVideoRotation_0, true);
}
TEST_F(WebRtcVideoFrameTest, InitOddHeight) {
TestInit(360, 765);
TestInit(360, 765, webrtc::kVideoRotation_0, true);
}
TEST_F(WebRtcVideoFrameTest, InitOddWidthHeight) {
TestInit(355, 1021);
TestInit(355, 1021, webrtc::kVideoRotation_0, true);
}
TEST_F(WebRtcVideoFrameTest, InitRotated90ApplyRotation) {
TestInit(640, 360, webrtc::kVideoRotation_90, true);
}
TEST_F(WebRtcVideoFrameTest, InitRotated90DontApplyRotation) {
TestInit(640, 360, webrtc::kVideoRotation_90, false);
}