public int getNativeCameraHardRotation(boolean preview) {
   int terminalRotation = getTerminalRotation();
   boolean isFront = NgnCameraProducer.isFrontFacingCameraEnabled();
   if (NgnApplication.isSamsung()) {
     if (preview) {
       if (isFront) {
         if (terminalRotation == 0) return 0;
         else return 90;
       } else return 0;
     } else {
       if (isFront) {
         if (terminalRotation == 0) return -270;
         else return 90;
       } else {
         if (terminalRotation == 0) return 0;
         else return 0;
       }
     }
   } else if (NgnApplication.isToshiba()) {
     if (preview) {
       if (terminalRotation == 0) return 0;
       else return 270;
     } else {
       return 0;
     }
   } else {
     return 0;
   }
 }
 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
   Log.d(TAG, "Destroy Preview");
   try {
     NgnCameraProducer.releaseCamera();
   } catch (Exception exception) {
     Log.e(TAG, exception.toString());
   }
 }
 public void toggleCamera() {
   if (super.mValid && super.mStarted && !super.mPaused && mProducer != null) {
     final Camera camera = NgnCameraProducer.toggleCamera();
     try {
       startCameraPreview(camera);
     } catch (Exception exception) {
       Log.e(TAG, exception.toString());
     }
   }
 }
 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
   Log.d(TAG, "Surface Changed Callback");
   final Camera camera = NgnCameraProducer.getCamera();
   try {
     myProducer.startCameraPreview(camera);
   } catch (Exception exception) {
     Log.e(TAG, exception.toString());
   }
 }
        public void onPreviewFrame(byte[] _data, Camera _camera) {
          if (NgnProxyVideoProducer.super.mValid) {
            mVideoFrame.put(_data);
            mProducer.push(mVideoFrame, mVideoFrame.capacity());
            mVideoFrame.rewind();

            if (NgnProxyVideoProducer.sAddCallbackBufferSupported) {
              NgnCameraProducer.addCallbackBuffer(_camera, _data);
            }
          }
        }
  private void startCameraPreview(Camera camera) {
    if (camera != null && mProducer != null && mVideoFrame != null) {
      try {
        Log.d(TAG, String.format("setPreviewSize [%d x %d ]", mWidth, mHeight));
        Camera.Parameters parameters = camera.getParameters();
        parameters.setPreviewSize(mWidth, mHeight);
        camera.setParameters(parameters);
      } catch (Exception e) {
        Log.e(TAG, e.toString());
      }

      try {
        int terminalRotation = getTerminalRotation();
        Camera.Parameters parameters = camera.getParameters();
        if (terminalRotation == 0) {
          parameters.set("orientation", "landscape");
        } else {
          parameters.set("orientation", "portrait");
        }
        camera.setParameters(parameters);
      } catch (Exception e) {
        Log.e(TAG, e.toString());
      }

      // Camera Orientation
      int rotation = compensCamRotation(false);
      Log.d(TAG, String.format("setDisplayOrientation [%d] ", rotation));
      NgnCameraProducer.setDisplayOrientation(camera, rotation);

      // Callback Buffers
      if (NgnProxyVideoProducer.sAddCallbackBufferSupported) {
        for (int i = 0; i < NgnProxyVideoProducer.CALLABACK_BUFFERS_COUNT; i++) {
          NgnCameraProducer.addCallbackBuffer(camera, new byte[mVideoFrame.capacity()]);
        }
      }

      camera.startPreview();
    }
  }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
      try {
        /*final Camera camera =*/ NgnCameraProducer.openCamera(
            myProducer.mFps,
            myProducer.mWidth,
            myProducer.mHeight,
            mHolder,
            myProducer.previewCallback);

      } catch (Exception exception) {
        Log.e(TAG, exception.toString());
      }
    }
  public void setOnPause(boolean pause) {
    if (super.mPaused == pause) {
      return;
    }
    try {
      if (super.mStarted) {
        final Camera camera = NgnCameraProducer.getCamera();
        if (pause) {
          camera.stopPreview();
        } else {
          camera.startPreview();
        }
      }
    } catch (Exception e) {
      Log.e(TAG, e.toString());
    }

    super.mPaused = pause;
  }
/** MyProxyVideoProducer */
public class NgnProxyVideoProducer extends NgnProxyPlugin {
  private static final String TAG = NgnProxyVideoProducer.class.getCanonicalName();
  private static final int DEFAULT_VIDEO_WIDTH = 176;
  private static final int DEFAULT_VIDEO_HEIGHT = 144;
  private static final int DEFAULT_VIDEO_FPS = 15;
  private static final int CALLABACK_BUFFERS_COUNT = 3;
  private static final boolean sAddCallbackBufferSupported =
      NgnCameraProducer.isAddCallbackBufferSupported();

  private final ProxyVideoProducer mProducer;
  private final MyProxyVideoProducerCallback mCallback;
  private Context mContext;
  private MyProxyVideoProducerPreview mPreview;
  private int mWidth;
  private int mHeight;
  private int mFps;
  private ByteBuffer mVideoFrame;

  public NgnProxyVideoProducer(BigInteger id, ProxyVideoProducer producer) {
    super(id, producer);
    mCallback = new MyProxyVideoProducerCallback(this);
    mProducer = producer;
    mProducer.setCallback(mCallback);

    // Initialize video stream parameters with default values
    mWidth = NgnProxyVideoProducer.DEFAULT_VIDEO_WIDTH;
    mHeight = NgnProxyVideoProducer.DEFAULT_VIDEO_HEIGHT;
    mFps = NgnProxyVideoProducer.DEFAULT_VIDEO_FPS;
  }

  public void setContext(Context context) {
    mContext = context;
  }

  // Very important: Must be done in the UI thread
  public final View startPreview(Context context) {
    mContext = context == null ? mContext : context;
    if (mPreview == null && mContext != null) {
      mPreview = new MyProxyVideoProducerPreview(this);
    }
    if (mPreview != null) {
      mPreview.setVisibility(View.VISIBLE);
      mPreview.getHolder().setSizeFromLayout();
      mPreview.bringToFront();
    }

    return mPreview;
  }

  public final View startPreview() {
    return startPreview(null);
  }

  public void pushBlankPacket() {
    if (super.mValid && mProducer != null && mVideoFrame != null) {
      final ByteBuffer buffer = ByteBuffer.allocateDirect(mVideoFrame.capacity());
      mProducer.push(buffer, buffer.capacity());
    }
  }

  public void toggleCamera() {
    if (super.mValid && super.mStarted && !super.mPaused && mProducer != null) {
      final Camera camera = NgnCameraProducer.toggleCamera();
      try {
        startCameraPreview(camera);
      } catch (Exception exception) {
        Log.e(TAG, exception.toString());
      }
    }
  }

  public int getTerminalRotation() {
    android.content.res.Configuration conf =
        NgnApplication.getContext().getResources().getConfiguration();
    int terminalRotation = 0;
    switch (conf.orientation) {
      case android.content.res.Configuration.ORIENTATION_LANDSCAPE:
        terminalRotation = 0; // The starting position is 0 (landscape).
        break;
      case android.content.res.Configuration.ORIENTATION_PORTRAIT:
        terminalRotation = 90;
        break;
    }
    return terminalRotation;
  }

  public int getNativeCameraHardRotation(boolean preview) {
    int terminalRotation = getTerminalRotation();
    boolean isFront = NgnCameraProducer.isFrontFacingCameraEnabled();
    if (NgnApplication.isSamsung()) {
      if (preview) {
        if (isFront) {
          if (terminalRotation == 0) return 0;
          else return 90;
        } else return 0;
      } else {
        if (isFront) {
          if (terminalRotation == 0) return -270;
          else return 90;
        } else {
          if (terminalRotation == 0) return 0;
          else return 0;
        }
      }
    } else if (NgnApplication.isToshiba()) {
      if (preview) {
        if (terminalRotation == 0) return 0;
        else return 270;
      } else {
        return 0;
      }
    } else {
      return 0;
    }
  }

  public int compensCamRotation(boolean preview) {
    int cameraHardRotation = getNativeCameraHardRotation(preview);
    int rotation = 0;
    int terminalRotation = getTerminalRotation();
    rotation = (terminalRotation - cameraHardRotation) % 360;
    return rotation;
  }

  public boolean isFrontFacingCameraEnabled() {
    return NgnCameraProducer.isFrontFacingCameraEnabled();
  }

  public void setRotation(int rot) {
    if (mProducer != null && super.mValid) {
      mProducer.setRotation(rot);
    }
  }

  public void setOnPause(boolean pause) {
    if (super.mPaused == pause) {
      return;
    }
    try {
      if (super.mStarted) {
        final Camera camera = NgnCameraProducer.getCamera();
        if (pause) {
          camera.stopPreview();
        } else {
          camera.startPreview();
        }
      }
    } catch (Exception e) {
      Log.e(TAG, e.toString());
    }

    super.mPaused = pause;
  }

  private int prepareCallback(int width, int height, int fps) {
    Log.d(NgnProxyVideoProducer.TAG, "prepareCallback(" + width + "," + height + "," + fps + ")");

    mWidth = width;
    mHeight = height;
    mFps = fps;

    final float capacity = (float) (width * height) * 1.5f /* (3/2) */;
    mVideoFrame = ByteBuffer.allocateDirect((int) capacity);
    super.mPrepared = true;

    return 0;
  }

  private int startCallback() {
    Log.d(TAG, "startCallback");
    this.mStarted = true;
    return 0;
  }

  private int pauseCallback() {
    Log.d(TAG, "pauseCallback");
    setOnPause(true);
    return 0;
  }

  private int stopCallback() {
    Log.d(TAG, "stopCallback");

    mPreview = null;
    mContext = null;
    super.mStarted = false;

    return 0;
  }

  private void startCameraPreview(Camera camera) {
    if (camera != null && mProducer != null && mVideoFrame != null) {
      try {
        Log.d(TAG, String.format("setPreviewSize [%d x %d ]", mWidth, mHeight));
        Camera.Parameters parameters = camera.getParameters();
        parameters.setPreviewSize(mWidth, mHeight);
        camera.setParameters(parameters);
      } catch (Exception e) {
        Log.e(TAG, e.toString());
      }

      try {
        int terminalRotation = getTerminalRotation();
        Camera.Parameters parameters = camera.getParameters();
        if (terminalRotation == 0) {
          parameters.set("orientation", "landscape");
        } else {
          parameters.set("orientation", "portrait");
        }
        camera.setParameters(parameters);
      } catch (Exception e) {
        Log.e(TAG, e.toString());
      }

      // Camera Orientation
      int rotation = compensCamRotation(false);
      Log.d(TAG, String.format("setDisplayOrientation [%d] ", rotation));
      NgnCameraProducer.setDisplayOrientation(camera, rotation);

      // Callback Buffers
      if (NgnProxyVideoProducer.sAddCallbackBufferSupported) {
        for (int i = 0; i < NgnProxyVideoProducer.CALLABACK_BUFFERS_COUNT; i++) {
          NgnCameraProducer.addCallbackBuffer(camera, new byte[mVideoFrame.capacity()]);
        }
      }

      camera.startPreview();
    }
  }

  private PreviewCallback previewCallback =
      new PreviewCallback() {
        public void onPreviewFrame(byte[] _data, Camera _camera) {
          if (NgnProxyVideoProducer.super.mValid) {
            mVideoFrame.put(_data);
            mProducer.push(mVideoFrame, mVideoFrame.capacity());
            mVideoFrame.rewind();

            if (NgnProxyVideoProducer.sAddCallbackBufferSupported) {
              NgnCameraProducer.addCallbackBuffer(_camera, _data);
            }
          }
        }
      };

  /** * MyProxyVideoProducerPreview */
  class MyProxyVideoProducerPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private final NgnProxyVideoProducer myProducer;

    MyProxyVideoProducerPreview(NgnProxyVideoProducer _producer) {
      super(_producer.mContext);

      myProducer = _producer;
      mHolder = getHolder();
      mHolder.addCallback(this);
      mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
      try {
        /*final Camera camera =*/ NgnCameraProducer.openCamera(
            myProducer.mFps,
            myProducer.mWidth,
            myProducer.mHeight,
            mHolder,
            myProducer.previewCallback);

      } catch (Exception exception) {
        Log.e(TAG, exception.toString());
      }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
      Log.d(TAG, "Destroy Preview");
      try {
        NgnCameraProducer.releaseCamera();
      } catch (Exception exception) {
        Log.e(TAG, exception.toString());
      }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
      Log.d(TAG, "Surface Changed Callback");
      final Camera camera = NgnCameraProducer.getCamera();
      try {
        myProducer.startCameraPreview(camera);
      } catch (Exception exception) {
        Log.e(TAG, exception.toString());
      }
    }
  }

  /** MyProxyVideoProducerCallback */
  static class MyProxyVideoProducerCallback extends ProxyVideoProducerCallback {
    final NgnProxyVideoProducer myProducer;

    public MyProxyVideoProducerCallback(NgnProxyVideoProducer producer) {
      super();
      myProducer = producer;
    }

    @Override
    public int prepare(int width, int height, int fps) {
      return myProducer.prepareCallback(width, height, fps);
    }

    @Override
    public int start() {
      return myProducer.startCallback();
    }

    @Override
    public int pause() {
      return myProducer.pauseCallback();
    }

    @Override
    public int stop() {
      return myProducer.stopCallback();
    }
  }
}
 public boolean isFrontFacingCameraEnabled() {
   return NgnCameraProducer.isFrontFacingCameraEnabled();
 }