Fix for the alignment problems/mismatch in ViECapture and VP8Encoder.

BUG=576
TEST=unittest

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2371 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
wu@webrtc.org 2012-06-05 23:52:59 +00:00
parent f4c2de9e2f
commit cac603f390
3 changed files with 66 additions and 6 deletions

View File

@ -364,19 +364,22 @@ WebRtc_Word32 VideoCaptureImpl::IncomingFrameI420(
// Copy Y
for (int i = 0; i < y_rows; ++i) {
memcpy(current_pointer, y_plane, y_width);
current_pointer += video_frame.y_pitch;
// Remove the alignment which ViE doesn't support.
current_pointer += y_width;
y_plane += video_frame.y_pitch;
}
// Copy U
for (int i = 0; i < uv_rows; ++i) {
memcpy(current_pointer, u_plane, uv_width);
current_pointer += video_frame.u_pitch;
// Remove the alignment which ViE doesn't support.
current_pointer += uv_width;
u_plane += video_frame.u_pitch;
}
// Copy V
for (int i = 0; i < uv_rows; ++i) {
memcpy(current_pointer, v_plane, uv_width);
current_pointer += video_frame.v_pitch;
// Remove the alignment which ViE doesn't support.
current_pointer += uv_width;
v_plane += video_frame.v_pitch;
}
_captureFrame.SetLength(frame_size);

View File

@ -402,8 +402,61 @@ TEST_F(VideoCaptureExternalTest , TestExternalCaptureI420) {
frame_i420.u_pitch = kTestWidth / 2;
frame_i420.v_pitch = kTestWidth / 2;
EXPECT_EQ(0, capture_input_interface_->IncomingFrameI420(frame_i420, 0));
EXPECT_TRUE(CompareFrames(frame_i420, capture_callback_.last_frame));
// Test with a frame with pitch not equal to width
memset(test_frame_.Buffer(), 0xAA, test_frame_.Length());
webrtc::VideoFrame aligned_test_frame;
int y_pitch = kTestWidth + 2;
int u_pitch = kTestWidth / 2 + 1;
int v_pitch = u_pitch;
aligned_test_frame.VerifyAndAllocate(kTestHeight * y_pitch +
(kTestHeight / 2) * u_pitch +
(kTestHeight / 2) * v_pitch);
aligned_test_frame.SetLength(aligned_test_frame.Size());
memset(aligned_test_frame.Buffer(), 0, aligned_test_frame.Length());
// Copy the test_frame_ to aligned_test_frame.
int y_width = kTestWidth;
int uv_width = kTestWidth / 2;
int y_rows = kTestHeight;
int uv_rows = kTestHeight / 2;
unsigned char* current_pointer = aligned_test_frame.Buffer();
unsigned char* y_plane = test_frame_.Buffer();
unsigned char* u_plane = y_plane + kTestWidth * kTestHeight;
unsigned char* v_plane = u_plane + ((kTestWidth * kTestHeight) >> 2);
// Copy Y
for (int i = 0; i < y_rows; ++i) {
memcpy(current_pointer, y_plane, y_width);
// Remove the alignment which ViE doesn't support.
current_pointer += y_pitch;
y_plane += y_width;
}
// Copy U
for (int i = 0; i < uv_rows; ++i) {
memcpy(current_pointer, u_plane, uv_width);
// Remove the alignment which ViE doesn't support.
current_pointer += u_pitch;
u_plane += uv_width;
}
// Copy V
for (int i = 0; i < uv_rows; ++i) {
memcpy(current_pointer, v_plane, uv_width);
// Remove the alignment which ViE doesn't support.
current_pointer += v_pitch;
v_plane += uv_width;
}
frame_i420.width = kTestWidth;
frame_i420.height = kTestHeight;
frame_i420.y_plane = aligned_test_frame.Buffer();
frame_i420.u_plane = frame_i420.y_plane + (y_pitch * y_rows);
frame_i420.v_plane = frame_i420.u_plane + (u_pitch * uv_rows);
frame_i420.y_pitch = y_pitch;
frame_i420.u_pitch = u_pitch;
frame_i420.v_pitch = v_pitch;
EXPECT_EQ(0, capture_input_interface_->IncomingFrameI420(frame_i420, 0));
EXPECT_TRUE(CompareFrames(test_frame_, capture_callback_.last_frame));
}
// Test frame rate and no picture alarm.

View File

@ -174,7 +174,11 @@ int VP8Encoder::InitEncode(const VideoCodec* inst,
encoded_image_._buffer = new uint8_t[encoded_image_._size];
encoded_image_._completeFrame = true;
raw_ = vpx_img_alloc(NULL, IMG_FMT_I420, codec_.width, codec_.height, 32);
unsigned int align = 1;
if (codec_.width % 32 == 0) {
align = 32;
}
raw_ = vpx_img_alloc(NULL, IMG_FMT_I420, codec_.width, codec_.height, align);
// populate encoder configuration with default values
if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), config_, 0)) {
return WEBRTC_VIDEO_CODEC_ERROR;
@ -970,7 +974,7 @@ VideoDecoder* VP8Decoder::Copy() {
if (!vpx_img_alloc(&ref_frame_->img,
static_cast<vpx_img_fmt_t>(image_format_),
decoded_image_._width, decoded_image_._height, 32)) {
decoded_image_._width, decoded_image_._height, 1)) {
assert(false);
delete copy;
return NULL;