/* * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include #include #include #include "vplib.h" #include using namespace webrtc; #define TEST_STR "Test Scale." #define TEST_PASSED() std::cerr << TEST_STR << " : [OK]" << std::endl #define PRINT_LINE std::cout << "------------------------------------------" << std::endl; void PrintFrame(WebRtc_UWord8* ptrFrame, WebRtc_Word32 width, WebRtc_Word32 height) { WebRtc_Word32 k = 0; for (WebRtc_Word32 i = 0; i < height; i++) { for (WebRtc_Word32 j = 0; j < width; j++) { std::cout << (WebRtc_Word32)ptrFrame[k++] << " "; } std::cout << " " << std::endl; } std::cout << " " << std::endl; } void PrintFrame(WebRtc_UWord8* ptrInFrame, WebRtc_Word32 width, WebRtc_Word32 height, const WebRtc_Word8* str) { std::cout << str << " (" << width << "x" << height << ") = " << std::endl; WebRtc_UWord8* ptrFrameY = ptrInFrame; WebRtc_UWord8* ptrFrameCb = ptrFrameY + width*height; WebRtc_UWord8* ptrFrameCr = ptrFrameCb + width*height/4; PrintFrame(ptrFrameY, width, height); PrintFrame(ptrFrameCb, width/2, height/2); PrintFrame(ptrFrameCr, width/2, height/2); } void CreateImage(WebRtc_Word32 width, WebRtc_Word32 height, WebRtc_UWord8* ptrFrame, WebRtc_Word32 offset, WebRtc_Word32 heightFactor, WebRtc_Word32 widthFactor = 0) { for (WebRtc_Word32 i = 0; i < height; i++) { for (WebRtc_Word32 j = 0; j < width; j++) { *ptrFrame = (WebRtc_UWord8)((i + offset)*heightFactor + j*widthFactor); ptrFrame++; } } } void ValidateImage2(WebRtc_Word32 width, WebRtc_Word32 height, WebRtc_UWord8* ptrFrame, WebRtc_Word32 offset, WebRtc_Word32 factor) { WebRtc_Word32 k = 0; WebRtc_Word32 res = offset*factor; for (WebRtc_Word32 i = 0; i < height; i++) { for (WebRtc_Word32 j = 0; j < width; j++) { assert(ptrFrame[k++] == res); } if (i > 0) { res += factor/2; } } } void ValidateImage3_2(WebRtc_Word32 width, WebRtc_Word32 height, WebRtc_UWord8* ptrFrame, WebRtc_Word32 offset, WebRtc_Word32 factor) { WebRtc_Word32 k = 0; bool inc = true; WebRtc_Word32 res = offset*factor; for (WebRtc_Word32 i = 1; i <= height; i++) { for (WebRtc_Word32 j = 0; j < width; j++) { assert(ptrFrame[k++] == res); } res += factor/2; if ((i % 3) == 0) { res += factor/2; } } } void ValidateImage1_3(WebRtc_Word32 width, WebRtc_Word32 height, WebRtc_UWord8* ptrFrame, WebRtc_Word32 offset, WebRtc_Word32 factor) { WebRtc_Word32 k = 0; WebRtc_Word32 res = offset*factor; res += factor/2; for (WebRtc_Word32 i = 0; i < height; i++) { for (WebRtc_Word32 j = 0; j < width; j++) { assert(ptrFrame[k++] == res); } res += factor*3; } } static void VerifyInBounds(const WebRtc_UWord8* ptrImage, const WebRtc_Word32 imageLength, const WebRtc_Word32 startOffset, const WebRtc_Word32 endOffset) { // Verify that function does not write outside buffer const WebRtc_UWord8* ptrFrameStart = ptrImage - startOffset; const WebRtc_UWord8* ptrFrameEnd = ptrImage + imageLength; // Verify that function does not write outside buffer for (WebRtc_Word32 i = 0; i < startOffset; i++) { assert(ptrFrameStart[i] == 255); } for (WebRtc_Word32 i = 0; i < endOffset; i++) { assert(ptrFrameEnd[i] == 255); } } WebRtc_Word32 VerifyAndAllocateTest(WebRtc_UWord8*& buffer, WebRtc_Word32 currentSize, WebRtc_Word32 newSize) { if(newSize > currentSize) { // make sure that our buffer is big enough WebRtc_UWord8* newBuffer = new WebRtc_UWord8[newSize]; if(buffer) { // copy the old data memcpy(newBuffer, buffer, currentSize); delete [] buffer; } buffer = newBuffer; return newSize; } return currentSize; } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- int scale_test() { std::string str; std::cout << "--------------------------------" << std::endl; std::cout << "-------- Test Scaling ----------" << std::endl; std::cout << "--------------------------------" << std::endl; std::cout << " " << std::endl; // ------------------------------- // Test ScaleI420Up2() ----------- // ------------------------------- PRINT_LINE; std::cout << "Test ScaleI420Up2()" << std::endl; PRINT_LINE; WebRtc_UWord32 width = 12; WebRtc_UWord32 height = 10; WebRtc_Word32 factorY = 2; WebRtc_Word32 factorCb = 10; WebRtc_Word32 factorCr = 20; WebRtc_Word32 offset = 5; WebRtc_Word32 startBufferOffset = 10; WebRtc_UWord32 length = CalcBufferSize(kI420, width, height); // Test bad inputs WebRtc_UWord32 scW = 0; WebRtc_UWord32 scH = 0; WebRtc_UWord8* testFrame = new WebRtc_UWord8[length + offset]; WebRtc_Word32 retVal = ScaleI420Up2(0, height,testFrame,length, scW, scH); assert(retVal == -1); retVal = ScaleI420Up2(width, 0, testFrame,length, scW, scH); assert(retVal == -1); retVal = ScaleI420Up2(49, height, testFrame, length, scW, scH); assert(retVal == -1); retVal = ScaleI420Up2(width, 3, testFrame,length, scW, scH); // odd height assert(retVal == -1); retVal = ScaleI420Up2(width + 2, height, testFrame,length, scW, scH); // width, height > allocated buffer size assert(retVal == -1); retVal = ScaleI420Up2(width, height + 2, testFrame,length, scW, scH); // width, height > allocated buffer size assert(retVal == -1); retVal = ScaleI420Up2(width, height, testFrame,length, scW, scH); // width, height == allocated buffer size, OK assert(retVal == scW * scH * 3 / 2); delete [] testFrame; testFrame = new WebRtc_UWord8[ length * 4 + startBufferOffset * 2]; memset(testFrame, 255, length * 4 + startBufferOffset * 2); // Create input frame WebRtc_UWord8* ptrFrameY = testFrame; WebRtc_UWord8* ptrFrameCb = ptrFrameY + width*height; WebRtc_UWord8* ptrFrameCr = ptrFrameCb + width*height/4; CreateImage(width, height, ptrFrameY, offset, factorY); // Y CreateImage(width/2, height/2, ptrFrameCb, offset, factorCb); // Cb CreateImage(width/2, height/2, ptrFrameCr, offset, factorCr); // Cr PrintFrame(testFrame, width, height, "InputFrame"); // Scale frame to twice its size WebRtc_UWord32 scaledWidth = 0; WebRtc_UWord32 scaledHeight = 0; retVal = ScaleI420Up2(width, height, testFrame, length * 4 + startBufferOffset * 2, scaledWidth, scaledHeight); PrintFrame(testFrame, scaledWidth, scaledHeight, "Output Frame"); // Validate results assert(retVal == scaledWidth * scaledHeight * 3 / 2); ptrFrameY = testFrame; ptrFrameCb = ptrFrameY + scaledWidth*scaledHeight; ptrFrameCr = ptrFrameCb + scaledWidth*scaledHeight/4; ValidateImage2(scaledWidth, scaledHeight, ptrFrameY, offset, factorY); ValidateImage2(scaledWidth/2, scaledHeight/2, ptrFrameCb, offset, factorCb); ValidateImage2(scaledWidth/2, scaledHeight/2, ptrFrameCr, offset, factorCr); delete [] testFrame; // -------------------------------- // Test ScaleI420Up3_2() ---------- // -------------------------------- PRINT_LINE; std::cout << "Test ScaleI420Up3_2()" << std::endl; PRINT_LINE; width = 12; height = 8; factorY = 2; factorCb = 10; factorCr = 20; offset = 5; startBufferOffset = 10; length = CalcBufferSize(kI420, width, height); // Test bad inputs testFrame = new WebRtc_UWord8[length]; retVal = ScaleI420Up3_2(0, height, testFrame,length, scW, scH); assert(retVal == -1); retVal = ScaleI420Up3_2(width, 0, testFrame,length, scW, scH); assert(retVal == -1); retVal = ScaleI420Up3_2(49, height, testFrame,length, scW, scH); // odd width assert(retVal == -1); retVal = ScaleI420Up3_2(width, 3, testFrame,length, scW, scH); // odd height assert(retVal == -1); retVal = ScaleI420Up3_2(width, 10, testFrame,length, scW, scH); // odd height (color) assert(retVal == -1); retVal = ScaleI420Up3_2(14, height, testFrame,length, scW, scH); // odd width (color) assert(retVal == -1); retVal = ScaleI420Up3_2(width + 2, height, testFrame,length, scW, scH); // width, height > allocated buffer size assert(retVal == -1); retVal = ScaleI420Up3_2(width, height + 2, testFrame,length, scW, scH); // width, height > allocated buffer size assert(retVal == -1); retVal = ScaleI420Up3_2(width, height, testFrame,length, scW, scH); // width, height == allocated buffer size, OK assert(retVal == scW * scH * 3 / 2); delete [] testFrame; testFrame = new WebRtc_UWord8[length + startBufferOffset]; memset(testFrame, 255, length + startBufferOffset); // Create input frame ptrFrameY = testFrame; ptrFrameCb = ptrFrameY + width*height; ptrFrameCr = ptrFrameCb + width*height/4; CreateImage(width, height, ptrFrameY, offset, factorY); // Y CreateImage(width/2, height/2, ptrFrameCb, offset, factorCb); // Cb CreateImage(width/2, height/2, ptrFrameCr, offset, factorCr); // Cr PrintFrame(testFrame, width, height, "Input Frame"); // Scale frame to 1.5 times its size scaledWidth = 0; scaledHeight = 0; retVal = ScaleI420Up3_2(width, height, testFrame, length + startBufferOffset, scaledWidth, scaledHeight); PrintFrame(testFrame, scaledWidth, scaledHeight, "Output Frame"); // Validate results assert(retVal == scaledWidth * scaledHeight * 3 / 2); // Verify that function does not write outside buffer ptrFrameY = testFrame;//imageBuffer.GetBuffer(); ptrFrameCb = ptrFrameY + scaledWidth*scaledHeight; ptrFrameCr = ptrFrameCb + scaledWidth*scaledHeight/4; ValidateImage3_2(scaledWidth, scaledHeight, ptrFrameY, offset, factorY); ValidateImage3_2(scaledWidth/2, scaledHeight/2, ptrFrameCb, offset, factorCb); ValidateImage3_2(scaledWidth/2, scaledHeight/2, ptrFrameCr, offset, factorCr); delete [] testFrame; // -------------------------------- // Test ScaleI420Down1_3() ---------- // -------------------------------- PRINT_LINE; std::cout << "Test ScaleI420Up1_3()" << std::endl; PRINT_LINE; width = 10; height = 8; factorY = 2; factorCb = 10; factorCr = 20; offset = 5; startBufferOffset = 10; length = webrtc::CalcBufferSize(kI420, width, height); // Test bad inputs testFrame = new WebRtc_UWord8[length]; retVal = ScaleI420Down1_3(0, height, testFrame, length, scW, scH); assert(retVal == -1); retVal = ScaleI420Down1_3(width, 0, testFrame, length, scW, scH); assert(retVal == -1); retVal = ScaleI420Down1_3(49, height, testFrame, length, scW, scH); // odd width assert(retVal == -1); retVal = ScaleI420Down1_3(width, 3, testFrame, length, scW, scH); // odd height assert(retVal == -1); retVal = ScaleI420Down1_3(width + 2, height, testFrame, length, scW, scH); // width, height > allocated buffer size assert(retVal == -1); retVal = ScaleI420Down1_3(width, height + 2, testFrame, length, scW, scH); // width, height > allocated buffer size assert(retVal == -1); retVal = ScaleI420Down1_3(width, height, testFrame, length, scW, scH); // width, height == allocated buffer size, ok assert(retVal == scW * scH * 3 / 2); delete [] testFrame; testFrame = new WebRtc_UWord8[length + startBufferOffset * 2]; memset(testFrame, 255, length + startBufferOffset * 2); // Create input frame ptrFrameY = testFrame; ptrFrameCb = ptrFrameY + width*height; ptrFrameCr = ptrFrameCb + width*height/4; CreateImage(width, height, ptrFrameY, offset, factorY); // Y CreateImage(width/2, height/2, ptrFrameCb, offset, factorCb); // Cb CreateImage(width/2, height/2, ptrFrameCr, offset, factorCr); // Cr PrintFrame(testFrame, width, height, "Input Frame"); // Scale frame to one third its size scaledWidth = 0; scaledHeight = 0; retVal = ScaleI420Down1_3(width, height, testFrame, length + startBufferOffset * 2 , scaledWidth, scaledHeight); PrintFrame(testFrame, scaledWidth, scaledHeight, "Output Frame"); // Validate results assert(retVal == scaledWidth * scaledHeight * 3 / 2); // Verify that function does not write outside buffer ptrFrameY = testFrame;//imageBuffer.GetBuffer(); ptrFrameCb = ptrFrameY + scaledWidth*scaledHeight; ptrFrameCr = ptrFrameCb + scaledWidth*scaledHeight/4; ValidateImage1_3(scaledWidth, scaledHeight, ptrFrameY, offset, factorY); ValidateImage1_3(scaledWidth/2, scaledHeight/2, ptrFrameCb, offset, factorCb); ValidateImage1_3(scaledWidth/2, scaledHeight/2, ptrFrameCr, offset, factorCr); delete [] testFrame; // ------------------- // Test PadI420Frame() // ------------------- PRINT_LINE; std::cout << "Test PadI420Frame()" << std::endl; PRINT_LINE; width = 16; height = 8; factorY = 1; factorCb = 1; factorCr = 1; offset = 5; startBufferOffset = 10; length = CalcBufferSize(kI420, width, height); testFrame = new WebRtc_UWord8[length]; memset(testFrame, 255, length); // Create input frame ptrFrameY = testFrame;//imageBuffer.GetBuffer(); ptrFrameCb = ptrFrameY + width*height; ptrFrameCr = ptrFrameCb + width*height/4; CreateImage(width, height, ptrFrameY, 1, factorY); // Y CreateImage(width/2, height/2, ptrFrameCb, 100, factorCb); // Cb CreateImage(width/2, height/2, ptrFrameCr, 200, factorCr); // Cr PrintFrame(testFrame, width, height, "Input Frame"); WebRtc_UWord8* testFrame2 = new WebRtc_UWord8[352*288]; // Test bad input assert(PadI420Frame(NULL, testFrame2, 16, 16, 32, 32) == -1); assert(PadI420Frame(testFrame, NULL, 16, 16, 32, 32) == -1); assert(PadI420Frame(testFrame, testFrame2, 0, 16, 32, 32) == -1); assert(PadI420Frame(testFrame, testFrame2, 16, 0, 32, 32) == -1); assert(PadI420Frame(testFrame, testFrame2, 16, 16, 0, 32) == -1); assert(PadI420Frame(testFrame, testFrame2, 16, 16, 32, 0) == -1); assert(PadI420Frame(testFrame, testFrame2, 16, 16, 8, 32) == -1); assert(PadI420Frame(testFrame, testFrame2, 16, 16, 32, 8) == -1); assert(PadI420Frame(testFrame, testFrame2, 16, 16, 16, 16) == 3 * 16 * 16 / 2); enum { NumOfPaddedSizes = 4 }; WebRtc_Word32 paddedWidth[NumOfPaddedSizes] = { 32, 22, 16, 20 }; WebRtc_Word32 paddedHeight[NumOfPaddedSizes] = { 16, 14, 12, 8 }; for (WebRtc_Word32 i = 0; i < NumOfPaddedSizes; i++) { scaledWidth = paddedWidth[i]; scaledHeight = paddedHeight[i]; WebRtc_Word32 toLength = webrtc::CalcBufferSize(kI420, scaledWidth, scaledHeight); if (testFrame2) { delete [] testFrame2; } testFrame2 = new WebRtc_UWord8[toLength + startBufferOffset * 2]; memset(testFrame2, 255, toLength + startBufferOffset * 2); retVal = webrtc::PadI420Frame(testFrame, testFrame2, width, height, scaledWidth, scaledHeight); PrintFrame(testFrame2, scaledWidth, scaledHeight, "Output Frame"); // Validate results assert(retVal == toLength); } std::cout << "Do the padded frames look correct?" << std::endl << "(Padded dimensions which are multiples of 16 will have the" << std::endl << "padding applied in blocks of 16)" << std::endl << "Press enter to continue..."; std::getline(std::cin, str); // ----------------- // Test video sizes // ----------------- const WebRtc_Word32 nr = 16; // currently not keeping video sizes as a type - testing scaling functions only WebRtc_UWord16 widths[nr] = {128, 160, 176, 320, 352, 640, 720, 704, 800, 960, 1024, 1440, 400, 800, 1280, 1920}; WebRtc_UWord16 heights[nr] = { 96, 120, 144, 240, 288, 480, 480, 576, 600, 720, 768, 1080, 240, 480, 720, 1080}; for (WebRtc_Word32 j = 0; j < 3; j++) { for (WebRtc_Word32 i = 0; i < nr; i++) { width = widths[i]; height = heights[i]; factorY = 2; factorCb = 2; factorCr = 2; offset = 2; startBufferOffset = 10; length = webrtc::CalcBufferSize(kI420, width, height); float f = 1; if (j == 0) { f = 2; } else if (j == 1) { f = 1.5; } else if (j == 2) { f = 1; } if (testFrame) { delete testFrame; testFrame = 0; } WebRtc_Word32 frameSize = (WebRtc_Word32) ((length * f * f) + startBufferOffset * 2); testFrame = new WebRtc_UWord8[frameSize]; memset(testFrame, 255, frameSize); // Create input frame ptrFrameY = testFrame; ptrFrameCb = ptrFrameY + width*height; ptrFrameCr = ptrFrameCb + width*height/4; CreateImage(width, height, ptrFrameY, offset, factorY); // Y CreateImage(width/2, height/2, ptrFrameCb, offset, factorCb); // Cb CreateImage(width/2, height/2, ptrFrameCr, offset, factorCr); // Cr scaledWidth = 0; scaledHeight = 0; if (j == 0) { retVal = ScaleI420Up2(width, height, testFrame,frameSize, scaledWidth, scaledHeight); length = scaledWidth*scaledHeight*3/2; } else if (j == 1) { retVal = ScaleI420Up3_2(width, height, testFrame,frameSize, scaledWidth, scaledHeight); length = scaledWidth*scaledHeight*3/2; } else if (j == 2) { retVal = ScaleI420Down1_3(width, height, testFrame,frameSize, scaledWidth, scaledHeight); length = width*height*3/2; } // Validate results assert(retVal == scaledWidth * scaledHeight * 3 / 2); } } // --------------------- // Test mirror functions // --------------------- std::cout << "Test Mirror function" << std::endl; // 4:2:0 images can't have odd width or height width = 16; height = 8; factorY = 1; factorCb = 1; factorCr = 1; offset = 5; startBufferOffset = 10; length = webrtc::CalcBufferSize(kI420, width, height); delete [] testFrame; testFrame = new WebRtc_UWord8[length]; memset(testFrame, 255, length); // Create input frame WebRtc_UWord8* inFrame = testFrame; ptrFrameCb = inFrame + width * height; ptrFrameCr = ptrFrameCb + (width * height) / 4; CreateImage(width, height, inFrame, 10, factorY, 1); // Y CreateImage(width/2, height/2, ptrFrameCb, 100, factorCb, 1); // Cb CreateImage(width/2, height/2, ptrFrameCr, 200, factorCr, 1); // Cr PrintFrame(testFrame, width, height, "Input Frame"); if (testFrame2) { delete [] testFrame2; testFrame2 = 0; } testFrame2 = new WebRtc_UWord8[length + startBufferOffset * 2]; memset(testFrame2, 255, length + startBufferOffset * 2); WebRtc_UWord8* outFrame = testFrame2; // LeftRight std::cout << "Test Mirror function: LeftRight" << std::endl; retVal = MirrorI420LeftRight(inFrame, outFrame, width, height); PrintFrame(testFrame2, width, height, "Output Frame"); retVal = MirrorI420LeftRight(outFrame, outFrame, width, height); assert(memcmp(inFrame, outFrame, length) == 0); //VerifyInBounds(outFrame, length, startBufferOffset, startBufferOffset); //UpDown std::cout << "Test Mirror function: UpDown" << std::endl; retVal = MirrorI420UpDown(inFrame, outFrame, width, height); PrintFrame(testFrame2, width, height, "Output Frame"); retVal = MirrorI420UpDown(outFrame, outFrame, width, height); assert(memcmp(inFrame, outFrame, length) == 0); //VerifyInBounds(outFrame, length, startBufferOffset, startBufferOffset); std::cout << "Do the mirrored frames look correct?" << std::endl << "Press enter to continue..."; std::getline(std::cin, str); // end Mirror Function check delete [] testFrame; testFrame = new WebRtc_UWord8[length]; memset(testFrame,255,length); inFrame = testFrame; CreateImage(width, height, inFrame, 10, factorY, 1); // Y CreateImage(width/2, height/2, ptrFrameCb, 100, factorCb, 1); // Cb CreateImage(width/2, height/2, ptrFrameCr, 200, factorCr, 1); // Cr PrintFrame(inFrame, width, height, "Input frame"); delete [] testFrame2; testFrame2 = new WebRtc_UWord8[length]; memset(testFrame2, 255, length); int yv12Size = CalcBufferSize(kI420, kYV12, length); WebRtc_UWord8* yv12TestFrame = new WebRtc_UWord8[yv12Size]; memset(yv12TestFrame, 255, yv12Size); outFrame = testFrame2; retVal = ConvertI420ToYV12(inFrame, yv12TestFrame, width, height, 0); assert(retVal >= 0); // Test convert and mirror functions ConvertToI420AndMirrorUpDown(yv12TestFrame, outFrame, width, height, kYV12); std::cout << "Test: ConvertAndMirrorUpDown" << std::endl; PrintFrame(outFrame, width, height, "Output Frame"); MirrorI420UpDown(outFrame, outFrame, width, height); assert(memcmp(inFrame, outFrame, length) == 0); std::cout << "Does the converted (U and V flipped) mirrored frame look correct?" << std::endl << "Press enter to continue..."; std::getline(std::cin, str); delete [] testFrame2; PrintFrame(inFrame, width, height, "Input frame"); // Test convert and rotate functions testFrame2 = new WebRtc_UWord8[length]; memset(testFrame2, 255, length); outFrame = testFrame2; WebRtc_UWord8* tempFrame = new WebRtc_UWord8[length]; ConvertToI420(kYV12, yv12TestFrame, width, height, outFrame, false, kRotateAntiClockwise); std::cout << "Test: ConvertAndRotateAntiClockwise" << std::endl; PrintFrame(outFrame, height, width, "Output Frame"); ConvertToI420(kI420, outFrame, height, width, tempFrame, false, kRotateAntiClockwise); ConvertToI420(kI420, tempFrame, width, height, outFrame, false, kRotateAntiClockwise); ConvertToI420(kI420, outFrame, height, width, tempFrame, false, kRotateAntiClockwise); assert(memcmp(inFrame, tempFrame, length) == 0); delete [] testFrame2; testFrame2 = new WebRtc_UWord8[length]; outFrame = testFrame2; memset(outFrame, 255, length); memset(tempFrame, 255, length); ConvertToI420(kYV12, yv12TestFrame, width, height, outFrame, false, kRotateClockwise); std::cout << "Test: ConvertAndRotateClockwise" << std::endl; PrintFrame(outFrame, height, width, "Output Frame"); ConvertToI420(kI420, outFrame, height, width, tempFrame, false, kRotateClockwise); ConvertToI420(kI420, tempFrame, width, height, outFrame, false, kRotateClockwise); ConvertToI420(kI420, outFrame, height, width, tempFrame, false, kRotateClockwise); assert(memcmp(inFrame, tempFrame, length) == 0); delete [] testFrame2; std::cout << "Do the converted (U and V flipped) and rotated frames look correct?" << std::endl << "Press enter to continue..."; std::getline(std::cin, str); PrintFrame(inFrame, width, height, "Input frame"); // Test rotation with padding height += 4; length = width * height * 3 / 2; testFrame2 = new WebRtc_UWord8[length]; memset(testFrame2, 255, length); outFrame = testFrame2; webrtc::ConvertToI420(kYV12, yv12TestFrame, width, height - 4, outFrame, false, webrtc::kRotateClockwise); std::cout << "Test: ConvertAndRotateClockwise (width padding)" << std::endl; PrintFrame(outFrame, height, width, "Output Frame"); width += 4; height -= 4; memset(testFrame2, 255, length); outFrame = testFrame2; ConvertToI420(kYV12, yv12TestFrame, width - 4, height, outFrame, false, webrtc::kRotateAntiClockwise); std::cout << "Test: ConvertAndRotateClockwise (height padding)" << std::endl; PrintFrame(outFrame, height, width, "Output Frame"); std::cout << "Do the rotated and padded images look correct?" << std::endl << "Press enter to continue..."; std::getline(std::cin, str); delete [] tempFrame; tempFrame = NULL; delete [] testFrame; testFrame = NULL; delete [] testFrame2; testFrame2 = NULL; delete [] yv12TestFrame; yv12TestFrame = NULL; TEST_PASSED(); std::cout << "Press enter to quit test..."; std::getline(std::cin, str); return 0; }