//-------------------------------------------------------------------------------- // UVC機器接続状態が変化したときのプラグインからのコールバック関数 //-------------------------------------------------------------------------------- public void OnDeviceChanged(IntPtr devicePtr, bool attached) { var id = UVCDevice.GetId(devicePtr); #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnDeviceChanged:id={id},attached={attached}"); #endif if (attached) { UVCDevice device = new UVCDevice(devicePtr); #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnDeviceChanged:device={device.ToString()}"); #endif if (HandleOnAttachEvent(device)) { attachedDevices.Add(device); StartPreview(device); } } else { var found = attachedDevices.Find(item => { return(item != null && item.id == id); }); if (found != null) { HandleOnDetachEvent(found); StopPreview(found); attachedDevices.Remove(found); } } }
/** * 映像取得を開始した * IUVCDrawerの実装 * @param manager 呼び出し元のUVCManager * @param device 対象となるUVC機器の情報 * @param tex UVC機器からの映像を受け取るTextureインスタンス */ public void OnUVCStartEvent(UVCManager manager, UVCDevice device, Texture tex) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnUVCStartEvent:{device}"); #endif HandleOnStartPreview(device.deviceName, tex); }
/** * 映像取得を終了した * IUVCDrawerの実装 * @param manager 呼び出し元のUVCManager * @param device 対象となるUVC機器の情報 */ public void OnUVCStopEvent(UVCManager manager, UVCDevice device) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnUVCStopEvent:{device}"); #endif HandleOnStopPreview(device.deviceName); }
/** * 解像度選択 * IOnUVCSelectSizeHandlerの実装 * @param manager 呼び出し元のUVCManager * @param device 対象となるUVC機器の情報 * @param formats 対応している解像度についての情報 */ public SupportedFormats.Size OnUVCSelectSize(UVCManager manager, UVCDevice device, SupportedFormats formats) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnUVCSelectSize:{device}"); #endif if (device.IsTHETA_V) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnUVCSelectSize:THETA V"); #endif return FindSize(formats, 3840, 1920); } else if (device.IsTHETA_S) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnUVCSelectSize:THETA S"); #endif return FindSize(formats, 1920, 1080); } else { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnUVCSelectSize:other UVC device,{device}"); #endif return formats.Find(DefaultWidth, DefaultHeight); } }
/** * UVC機器のフィルタ処理用 * filtersがnullの場合はマッチしたことにする * 除外フィルターにヒットしたときはその時点で評価を終了しfalseを返す * 除外フィルターにヒットせず通常フィルターのいずれかにヒットすればtrueを返す * @param device * @param filters Nullable */ public static bool Match(UVCDevice device, UVCFilter[] filters /*Nullable*/) { var result = true; if ((filters != null) && (filters.Length > 0)) { result = false; foreach (var filter in filters) { if (filter != null) { var b = filter.Match(device); if (b && filter.IsExclude) { // 除外フィルターにヒットしたときはその時点でフィルタ処理を終了 result = false; break; } else { // どれか一つにヒットすればいい result |= b; } } else { // 空フィルターはマッチしたことにする result = true; } } } #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}Match({device}):result={result}"); #endif return(result); }
//-------------------------------------------------------------------------------- /** * 指定したUVC識別文字列に対応するCameraInfoを取得する * まだ登録させていなければ新規作成する * @param deviceName UVC機器識別文字列 * @param CameraInfoを返す */ /*NonNull*/ private CameraInfo CreateIfNotExist(UVCDevice device) { if (!cameraInfos.ContainsKey(device.id)) { cameraInfos[device.id] = new CameraInfo(device); } return(cameraInfos[device.id]); }
public static UVCDevice Parse(string deviceName, string jsonString) { AndroidDebug.Logd("Parse", "deviceName:" + jsonString); UVCDevice result; try { //var element = JsonDocument.Parse(jsonString).RootElement; //JsonElement v; //string name; //if (element.TryGetProperty("name", out v)) //{ // name = v.GetString(); //} else //{ // name = null; //} //result = new UVCDevice(deviceName, //element.GetProperty("vid").GetInt32(), //element.GetProperty("pid").GetInt32(), name); JToken element = JObject.Parse(jsonString).Root; string name; Debug.Log("获取根节点:" + element.ToString()); //if(element["name"].HasValues) //{ // name = element["name"].ToString(); // AndroidDebug.Logd("Parse", "deviceName:" + name); //} //else //{ name = null; // AndroidDebug.Logd("Parse", "deviceName:" + name); //} result = new UVCDevice( deviceName, int.Parse(element["vid"].ToString()), int.Parse(element["pid"].ToString()), name); } catch (Exception e) { throw new ArgumentException(e.ToString()); } if (result == null) { throw new ArgumentException($"failed to parse ({jsonString})"); } return(result); }
/** * UVC機器が取り外されたときの処理の実体 * @param info */ private void HandleOnDetachEvent(UVCDevice device /*NonNull*/) { if ((UVCDrawers != null) && (UVCDrawers.Length > 0)) { foreach (var drawer in UVCDrawers) { if (drawer is IUVCDrawer) { (drawer as IUVCDrawer).OnUVCDetachEvent(this, device); } } } }
// // Update is called once per frame // void Update() // { // // } //================================================================================ /** * UVC機器が接続された * IOnUVCAttachHandlerの実装 * @param manager 呼び出し元のUVCManager * @param device 対象となるUVC機器の情報 * @return true: UVC機器を使用する, false: UVC機器を使用しない */ public bool OnUVCAttachEvent(UVCManager manager, UVCDevice device) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnUVCAttachEvent:{device}"); #endif // XXX 今の実装では基本的に全てのUVC機器を受け入れる // ただしTHETA SとTHETA Vは映像を取得できないインターフェースがあるのでオミットする // CanDrawと同様にUVC機器フィルターをインスペクタで設定できるようにする var result = !device.IsRicoh || (device.IsTHETA_S || device.IsTHETA_V); result &= UVCFilter.Match(device, UVCFilters); return result; }
private void StopPreview(UVCDevice device) { var info = Get(device); if ((info != null) && info.IsPreviewing) { mainContext.Post(__ => { HandleOnStopPreviewEvent(info); Stop(device.id); StopCoroutine(info.OnRender()); info.SetSize(0, 0); info.activeId = 0; }, null); } }
//-------------------------------------------------------------------------------- /** * 引数のUVC機器にマッチするかどうかを取得 * @param device */ public bool Match(UVCDevice device) { bool result = device != null; if (result) { result &= ((Vid <= 0) || (Vid == device.vid)) && ((Pid <= 0) || (Pid == device.pid)) && (String.IsNullOrEmpty(DeviceName) || DeviceName.Equals(device.deviceName) || (String.IsNullOrEmpty(device.name) || (String.IsNullOrEmpty(device.deviceName) || device.deviceName.Contains(DeviceName)) || DeviceName.Equals(device.name) || device.name.Contains(DeviceName)) ); } return(result); }
/** * 获取指定的UVC设备的信息(现在是vid和pid)作为UVC设备 * @param deviceName UVC设备识别字符串 */ private UVCDevice GetDevice(string deviceName) { AndroidDebug.Logd(TAG, "获取指定的UVC设备的信息1:" + deviceName); if (!String.IsNullOrEmpty(deviceName)) { using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { AndroidDebug.Logd(TAG, "获取指定的UVC设备的信息2:" + AndroidUtils.GetCurrentActivity()); AndroidDebug.Logd(TAG, "获取指定的UVC设备的信息2:" + clazz.CallStatic <string>("getInfo", AndroidUtils.GetCurrentActivity(), deviceName)); return(UVCDevice.Parse(deviceName, clazz.CallStatic <string>("getInfo", AndroidUtils.GetCurrentActivity(), deviceName))); } } else { throw new ArgumentException("device name is empty/null"); } }
/** * 指定したUVC機器の情報(今はvidとpid)をUVCDeviceとして取得する * @param deviceName UVC機器識別文字列 */ private UVCDevice GetDevice(string deviceName) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}GetDevice:{deviceName}"); #endif if (!String.IsNullOrEmpty(deviceName)) { using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { return(UVCDevice.Parse(deviceName, clazz.CallStatic <string>("getInfo", AndroidUtils.GetCurrentActivity(), deviceName))); } } else { throw new ArgumentException("device name is empty/null"); } }
public static UVCDevice Parse(string deviceName, string jsonString) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"UVCInfo:{jsonString}"); #endif UVCDevice result; try { var element = JsonDocument.Parse(jsonString).RootElement; JsonElement v; string name; if (element.TryGetProperty("name", out v)) { name = v.GetString(); } else { name = null; } result = new UVCDevice( deviceName, element.GetProperty("vid").GetInt32(), element.GetProperty("pid").GetInt32(), name); } catch (JsonException e) { throw new ArgumentException(e.ToString()); } if (result == null) { throw new ArgumentException($"failed to parse ({jsonString})"); } return(result); }
//-------------------------------------------------------------------------------- /** * UVC機器が接続されたときの処理の実体 * @param info * @return true: 接続されたUVC機器を使用する, false: 接続されたUVC機器を使用しない */ private bool HandleOnAttachEvent(UVCDevice device /*NonNull*/) { if ((UVCDrawers == null) || (UVCDrawers.Length == 0)) { // IUVCDrawerが割り当てられていないときはtrue(接続されたUVC機器を使用する)を返す return(true); } else { bool hasDrawer = false; foreach (var drawer in UVCDrawers) { if (drawer is IUVCDrawer) { hasDrawer = true; if ((drawer as IUVCDrawer).OnUVCAttachEvent(this, device)) { // どれか1つのIUVCDrawerがtrueを返せばtrue(接続されたUVC機器を使用する)を返す return(true); } } } // IUVCDrawerが割り当てられていないときはtrue(接続されたUVC機器を使用する)を返す return(!hasDrawer); } }
// /** // * 対応解像度を取得 // * @param camera 対応解像度を取得するUVC機器を指定 // * @return 対応解像度 既にカメラが取り外されている/closeしているのであればnull // */ // public SupportedFormats GetSupportedVideoSize(CameraInfo camera) // { // var info = (camera != null) ? Get(camera.DeviceName) : null; // if ((info != null) && info.IsOpen) // { // return GetSupportedVideoSize(info.DeviceName); // } // else // { // return null; // } // } // /** // * 解像度を変更 // * @param 解像度を変更するUVC機器を指定 // * @param 変更する解像度を指定, nullならデフォルトに戻す // * @param 解像度が変更されたかどうか // */ // public bool SetVideoSize(CameraInfo camera, SupportedFormats.Size size) // { // var info = (camera != null) ? Get(camera.DeviceName) : null; // var width = size != null ? size.Width : DefaultWidth; // var height = size != null ? size.Height : DefaultHeight; // if ((info != null) && info.IsPreviewing) // { // if ((width != info.CurrentWidth) || (height != info.CurrentHeight)) // { // 解像度が変更になるとき // StopPreview(info.DeviceName); // StartPreview(info.DeviceName, width, height); // return true; // } // } // return false; // } private void StartPreview(UVCDevice device) { var info = CreateIfNotExist(device); if ((info != null) && !info.IsPreviewing) { int width = DefaultWidth; int height = DefaultHeight; // var supportedVideoSize = GetSupportedVideoSize(deviceName); // if (supportedVideoSize == null) // { // throw new ArgumentException("fauled to get supported video size"); // } // // 解像度の選択処理 // if ((UVCDrawers != null) && (UVCDrawers.Length > 0)) // { // foreach (var drawer in UVCDrawers) // { // if ((drawer is IUVCDrawer) && ((drawer as IUVCDrawer).CanDraw(this, info.device))) // { // var size = (drawer as IUVCDrawer).OnUVCSelectSize(this, info.device, supportedVideoSize); //#if (!NDEBUG && DEBUG && ENABLE_LOG) // Console.WriteLine($"{TAG}StartPreview:selected={size}"); //#endif // if (size != null) // { // 一番最初に見つかった描画可能なIUVCDrawersがnull以外を返せばそれを使う // width = size.Width; // height = size.Height; // break; // } // } // } // } // FIXME 対応解像度の確認処理 #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}StartPreview:({width}x{height}),id={device.id}"); #endif Resize(device.id, DEFAULT_FRAME_TYPE, width, height); info.SetSize(width, height); info.activeId = device.id; mainContext.Post(__ => { // テクスチャの生成はメインスレッドで行わないといけない #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}映像受け取り用テクスチャ生成:({width}x{height})"); #endif Texture2D tex = new Texture2D( width, height, TextureFormat.ARGB32, false, /* mipmap */ true /* linear */); tex.filterMode = FilterMode.Point; tex.Apply(); info.previewTexture = tex; var nativeTexPtr = info.previewTexture.GetNativeTexturePtr(); Start(device.id, nativeTexPtr.ToInt32()); HandleOnStartPreviewEvent(info); StartCoroutine(info.OnRender()); }, null); } }
//-------------------------------------------------------------------------------- /** * UVC機器のフィルタ処理用 * filtersがnullの場合はマッチしたことにする * 除外フィルターにヒットしたときはその時点で評価を終了しfalseを返す * 除外フィルターにヒットせず通常フィルターのいずれかにヒットすればtrueを返す * @param device * @param filters Nullable */ public static bool Match(UVCDevice device, List <UVCFilter> filters /*Nullable*/) { return(Match(device, filters != null ? filters.ToArray() : (null as UVCFilter[]))); }
/** * UVC機器が取り外された * IOnUVCDetachEventHandlerの実装 * @param manager 呼び出し元のUVCManager * @param device 対象となるUVC機器の情報 */ public void OnUVCDetachEvent(UVCManager manager, UVCDevice device) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}OnUVCDetachEvent:{device}"); #endif }
/** * IUVCDrawerが指定したUVC機器の映像を描画できるかどうかを取得 * IUVCDrawerの実装 * @param manager 呼び出し元のUVCManager * @param device 対象となるUVC機器の情報 */ public bool CanDraw(UVCManager manager, UVCDevice device) { return UVCFilter.Match(device, UVCFilters); }
internal CameraInfo(UVCDevice device) { this.device = device; }
/** * 指定したUVC識別文字列に対応するCameraInfoを取得する * @param deviceName UVC機器識別文字列 * @param 登録してあればCameraInfoを返す、登録されていなければnull */ /*Nullable*/ private CameraInfo Get(UVCDevice device) { return(cameraInfos.ContainsKey(device.id) ? cameraInfos[device.id] : null); }