1

Folks,

I'm developing screen capture application on Android that using MediaProjection API.

I'm using ImageReader to realize it but Image.getPlanes() is too heavy to capture realtime screen.

It lost too much frames to see smooth rendered screen since Image.getPlanes() blocks main thread. When I commented it out, ImageReader acquires many images than before.

I cannot do Image.getPlanes() in background since onImageAvailable is called after Image.close() is called.

So, my questions are:

  • Why is Image.getPlanes() so heavy?
  • Is there any way to realize smooth screen capture?

The code is as follows.

public void onImageAvailable(ImageReader reader) {

    try {

        Image img = reader.acquireLatestImage();

        //Too heavy!!
        Image.Plane[] planes = img.getPlanes();

        /* Do something */

        img.close();

    }catch (Exception e){
        setImageReader();
    }
}

Thank for your helps!

Question updated

//Background process example
@Override
public void onImageAvailable(ImageReader reader) {

    try {

        final Image img = reader.acquireLatestImage();

        new Thread(new Runnable() {
            @Override
            public void run() {

                Image.Plane[] planes = img.getPlanes();

                /* Do something */

                img.close();
                //onImageAvailable is no called Until here.
                //Because ImageReader is locked from ImageReader.acquireLatestImage() to Image.close()

            }
        }).start();

    }catch(Exception e){}
}
  • Check the example how to put this heavy operation to background http://www.programcreek.com/java-api-examples/index.php?source_dir=LiveMultimedia-master/app/src/main/java/com/constantinnovationsinc/livemultimedia/cameras/LollipopCamera.java – Eugen Martynov Aug 10 '16 at 04:58
  • onImageAvailable() is not called(blocked) untils call Image.close() event though it is runninng on background. – Taichiro Suzuki Aug 10 '16 at 05:43
  • Sorry, I thought it is easy case. Don't have much expertise – Eugen Martynov Aug 10 '16 at 06:01
  • I'm developing more than 100 Android applications and I don't think this is easy case. If you think so, may be my bad English misleads something. – Taichiro Suzuki Aug 10 '16 at 06:07
  • Yeah, sorry, my English is not perfect also. Last comment was excuses for treating this post as easy case – Eugen Martynov Aug 10 '16 at 06:15
  • I don't understand why you can't perform `getPlanes()` on a background `Thread`. In your code snippet `img.close()` is called _after_ the `getPlanes()` call. – earthw0rmjim Aug 10 '16 at 06:25
  • Oh thanks for your reply! Could you tell me an idea to realize this? – Taichiro Suzuki Aug 10 '16 at 06:31
  • @user13 I updated my question that added some codes. Please check it. Thanks! – Taichiro Suzuki Aug 10 '16 at 06:45
  • Here is another example that handles it on different thread https://github.com/commonsguy/cw-omnibus/blob/v7.5/MediaProjection/andprojector/app/src/main/java/com/commonsware/andprojector/ProjectorService.java. The problem is not to block UI thread solved, but problem that image processing takes a lot of time is not. But I don't know how you can solve it without the hardware update. If you would able to receive more onImage calls, you still will stuck with processing of them, the pile will just grow without or with control – Eugen Martynov Aug 10 '16 at 06:50
  • @EugenMartynov Thanks for giving me a sample code. I tried it but it has same problem. – Taichiro Suzuki Aug 10 '16 at 08:01

1 Answers1

0

Ok, I understand that emulators are not good at this operation.

The operation with my real device is work fine.

I will try to find options to optimize it.

Thanks for all helps.