Adding stride alignment
TEST= common_video_unittests and video_capture_module_test
BUG=985
Review URL: https://webrtc-codereview.appspot.com/965005
git-svn-id: http://webrtc.googlecode.com/svn/trunk@3023 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/common_video/libyuv/include/webrtc_libyuv.h b/webrtc/common_video/libyuv/include/webrtc_libyuv.h
index 4b1b2a5..c6a0046 100644
--- a/webrtc/common_video/libyuv/include/webrtc_libyuv.h
+++ b/webrtc/common_video/libyuv/include/webrtc_libyuv.h
@@ -63,6 +63,15 @@
// Return value: An aligned form of the input value.
int AlignInt(int value, int alignment);
+// Align stride values for I420 Video frames.
+// Input:
+// - width : Image width.
+// - stride_y : Pointer to the stride of the y plane.
+// - stride_uv: Pointer to the stride of the u and v planes (setting identical
+// values for both).
+// Setting 16 byte alignment.
+void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv);
+
// Calculate the required buffer size.
// Input:
// - type :The type of the designated video frame.
diff --git a/webrtc/common_video/libyuv/libyuv_unittest.cc b/webrtc/common_video/libyuv/libyuv_unittest.cc
index 6f760655..6ab8c23 100644
--- a/webrtc/common_video/libyuv/libyuv_unittest.cc
+++ b/webrtc/common_video/libyuv/libyuv_unittest.cc
@@ -138,8 +138,12 @@
printf("\nConvert #%d I420 <-> RGB24\n", j);
scoped_array<uint8_t> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]);
I420VideoFrame res_i420_frame;
- res_i420_frame.CreateEmptyFrame(width_, height_, width_,
- (width_ + 1) / 2, (width_ + 1) / 2);
+ // Align the stride values for the output frame.
+ int stride_y = 0;
+ int stride_uv = 0;
+ Calc16ByteAlignedStride(width_, &stride_y, &stride_uv);
+ res_i420_frame.CreateEmptyFrame(width_, height_, stride_y,
+ stride_uv, stride_uv);
EXPECT_EQ(0, ConvertFromI420(orig_frame, kRGB24, 0, res_rgb_buffer2.get()));
EXPECT_EQ(0, ConvertToI420(kRGB24, res_rgb_buffer2.get(), 0, 0, width_,
@@ -320,4 +324,21 @@
EXPECT_EQ(0x400, AlignInt(value, 32)); // Low 5 bits are zero.
}
+TEST_F(TestLibYuv, StrideAlignment) {
+ int stride_y = 0;
+ int stride_uv = 0;
+ int width = 52;
+ Calc16ByteAlignedStride(width, &stride_y, &stride_uv);
+ EXPECT_EQ(64, stride_y);
+ EXPECT_EQ(32, stride_uv);
+ width = 128;
+ Calc16ByteAlignedStride(width, &stride_y, &stride_uv);
+ EXPECT_EQ(128, stride_y);
+ EXPECT_EQ(64, stride_uv);
+ width = 127;
+ Calc16ByteAlignedStride(width, &stride_y, &stride_uv);
+ EXPECT_EQ(128, stride_y);
+ EXPECT_EQ(64, stride_uv);
+}
+
} // namespace
diff --git a/webrtc/common_video/libyuv/webrtc_libyuv.cc b/webrtc/common_video/libyuv/webrtc_libyuv.cc
index 816fa8f..ba5c6fa 100644
--- a/webrtc/common_video/libyuv/webrtc_libyuv.cc
+++ b/webrtc/common_video/libyuv/webrtc_libyuv.cc
@@ -17,6 +17,8 @@
namespace webrtc {
+const int k16ByteAlignment = 16;
+
VideoType RawVideoTypeToCommonVideoVideoType(RawVideoType type) {
switch (type) {
case kVideoI420:
@@ -58,6 +60,11 @@
return ((value + alignment - 1) & ~ (alignment - 1));
}
+void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) {
+ *stride_y = AlignInt(width, k16ByteAlignment);
+ *stride_uv = AlignInt((width + 1) / 2, k16ByteAlignment);
+}
+
int CalcBufferSize(VideoType type, int width, int height) {
int buffer_size = 0;
switch (type) {
diff --git a/webrtc/modules/video_capture/main/source/video_capture_impl.cc b/webrtc/modules/video_capture/main/source/video_capture_impl.cc
index e2e1209..794156f 100644
--- a/webrtc/modules/video_capture/main/source/video_capture_impl.cc
+++ b/webrtc/modules/video_capture/main/source/video_capture_impl.cc
@@ -284,9 +284,12 @@
// Setting absolute height (in case it was negative).
// In Windows, the image starts bottom left, instead of top left.
// Setting a negative source height, inverts the image (within LibYuv).
+ int stride_y = 0;
+ int stride_uv = 0;
+ Calc16ByteAlignedStride(width, &stride_y, &stride_uv);
int ret = _captureFrame.CreateEmptyFrame(width, abs(height),
- width, (width + 1) / 2,
- (width + 1) / 2);
+ stride_y,
+ stride_uv, stride_uv);
if (ret < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
@@ -336,7 +339,6 @@
const VideoFrameI420& video_frame, WebRtc_Word64 captureTime) {
CriticalSectionScoped cs(&_callBackCs);
- // TODO(mikhal): Do we take the stride as is, or do we align it?
int size_y = video_frame.height * video_frame.y_pitch;
int size_u = video_frame.u_pitch * (video_frame.height + 1) / 2;
int size_v = video_frame.v_pitch * (video_frame.height + 1) / 2;
diff --git a/webrtc/modules/video_capture/main/source/video_capture_impl.h b/webrtc/modules/video_capture/main/source/video_capture_impl.h
index 7d62de3..38f62bf 100644
--- a/webrtc/modules/video_capture/main/source/video_capture_impl.h
+++ b/webrtc/modules/video_capture/main/source/video_capture_impl.h
@@ -98,7 +98,6 @@
protected:
VideoCaptureImpl(const WebRtc_Word32 id);
virtual ~VideoCaptureImpl();
- // TODO(mikhal): Remove codec_type.
WebRtc_Word32 DeliverCapturedFrame(I420VideoFrame& captureFrame,
WebRtc_Word64 capture_time);
WebRtc_Word32 DeliverEncodedCapturedFrame(