diff --git a/AUTHORS b/AUTHORS index af1688f035..69b5e2fc4a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -14,6 +14,7 @@ Chris Tserng Christophe Dumez Cody Barnes Colin Plumb +David Porter Dax Booysen Dmitry Lizin Eric Rescorla, RTFM Inc. diff --git a/sdk/objc/Framework/Classes/Video/RTCCVPixelBuffer.mm b/sdk/objc/Framework/Classes/Video/RTCCVPixelBuffer.mm index f854c91edc..9e5ac7320b 100644 --- a/sdk/objc/Framework/Classes/Video/RTCCVPixelBuffer.mm +++ b/sdk/objc/Framework/Classes/Video/RTCCVPixelBuffer.mm @@ -323,8 +323,12 @@ const uint8_t* src = static_cast(CVPixelBufferGetBaseAddress(_pixelBuffer)); const int srcStride = CVPixelBufferGetBytesPerRow(_pixelBuffer); - // Crop just by modifying pointers. - src += srcStride * _cropY + _cropX; + // Crop just by modifying pointers. Need to ensure that src pointer points to a byte corresponding + // to the start of a new pixel (byte with B for BGRA) so that libyuv scales correctly. + const int bytesPerPixel = 4; + src += srcStride * _cropY + (_cropX * bytesPerPixel); + + // kCVPixelFormatType_32BGRA corresponds to libyuv::FOURCC_ARGB libyuv::ARGBScale(src, srcStride, _cropWidth, diff --git a/sdk/objc/Framework/UnitTests/RTCCVPixelBuffer_xctest.mm b/sdk/objc/Framework/UnitTests/RTCCVPixelBuffer_xctest.mm index a6200dca5a..834bb222b9 100644 --- a/sdk/objc/Framework/UnitTests/RTCCVPixelBuffer_xctest.mm +++ b/sdk/objc/Framework/UnitTests/RTCCVPixelBuffer_xctest.mm @@ -153,6 +153,14 @@ [self cropAndScaleTestWithRGBPixelFormat:kCVPixelFormatType_32ARGB]; } +- (void)testCropAndScaleWithSmallCropInfo_32ARGB { + [self cropAndScaleTestWithRGBPixelFormat:kCVPixelFormatType_32ARGB cropX:2 cropY:3]; +} + +- (void)testCropAndScaleWithLargeCropInfo_32ARGB { + [self cropAndScaleTestWithRGBPixelFormat:kCVPixelFormatType_32ARGB cropX:200 cropY:300]; +} + - (void)testToI420_NV12 { [self toI420WithPixelFormat:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]; } @@ -224,12 +232,24 @@ } - (void)cropAndScaleTestWithRGBPixelFormat:(OSType)pixelFormat { + [self cropAndScaleTestWithRGBPixelFormat:pixelFormat cropX:0 cropY:0]; +} + +- (void)cropAndScaleTestWithRGBPixelFormat:(OSType)pixelFormat cropX:(int)cropX cropY:(int)cropY { CVPixelBufferRef pixelBufferRef = NULL; CVPixelBufferCreate(NULL, 720, 1280, pixelFormat, NULL, &pixelBufferRef); DrawGradientInRGBPixelBuffer(pixelBufferRef); - RTCCVPixelBuffer *buffer = [[RTCCVPixelBuffer alloc] initWithPixelBuffer:pixelBufferRef]; + RTCCVPixelBuffer *buffer = + [[RTCCVPixelBuffer alloc] initWithPixelBuffer:pixelBufferRef + adaptedWidth:CVPixelBufferGetWidth(pixelBufferRef) + adaptedHeight:CVPixelBufferGetHeight(pixelBufferRef) + cropWidth:CVPixelBufferGetWidth(pixelBufferRef) - cropX + cropHeight:CVPixelBufferGetHeight(pixelBufferRef) - cropY + cropX:cropX + cropY:cropY]; + XCTAssertEqual(buffer.width, 720); XCTAssertEqual(buffer.height, 1280);