camera: previewRotationQuarterTurns + async previewSize event
Black-screen + extra-90°-rotation on Android both came from
AVFoundation vs CameraX behaving differently at the preview output:
- AVFoundation: data-output connection's `videoOrientation`
pre-rotates sample buffers. The Flutter Texture displays them
upright; `device.activeFormat` reports the sensor-native size
synchronously.
- CameraX: the SurfaceProvider hands back a Surface; CameraX
writes raw sensor frames into it. Rotation is a *transform hint*
via Preview.setTargetRotation that consumers must apply
themselves. And the final negotiated resolution isn't known
until the first SurfaceRequest fires — which happens AFTER
bindToLifecycle, AFTER lifecycle.start, async on the camera
executor. So `create` was returning Size(0,0).
Surface extension to bridge the gap:
- UxCameraValue.previewRotationQuarterTurns (int 0/1/2/3).
iOS native always emits 0; Android native emits
`(sensorRotationDegrees / 90) % 4` for the active camera.
[UxCameraPreview] wraps the Texture in a RotatedBox by that many
quarter-turns (applied *before* the front-cam mirror so the
flip lives in screen space, not sensor space).
- UxCameraPreviewSizeChanged event. Android emits this from
PreviewSink.onResize whenever a SurfaceRequest carries a new
resolution; the controller copies it into value.previewSize.
First emission is what unblocks the camera_thumb's SizedBox
from its initial 0x0 = "render nothing" state.
- UxCameraBackend.setDescription's return changed from `Size` to
`({Size previewSize, int previewRotationQuarterTurns})` so
a lens swap can both update the rotation and signal that a new
previewSizeChanged event is incoming.
iOS continues to send previewSize in the create result (the active
format is known synchronously); no previewSizeChanged emission is
needed there. The new field is set to 0 in both create and
setDescription results on iOS.
This commit is contained in:
@@ -136,7 +136,8 @@ public class CameraPlugin: NSObject, NativePlugin, FlutterStreamHandler {
|
||||
"previewSize": [
|
||||
"width": size.width,
|
||||
"height": size.height,
|
||||
]
|
||||
],
|
||||
"previewRotationQuarterTurns": 0,
|
||||
])
|
||||
}
|
||||
} catch let error as NSError {
|
||||
@@ -344,6 +345,10 @@ public class CameraPlugin: NSObject, NativePlugin, FlutterStreamHandler {
|
||||
"width": size.width,
|
||||
"height": size.height,
|
||||
],
|
||||
// iOS pre-rotates frames via the data-output
|
||||
// connection's videoOrientation, so the Flutter
|
||||
// Texture displays upright as-is.
|
||||
"previewRotationQuarterTurns": 0,
|
||||
])
|
||||
}
|
||||
} catch let error as NSError {
|
||||
|
||||
Reference in New Issue
Block a user