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(