From 2fd1c07e7097a4ee58512f1d47efe3dade3c8a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tar=C4=B1k=20Y=C4=B1lmaz?= Date: Wed, 6 Oct 2021 22:34:30 +0300 Subject: [PATCH 1/5] Add mirroring correction on bgra8888 format --- .../camera/camera/ios/Classes/CameraPlugin.m | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index da560d6c4df7..99a80c4c0fbe 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -704,7 +704,81 @@ - (void)captureOutput:(AVCaptureOutput *)output CVPixelBufferRef nextBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CMTime nextSampleTime = CMTimeSubtract(_lastVideoSampleTime, _videoTimeOffset); - [_videoAdaptor appendPixelBuffer:nextBuffer withPresentationTime:nextSampleTime]; + + if ([_captureDevice position] == AVCaptureDevicePositionFront) { + CVPixelBufferLockBaseAddress(nextBuffer, kCVPixelBufferLock_ReadOnly); + + const Boolean isPlanar = CVPixelBufferIsPlanar(nextBuffer); + size_t planeCount; + if (isPlanar) { + planeCount = CVPixelBufferGetPlaneCount(nextBuffer); + } else { + planeCount = 1; + } + + if (planeCount == 1) { + OSType formatType = CVPixelBufferGetPixelFormatType(nextBuffer); + void *planeAddress = CVPixelBufferGetBaseAddress(nextBuffer); + size_t bytesPerRow = CVPixelBufferGetBytesPerRow(nextBuffer); + size_t height = CVPixelBufferGetHeight(nextBuffer); + size_t width = CVPixelBufferGetWidth(nextBuffer); + + void* targetBytes = malloc(height * bytesPerRow); + size_t targetBytesPerRow = bytesPerRow; + + vImage_Buffer inBuffer; + inBuffer.data = planeAddress; + inBuffer.rowBytes = bytesPerRow; + inBuffer.width = width; + inBuffer.height = height; + + vImage_Buffer outBuffer; + outBuffer.data = targetBytes; + outBuffer.rowBytes = targetBytesPerRow; + outBuffer.width = width; + outBuffer.height = height; + + vImage_Error err; + + err = vImageHorizontalReflect_ARGB8888(&inBuffer, &outBuffer, kvImageNoFlags); + + if (err != kvImageNoError) { + NSLog (@"vImageHorizontalReflect_ARGB8888 returned %ld", err); + + free(targetBytes); + targetBytes = NULL; + + return; + } + + CVReturn status; + CVPixelBufferRef nnb = NULL; + + status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, formatType, outBuffer.data, outBuffer.rowBytes, NULL, NULL, NULL, &nnb); + + if (status != kCVReturnSuccess) { + NSLog (@"CVPixelBufferCreateWithBytes returned %d", status); + + free(targetBytes); + targetBytes = NULL; + + return; + } + + [_videoAdaptor appendPixelBuffer:nnb withPresentationTime:nextSampleTime]; + + free(targetBytes); + targetBytes = NULL; + + CVBufferRelease(nnb); + } else { + + } + + CVPixelBufferUnlockBaseAddress(nextBuffer, kCVPixelBufferLock_ReadOnly); + } else { + [_videoAdaptor appendPixelBuffer:nextBuffer withPresentationTime:nextSampleTime]; + } } else { CMTime dur = CMSampleBufferGetDuration(sampleBuffer); From b50c554fb5d1ad9d2752dcd86fc890988d33da63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tar=C4=B1k=20Y=C4=B1lmaz?= Date: Fri, 8 Oct 2021 17:08:58 +0300 Subject: [PATCH 2/5] Add mirroring correction on bi-planar 4:2:0 format --- .../camera/camera/ios/Classes/CameraPlugin.m | 94 ++++++++++++++++++- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 99a80c4c0fbe..f0cd00fcf3f2 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -716,8 +716,9 @@ - (void)captureOutput:(AVCaptureOutput *)output planeCount = 1; } - if (planeCount == 1) { - OSType formatType = CVPixelBufferGetPixelFormatType(nextBuffer); + OSType formatType = CVPixelBufferGetPixelFormatType(nextBuffer); + + if (!isPlanar) { void *planeAddress = CVPixelBufferGetBaseAddress(nextBuffer); size_t bytesPerRow = CVPixelBufferGetBytesPerRow(nextBuffer); size_t height = CVPixelBufferGetHeight(nextBuffer); @@ -754,7 +755,8 @@ - (void)captureOutput:(AVCaptureOutput *)output CVReturn status; CVPixelBufferRef nnb = NULL; - status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, formatType, outBuffer.data, outBuffer.rowBytes, NULL, NULL, NULL, &nnb); + status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, formatType, outBuffer.data, + outBuffer.rowBytes, NULL, NULL, NULL, &nnb); if (status != kCVReturnSuccess) { NSLog (@"CVPixelBufferCreateWithBytes returned %d", status); @@ -772,7 +774,93 @@ - (void)captureOutput:(AVCaptureOutput *)output CVBufferRelease(nnb); } else { + uint8_t* planeAddress[planeCount]; + size_t bytesPerRow[planeCount]; + size_t height[planeCount]; + size_t width[planeCount]; + + uint8_t* targetAddress[planeCount]; + + for (int i = 0; i < planeCount; i++) { + planeAddress[i] = CVPixelBufferGetBaseAddressOfPlane(nextBuffer, i); + bytesPerRow[i] = CVPixelBufferGetBytesPerRowOfPlane(nextBuffer, i); + height[i] = CVPixelBufferGetHeightOfPlane(nextBuffer, i); + width[i] = CVPixelBufferGetWidthOfPlane(nextBuffer, i); + + targetAddress[i] = malloc(height[i] * bytesPerRow[i]); + } + + size_t wp; + size_t hp; + + uint8_t x = bytesPerRow[1] - (width[1] * 2) - 1; + for (size_t i = 0; i < height[1]; i++) { + for (size_t j = 0; j < bytesPerRow[1]; j++) { + if (j >= bytesPerRow[1] / 2) { + continue; + } + + wp = j + (i * bytesPerRow[1]); + hp = (bytesPerRow[1] - j - 1) + (bytesPerRow[1] * i); + + targetAddress[1][hp] = planeAddress[1][wp - x]; + targetAddress[1][wp] = planeAddress[1][hp - x]; + } + } + + vImage_Buffer inBuffer; + inBuffer.data = planeAddress[0]; + inBuffer.rowBytes = bytesPerRow[0]; + inBuffer.width = width[0]; + inBuffer.height = height[0]; + + vImage_Buffer outBuffer; + outBuffer.data = targetAddress[0]; + outBuffer.rowBytes = bytesPerRow[0]; + outBuffer.width = width[0]; + outBuffer.height = height[0]; + + vImage_Error err; + + err = vImageHorizontalReflect_Planar8(&inBuffer, &outBuffer, kvImageNoFlags); + + if (err != kvImageNoError) { + NSLog (@"vImageHorizontalReflect_Planar8 returned %ld", err); + + for (int i = 0; i < planeCount; i++) { + free(targetAddress[i]); + } + + return; + } + + CVReturn status; + CVPixelBufferRef nnb = NULL; + + status = CVPixelBufferCreate(kCFAllocatorDefault, width[0], height[0], formatType, NULL, &nnb); + + if (status != kCVReturnSuccess) { + NSLog (@"CVPixelBufferCreate returned %d", status); + + return; + } + + CVPixelBufferLockBaseAddress(nnb, kCVPixelBufferLock_ReadOnly); + uint8_t *y = CVPixelBufferGetBaseAddressOfPlane(nnb, 0); + memcpy(y, targetAddress[0], height[0] * bytesPerRow[0]); + + uint8_t *uv = CVPixelBufferGetBaseAddressOfPlane(nnb, 1); + memcpy(uv, targetAddress[1], height[1] * bytesPerRow[1]); + CVPixelBufferUnlockBaseAddress(nnb, kCVPixelBufferLock_ReadOnly); + + [_videoAdaptor appendPixelBuffer:nnb withPresentationTime:nextSampleTime]; + + for (int i = 0; i < planeCount; i++) { + free(targetAddress[i]); + } + + CVBufferRelease(nnb); } CVPixelBufferUnlockBaseAddress(nextBuffer, kCVPixelBufferLock_ReadOnly); From 7fc558f563fa044bd21c0fa9cab266a8f2a66f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tar=C4=B1k=20Y=C4=B1lmaz?= Date: Fri, 8 Oct 2021 17:20:46 +0300 Subject: [PATCH 3/5] Format camera plugin on iOS --- .../camera/camera/ios/Classes/CameraPlugin.m | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index f0cd00fcf3f2..480606eae7e0 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -707,7 +707,7 @@ - (void)captureOutput:(AVCaptureOutput *)output if ([_captureDevice position] == AVCaptureDevicePositionFront) { CVPixelBufferLockBaseAddress(nextBuffer, kCVPixelBufferLock_ReadOnly); - + const Boolean isPlanar = CVPixelBufferIsPlanar(nextBuffer); size_t planeCount; if (isPlanar) { @@ -724,7 +724,7 @@ - (void)captureOutput:(AVCaptureOutput *)output size_t height = CVPixelBufferGetHeight(nextBuffer); size_t width = CVPixelBufferGetWidth(nextBuffer); - void* targetBytes = malloc(height * bytesPerRow); + void *targetBytes = malloc(height * bytesPerRow); size_t targetBytesPerRow = bytesPerRow; vImage_Buffer inBuffer; @@ -744,7 +744,7 @@ - (void)captureOutput:(AVCaptureOutput *)output err = vImageHorizontalReflect_ARGB8888(&inBuffer, &outBuffer, kvImageNoFlags); if (err != kvImageNoError) { - NSLog (@"vImageHorizontalReflect_ARGB8888 returned %ld", err); + NSLog(@"vImageHorizontalReflect_ARGB8888 returned %ld", err); free(targetBytes); targetBytes = NULL; @@ -755,11 +755,12 @@ - (void)captureOutput:(AVCaptureOutput *)output CVReturn status; CVPixelBufferRef nnb = NULL; - status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, formatType, outBuffer.data, - outBuffer.rowBytes, NULL, NULL, NULL, &nnb); - + status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, formatType, + outBuffer.data, outBuffer.rowBytes, NULL, NULL, + NULL, &nnb); + if (status != kCVReturnSuccess) { - NSLog (@"CVPixelBufferCreateWithBytes returned %d", status); + NSLog(@"CVPixelBufferCreateWithBytes returned %d", status); free(targetBytes); targetBytes = NULL; @@ -774,25 +775,25 @@ - (void)captureOutput:(AVCaptureOutput *)output CVBufferRelease(nnb); } else { - uint8_t* planeAddress[planeCount]; + uint8_t *planeAddress[planeCount]; size_t bytesPerRow[planeCount]; size_t height[planeCount]; size_t width[planeCount]; - uint8_t* targetAddress[planeCount]; - + uint8_t *targetAddress[planeCount]; + for (int i = 0; i < planeCount; i++) { planeAddress[i] = CVPixelBufferGetBaseAddressOfPlane(nextBuffer, i); bytesPerRow[i] = CVPixelBufferGetBytesPerRowOfPlane(nextBuffer, i); height[i] = CVPixelBufferGetHeightOfPlane(nextBuffer, i); width[i] = CVPixelBufferGetWidthOfPlane(nextBuffer, i); - + targetAddress[i] = malloc(height[i] * bytesPerRow[i]); } size_t wp; size_t hp; - + uint8_t x = bytesPerRow[1] - (width[1] * 2) - 1; for (size_t i = 0; i < height[1]; i++) { @@ -814,7 +815,7 @@ - (void)captureOutput:(AVCaptureOutput *)output inBuffer.rowBytes = bytesPerRow[0]; inBuffer.width = width[0]; inBuffer.height = height[0]; - + vImage_Buffer outBuffer; outBuffer.data = targetAddress[0]; outBuffer.rowBytes = bytesPerRow[0]; @@ -826,7 +827,7 @@ - (void)captureOutput:(AVCaptureOutput *)output err = vImageHorizontalReflect_Planar8(&inBuffer, &outBuffer, kvImageNoFlags); if (err != kvImageNoError) { - NSLog (@"vImageHorizontalReflect_Planar8 returned %ld", err); + NSLog(@"vImageHorizontalReflect_Planar8 returned %ld", err); for (int i = 0; i < planeCount; i++) { free(targetAddress[i]); @@ -838,14 +839,15 @@ - (void)captureOutput:(AVCaptureOutput *)output CVReturn status; CVPixelBufferRef nnb = NULL; - status = CVPixelBufferCreate(kCFAllocatorDefault, width[0], height[0], formatType, NULL, &nnb); + status = + CVPixelBufferCreate(kCFAllocatorDefault, width[0], height[0], formatType, NULL, &nnb); if (status != kCVReturnSuccess) { - NSLog (@"CVPixelBufferCreate returned %d", status); + NSLog(@"CVPixelBufferCreate returned %d", status); return; } - + CVPixelBufferLockBaseAddress(nnb, kCVPixelBufferLock_ReadOnly); uint8_t *y = CVPixelBufferGetBaseAddressOfPlane(nnb, 0); memcpy(y, targetAddress[0], height[0] * bytesPerRow[0]); @@ -862,7 +864,7 @@ - (void)captureOutput:(AVCaptureOutput *)output CVBufferRelease(nnb); } - + CVPixelBufferUnlockBaseAddress(nextBuffer, kCVPixelBufferLock_ReadOnly); } else { [_videoAdaptor appendPixelBuffer:nextBuffer withPresentationTime:nextSampleTime]; From b6cadce4d924fcd0ff96dadf3745afe036320adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tar=C4=B1k=20Y=C4=B1lmaz?= Date: Sat, 9 Oct 2021 13:55:41 +0300 Subject: [PATCH 4/5] Update change log and version --- packages/camera/camera/CHANGELOG.md | 4 ++-- packages/camera/camera/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index c9dfc63eb46c..bd4d46674b1a 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,6 +1,6 @@ -## NEXT +## 0.9.5+1 -* Updated package description. +* Update front camera mirroring on iOS. ## 0.9.4+1 diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 21892b213781..91415f2519a4 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing Dart. repository: https://github.com/flutter/plugins/tree/master/packages/camera/camera issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.4+1 +version: 0.9.5+1 environment: sdk: ">=2.14.0 <3.0.0" From 6c01e10d5f5eef5c802dde071e4be8027f376b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tar=C4=B1k=20Y=C4=B1lmaz?= Date: Sat, 9 Oct 2021 14:02:26 +0300 Subject: [PATCH 5/5] Update version --- packages/camera/camera/CHANGELOG.md | 2 +- packages/camera/camera/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index bd4d46674b1a..6f0ce8dcab26 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.9.5+1 +## 0.9.4+2 * Update front camera mirroring on iOS. diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 91415f2519a4..f68d026b206c 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing Dart. repository: https://github.com/flutter/plugins/tree/master/packages/camera/camera issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.5+1 +version: 0.9.4+2 environment: sdk: ">=2.14.0 <3.0.0"