using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using SLAMUVC;
using UnityEngine.UI;
using System.Collections.Generic;
using AOT;
using System.Threading;
using UnityEngine.Events;
using UnityEngine.Android;
namespace SLAMUVC
{
//UVC������
public class UVCInterface_Android : UVCInterface
{
private const string UVC_MANAGER = "com.slambb.myuvc.MyUVCManager";
//java����
private AndroidJavaObject uvcManagerObj = null;
CameraFormat mCameraFormat = CameraFormat.MJPEG;
CameraMirror mCameraMirror = CameraMirror.VERTICAL;//Ĭ�ϴ�ֱ
int Width = 1280;
int Height = 720;
Texture2D _cameraTexture;
public override Texture2D CameraTexture => _cameraTexture;
private UVCCtrl[] uvcCtrls;
public override UVCCtrl[] UVCCtrls => uvcCtrls;
//修改时候的分辨率
int[] tempSize = new int[2] { 1280, 720 };
public override int[] tempCameraSize => tempSize;
private SynchronizationContext mainContext;
/////
///// ��ʼ�����Ȩ�ɹ�
/////
//public CameraPermissionHandle systemCameraPermissionHandle;
//public void CameraPermissionHandle();
/////
///// ��������¼�
/////
//public CameraTextureHandle cameraTextureHandle;
//public void CameraTextureHandle();
private static readonly string ActivityClassName = "com.slambb.myuvc.UsbPermissionActivity";
//public void RequestUsbPermission()
//{
// using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
// {
// AndroidJavaObject activity = unityPlayer.GetStatic("currentActivity");
// AndroidJavaClass usbPermissionActivity = new AndroidJavaClass(ActivityClassName);
// // Start UsbPermissionActivity
// activity.Call("startActivity", usbPermissionActivity.CallStatic("newIntent", activity));
// }
//}
void Awake()
{
try
{
// ���� uvcManagerObj ����
uvcManagerObj = new AndroidJavaObject(UVC_MANAGER);
}
catch (Exception e)
{
Debug.LogError("UVC_MANAGER Exception: " + e.Message);
}
//RequestUsbPermission();
}
void Start()
{
OpenCameraPermisson();
}
private void OnDestroy()
{
Remove(this);
uvcManagerObj.Call("clearCameraHelper");
}
///
/// ����һ������id�����
///
private void CreateTextureAndPassToPlugin()
{
// ��������
if (_cameraTexture != null)
{
Destroy(_cameraTexture);
_cameraTexture = null;
}
// Create a texture
Texture2D tex = new Texture2D(Width, Height, TextureFormat.ARGB32, false);
// ���õ���ˣ��Ա����ǿ�������ؿ�������
tex.filterMode = FilterMode.Point;
// ����Apply()��ʹ��ʵ���ϴ���GPU
tex.Apply();
_cameraTexture = tex;
//������ָ�봫�ݸ����
SetTexture(tex.GetNativeTexturePtr(), tex.width, tex.height);
//cameraTextureHandle?.Invoke();
OnCameraTextureUpdated();
}
//private IEnumerator CallPluginAtEndOfFrames()
//{
// while (true)
// {
// //�ȴ�����֡��Ⱦ���
// yield return new WaitForEndOfFrame();
// //������������������ʶ���IJ���¼���
// //�ò���������ֲ�ͬ��
// //����Ҫ�������ID�������顣
// //�������ǵļ�������������ﴫ���ĸ�ID������Ҫ��
// if(GetIsPreviewing()) GL.IssuePluginEvent(GetRenderEventFunc(), 1);
// }
//}
///
/// ��������
///
///
///
///
public override void OnTextureUpdate(int width, int height, bool bUpdate)
{
mainContext.Post(__ =>
{
if (bUpdate)
{
Debug.Log("�����������size=[" + width + "," + height + "]");
Width = width;
Height = height;
CreateTextureAndPassToPlugin();
}
else
{
GL.IssuePluginEvent(GetRenderEventFunc(), 1);
}
}, null);
}
public override bool GetIsPreviewing()
{
if (uvcManagerObj != null)
{
if (uvcManagerObj.Call("GetIsPreviewing") == 1)
{
return true;
}
}
return false;
}
///
/// ��ʼ������Ͷ�Ӧ�IJ�������ʼ������Զ������
///
///
///
public override void InitCamera(int width, int height)
{
Width = width;
Height = height;
uvcManagerObj.Call("initCameraHelper", Width, Height, mCameraFormat.ToString(), mCameraMirror.ToString());
//���߳�
mainContext = SynchronizationContext.Current;
//ע��c�ص�
Add(this);
//mainContext.Post(__ =>
//{
// //CreateTextureAndPassToPlugin();
//}, null);
//StartCoroutine("CallPluginAtEndOfFrames");
}
public override void OpenCamera()
{
uvcManagerObj.Call("OpenCamera");
}
public override void CloseCamera()
{
uvcManagerObj.Call("CloseCamera");
}
public override void ChangeCameraInfo(int width, int height)
{
uvcManagerObj.Call("ChangeCameraInfo", width, height, mCameraFormat.ToString());
}
public override string[] GetSupportedResolutions()
{
if (uvcManagerObj != null)
{
var objPtr = uvcManagerObj.Call("GetSupportedResolutions").GetRawObject();
if (objPtr != IntPtr.Zero)
return AndroidJNIHelper.ConvertFromJNIArray(objPtr);
}
return null;
}
///
/// ˮƽ��ת
///
public override void FlipHorizontally()
{
uvcManagerObj.Call("FlipHorizontally");
}
///
/// ��ֱ��ת
///
public override void FlipVertically()
{
uvcManagerObj.Call("FlipVertically");
}
public override void resetControlParams()
{
uvcManagerObj.Call("resetControlParams");
}
public override string GetUvcCtrlList()
{
if (uvcManagerObj != null)
{
string json = uvcManagerObj.Call("GetUvcCtrlList");
UVCCtrlWrapper wrapper = JsonUtility.FromJson("{\"uvcCtrls\":" + json + "}");
if (wrapper != null && wrapper.uvcCtrls != null)
{
//��ֵ
uvcCtrls = wrapper.uvcCtrls;
//foreach (UVCCtrl ctrl in wrapper.uvcCtrls)
//{
// Debug.Log($"name:{ctrl.name}, isAuto: {ctrl.isAuto}, isEnable: {ctrl.isEnable}, limit: {string.Join(", ", ctrl.limit)}, value: {ctrl.value}");
//}
}
else
{
Debug.LogError("Failed to parse JSON data.");
}
}
return "";
}
public override void SetBrightness(int value)
{
uvcManagerObj.Call("SetBrightness", value);
}
public override void SetContrast(int value)
{
uvcManagerObj.Call("SetContrast", value);
}
public override int SetCtrlValue(string type, Int32 value)
{
int result = -1;
if (type == "PU_BRIGHTNESS")
{
uvcManagerObj.Call("SetBrightness", value);
result = 0;
}
else if (type == "PU_CONTRAST")
{
uvcManagerObj.Call("SetContrast", value);
result = 0;
}
return result;
}
//--------------------------------------------------------------------------------
/**
* �ȴ������Ȩ��
*/
private void OpenCameraPermisson()
{
if (Permission.HasUserAuthorizedPermission(Permission.Camera))
{
Debug.LogError("HasUserAuthorizedPermission��");
//systemCameraPermissionHandle?.Invoke();
OnCameraPermissionGranted();
return;
}
bool useCallbacks = true;
if (!useCallbacks)
{
// We do not have permission to use the microphone.
// Ask for permission or proceed without the functionality enabled.
Permission.RequestUserPermission(Permission.Camera);
}
else
{
var callbacks = new PermissionCallbacks();
callbacks.PermissionDenied += PermissionCallbacks_PermissionDenied;
callbacks.PermissionGranted += PermissionCallbacks_PermissionGranted;
callbacks.PermissionDeniedAndDontAskAgain += PermissionCallbacks_PermissionDeniedAndDontAskAgain;
Permission.RequestUserPermission(Permission.Camera, callbacks);
}
}
void PermissionCallbacks_PermissionDenied(string PermissionName)
{
Debug.LogError($"PermissionCallbacks_PermissionDenied[{PermissionName}]");
}
//��������
void PermissionCallbacks_PermissionGranted(string PermissionName)
{
Debug.Log($"PermissionCallbacks_PermissionGranted[{PermissionName}]");
//systemCameraPermissionHandle?.Invoke();
OnCameraPermissionGranted();
}
void PermissionCallbacks_PermissionDeniedAndDontAskAgain(string PermissionName)
{
Debug.Log($"PermissionCallbacks_PermissionDeniedAndDontAskAgain[{PermissionName}]");
//systemCameraPermissionHandle?.Invoke();
OnCameraPermissionGranted();
}
//����GL����
[DllImport("TransferTexture")]
private static extern void SetTexture(IntPtr texture, int w, int h);
//GL��Ⱦ�¼�
[DllImport("TransferTexture")]
private static extern IntPtr GetRenderEventFunc();
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void TextureUpdateDelegate(Int32 id, int width, int height, bool bUpdate);
[DllImport("TransferTexture")]
private static extern void RegisterTextureUpdateCallback(Int32 id, TextureUpdateDelegate callback);
[DllImport("TransferTexture")]
private static extern void UnregisterTextureUpdateCallback(Int32 id, TextureUpdateDelegate callback);
//��¼MyUVCInterface
private static Dictionary mUVCInterfaces = new Dictionary();
private static TextureUpdateDelegate textureUpdateDelegate;
//ע��ص��¼�
public static void Add(UVCInterface myUVCInterface)
{
Int32 id = myUVCInterface.GetHashCode();
textureUpdateDelegate = new TextureUpdateDelegate(TextureUpdateHandler);
mUVCInterfaces.Add(id, myUVCInterface);
RegisterTextureUpdateCallback(id, textureUpdateDelegate);
}
//�Ƴ��ص��¼�
public static void Remove(UVCInterface myUVCInterface)
{
Int32 id = myUVCInterface.GetHashCode();
UnregisterTextureUpdateCallback(id, textureUpdateDelegate);
mUVCInterfaces.Remove(id);
}
//���ݸ���ʱ��ص�
[MonoPInvokeCallback(typeof(TextureUpdateDelegate))]
private static void TextureUpdateHandler(Int32 id, int width, int height, bool bUpdate)
{
var myUVCInterface = mUVCInterfaces.ContainsKey(id) ? mUVCInterfaces[id] : null;
if (myUVCInterface != null)
{
myUVCInterface.OnTextureUpdate(width, height, bUpdate);
}
}
public override void ChangeCameraInfoCallback(int width, int height)
{
throw new NotImplementedException();
}
}
}