airsdk / Adobe-Runtime-Support

Report, track and discuss issues in Adobe AIR. Monitored by Adobe - and HARMAN - and maintained by the AIR community.
200 stars 11 forks source link

[Android] Camera usage cause terrible performance #1980

Open itlancer opened 2 years ago

itlancer commented 2 years ago

Problem Description

Camera usage cause terrible performance with Android devices. In Scout you can see that "Other overhead" take about 15-20 ms each camera frame when application uses Camera even with high-end devices with powerful CPUs. This cause many lags and low performance for any AIR application that uses camera with Android devices.

May be it related that AIR still uses legacy Android Camera API https://developer.android.com/guide/topics/media/camera, not CameraX https://developer.android.com/training/camerax or Camera2 https://developer.android.com/reference/android/hardware/camera2/package-summary.

Tested with multiple AIR versions, even with latest AIR 33.1.1.889 with multiple different Android devices (armv7, armv8, smartphones, tablets, TV Boxes) with different OS versions with different cameras (embedded and external USB). Same problem in all cases. Higher camera resolution cause more lags. There is no such issues with Windows, macOS and iOS devices.

Steps to Reproduce

Launch code below with any Android device with camera. It just start camera and display it.

Application example with sources and Scout log attached. android_camera_lags.zip

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.media.Camera;
    import flash.media.Video;
    import flash.events.PermissionEvent;
    import flash.permissions.PermissionManager;
    import flash.permissions.PermissionStatus;

    public class AndroidCameraLags extends Sprite {
        private var video:Video;

        public function AndroidCameraLags() {
            addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            var cameraPermissionManager:PermissionManager = Camera.permissionManager;
            if (cameraPermissionManager.permissionStatus != PermissionStatus.GRANTED){
                Camera.permissionManager.addEventListener(PermissionEvent.PERMISSION_STATUS, permissionChanged);
                Camera.permissionManager.requestPermission();
            } else {
                startCamera();
            }
        }

        private function permissionChanged(e:PermissionEvent):void {
            trace("permissionChanged", Camera.permissionManager.permissionStatus);
            startCamera();
        }

        private function startCamera():void {
            var cameras:Array = Camera.names;
            trace(cameras);
            var camera:Camera = Camera.getCamera();
            camera.setMode(1920, 1080, 60, true);
            trace("Camera settings:", camera.width + "x" + camera.height, camera.fps);

            video = new Video();
            video.attachCamera(camera);
            addChild(video);
        }
    }
}

Actual Result: Application low performance. In Scout you can see that "Other overhead" take about 15-20 ms each camera frame. image

Expected Result: No performance issues.

Known Workarounds

none May be write own native extension for camera usage.

MalacTheLittle commented 2 years ago

Just wondering do you have <containsVideo>true</containsVideo> inside android tag in manifest? Screen goes black when you run first video in app if it's not there, so maybe it's also somehow connected to your problem...

itlancer commented 2 years ago

@MalacTheLittle

No matter which containsVideo value will be used. Low performance in both cases. Also no matter which disableMediaCodec value will be used. Also the same issue if you try to use VideoTexture instead of Video to display camera. In real applications I use <containsVideo>true</containsVideo> to avoid some video issues. But I think it not related to this issue.