package org.deviceconnect.android.deviceplugin.theta.profile; import android.graphics.Bitmap; import org.deviceconnect.android.deviceplugin.theta.core.SphericalViewRenderer; import org.deviceconnect.android.deviceplugin.theta.opengl.PixelBuffer; import java.io.ByteArrayOutputStream; import java.nio.IntBuffer; class DefaultProjector extends AbstractProjector { private PixelBuffer mPixelBuffer; private Thread mThread; private boolean mIsRequestedToStop; private byte[] mImageCache; @Override public void setRenderer(final SphericalViewRenderer renderer) { super.setRenderer(renderer); mRenderer.setSurfaceListener(this); } @Override public boolean start() { if (mThread != null) { return false; } if (mScreen == null) { return false; } mThread = new Thread(new Runnable() { @Override public void run() { try { mScreen.onStart(DefaultProjector.this); while(!mIsRequestedToStop) { long start = System.currentTimeMillis(); if (mIsChangedImageSize) { disposeBuffer(); prepareBuffer(); mRenderer.requestToUpdateTexture(); mIsChangedImageSize = false; } draw(); readBuffer(); long end = System.currentTimeMillis(); long interval = 100 - (end - start); if (interval > 0) { Thread.sleep(interval); } } } catch (InterruptedException e) { // Nothing to do. } catch (Throwable e) { e.printStackTrace(); } finally { mIsRequestedToStop = false; mThread = null; disposeBuffer(); mScreen.onStop(DefaultProjector.this); } } }); mThread.start(); return true; } @Override public boolean stop() { if (mThread == null) { return false; } mIsRequestedToStop = true; return true; } @Override public byte[] getImageCache() { return mImageCache; } private void prepareBuffer() { if (mPixelBuffer == null) { int width = mRenderer.getScreenWidth(); int height = mRenderer.getScreenHeight(); boolean isStereo = mRenderer.isStereo(); mPixelBuffer = new PixelBuffer(width, height, isStereo); mPixelBuffer.setRenderer(mRenderer); } } private void disposeBuffer() { if (mPixelBuffer != null) { mPixelBuffer.destroy(); mPixelBuffer = null; } } private void readBuffer() { Bitmap b = mPixelBuffer.convertToBitmap(); reverse(b); ByteArrayOutputStream baos = new ByteArrayOutputStream(); b.compress(Bitmap.CompressFormat.JPEG, 100, baos); byte[] jpeg = baos.toByteArray(); mImageCache = jpeg; mScreen.onProjected(this, jpeg); } private void reverse(final Bitmap b) { int width = b.getWidth(); int height = b.getHeight(); IntBuffer buf = IntBuffer.allocate(width * height); IntBuffer tmp = IntBuffer.allocate(width * height); b.copyPixelsToBuffer(buf); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { tmp.put((height - i - 1) * width + j, buf.get(i * width + j)); } } b.copyPixelsFromBuffer(tmp); buf.clear(); } protected void draw() { mPixelBuffer.render(); } }