Index: media/base/video_util_unittest.cc |
diff --git a/media/base/video_util_unittest.cc b/media/base/video_util_unittest.cc |
index 94fe7e9cb07d00b0b1c23b8380495c1383a2e093..170134ce1d10a15d44f98799a569855ceb515503 100644 |
--- a/media/base/video_util_unittest.cc |
+++ b/media/base/video_util_unittest.cc |
@@ -12,6 +12,95 @@ |
#include "media/base/video_frame.h" |
#include "testing/gtest/include/gtest/gtest.h" |
+namespace { |
xhwang
2016/05/05 22:00:21
nit: move this whole anonymous namespace block int
xjz
2016/05/05 22:52:19
These are helper functions. I think it might be be
|
+ |
+// Helper function used to verify the data in the coded region after copying the |
+// visible region and padding the remaining area. |
+bool VerifyCodedRegion(const uint8_t* src, |
+ size_t src_stride, |
+ const gfx::Size& visible_size, |
+ const uint8_t* dst, |
+ size_t dst_stride, |
+ const gfx::Size& coded_size) { |
xhwang
2016/05/05 22:00:21
It's probably more readable if you s/visible_size/
xjz
2016/05/05 22:52:19
Done.
|
+ if (!src || !dst) |
+ return false; |
+ |
+ const size_t width = visible_size.width(); |
xhwang
2016/05/05 22:00:21
nit: src_width
xjz
2016/05/05 22:52:19
Done.
|
+ const size_t height = visible_size.height(); |
+ const size_t dst_width = coded_size.width(); |
+ const size_t dst_height = coded_size.height(); |
+ if (width > dst_width || width > src_stride || height > dst_height || |
+ visible_size.IsEmpty() || coded_size.IsEmpty()) |
+ return false; |
+ |
+ const uint8_t *src_ptr = src, *dst_ptr = dst; |
+ for (size_t i = 0; i < height; |
+ ++i, src_ptr += src_stride, dst_ptr += dst_stride) { |
+ size_t j = 0; |
+ for (; j < width; ++j) { |
+ if (src_ptr[j] != dst_ptr[j]) |
+ return false; |
+ } |
xhwang
2016/05/05 22:00:21
Use memcmp for this one?
xjz
2016/05/05 22:52:19
Done.
|
+ uint8_t last_pixel = src_ptr[j - 1]; |
xhwang
2016/05/05 22:00:21
width - 1 might be a bit more readable.
xjz
2016/05/05 22:52:19
Done.
|
+ for (; j < dst_width; ++j) { |
+ if (last_pixel != dst_ptr[j]) |
+ return false; |
+ } |
xhwang
2016/05/05 22:00:21
ditto about memcmp
xjz
2016/05/05 22:52:19
Done.
|
+ } |
+ if (height < dst_height) { |
+ src_ptr = dst + (height - 1) * dst_stride; |
+ for (size_t i = height; i < dst_height; ++i, dst_ptr += dst_stride) { |
+ for (size_t j = 0; j < dst_width; ++j) { |
+ if (src_ptr[j] != dst_ptr[j]) |
+ return false; |
+ } |
+ } |
+ } |
+ return true; |
+} |
+ |
+bool VerifyCopyWithPadding(const media::VideoFrame& src_frame, |
+ const media::VideoFrame& dst_frame) { |
+ if (!src_frame.IsMappable() || !dst_frame.IsMappable() || |
+ src_frame.visible_rect().size() != dst_frame.visible_rect().size()) |
+ return false; |
+ |
+ if (!VerifyCodedRegion(src_frame.visible_data(media::VideoFrame::kYPlane), |
+ src_frame.stride(media::VideoFrame::kYPlane), |
+ src_frame.visible_rect().size(), |
+ dst_frame.data(media::VideoFrame::kYPlane), |
+ dst_frame.stride(media::VideoFrame::kYPlane), |
+ dst_frame.coded_size())) |
+ return false; |
+ if (!VerifyCodedRegion( |
+ src_frame.visible_data(media::VideoFrame::kUPlane), |
+ src_frame.stride(media::VideoFrame::kUPlane), |
+ media::VideoFrame::PlaneSize(media::PIXEL_FORMAT_I420, |
+ media::VideoFrame::kUPlane, |
+ src_frame.visible_rect().size()), |
+ dst_frame.data(media::VideoFrame::kUPlane), |
+ dst_frame.stride(media::VideoFrame::kUPlane), |
+ media::VideoFrame::PlaneSize(media::PIXEL_FORMAT_I420, |
+ media::VideoFrame::kUPlane, |
+ dst_frame.coded_size()))) |
+ return false; |
+ if (!VerifyCodedRegion( |
+ src_frame.visible_data(media::VideoFrame::kVPlane), |
+ src_frame.stride(media::VideoFrame::kVPlane), |
+ media::VideoFrame::PlaneSize(media::PIXEL_FORMAT_I420, |
+ media::VideoFrame::kVPlane, |
+ src_frame.visible_rect().size()), |
+ dst_frame.data(media::VideoFrame::kVPlane), |
+ dst_frame.stride(media::VideoFrame::kVPlane), |
+ media::VideoFrame::PlaneSize(media::PIXEL_FORMAT_I420, |
+ media::VideoFrame::kVPlane, |
+ dst_frame.coded_size()))) |
+ return false; |
+ |
+ return true; |
+} |
+} |
+ |
namespace media { |
class VideoUtilTest : public testing::Test { |
@@ -362,4 +451,36 @@ TEST_F(VideoUtilTest, LetterboxYUV) { |
} |
} |
+TEST_F(VideoUtilTest, I420CopyWithPadding) { |
+ gfx::Size visible_size(40, 30); |
+ scoped_refptr<VideoFrame> src_frame(VideoFrame::CreateFrame( |
+ PIXEL_FORMAT_I420, visible_size, gfx::Rect(visible_size), visible_size, |
+ base::TimeDelta())); |
+ // Expect to return false when copying to an empty buffer. |
+ EXPECT_FALSE(I420CopyWithPadding(*src_frame, nullptr)); |
+ |
+ scoped_refptr<VideoFrame> dst_frame(VideoFrame::CreateFrame( |
+ PIXEL_FORMAT_I420, visible_size, gfx::Rect(visible_size), visible_size, |
+ base::TimeDelta())); |
+ EXPECT_TRUE(I420CopyWithPadding(*src_frame, dst_frame.get())); |
+ EXPECT_TRUE(VerifyCopyWithPadding(*src_frame, *dst_frame)); |
+ |
+ gfx::Size coded_size(60, 40); |
+ dst_frame = VideoFrame::CreateFrame(PIXEL_FORMAT_I420, coded_size, |
+ gfx::Rect(visible_size), coded_size, |
+ base::TimeDelta()); |
+ EXPECT_TRUE(I420CopyWithPadding(*src_frame, dst_frame.get())); |
+ EXPECT_TRUE(VerifyCopyWithPadding(*src_frame, *dst_frame)); |
+ |
+ gfx::Size odd_size(39, 31); |
+ src_frame = |
+ VideoFrame::CreateFrame(PIXEL_FORMAT_I420, odd_size, gfx::Rect(odd_size), |
+ odd_size, base::TimeDelta()); |
+ dst_frame = VideoFrame::CreateFrame(PIXEL_FORMAT_I420, coded_size, |
+ gfx::Rect(odd_size), coded_size, |
+ base::TimeDelta()); |
+ EXPECT_TRUE(I420CopyWithPadding(*src_frame, dst_frame.get())); |
+ EXPECT_TRUE(VerifyCopyWithPadding(*src_frame, *dst_frame)); |
+} |
+ |
} // namespace media |