diff --git a/Examples/OpenSeeWebcamInfo.cs b/Examples/OpenSeeWebcamInfo.cs new file mode 100644 index 0000000..3e849cb --- /dev/null +++ b/Examples/OpenSeeWebcamInfo.cs @@ -0,0 +1,235 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Runtime.InteropServices; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +// To use this, add the following entry to the dependencies in Packages\manifest.json: +// "com.unity.nuget.newtonsoft-json": "2.0.0" +using Newtonsoft.Json; + +namespace OpenSee { + +[Serializable] +public enum OpenSeeWebcamType { Unknown = -1, DirectShow, Blackmagic }; + +[Serializable] +public enum OpenSeeWebcamFormat { Any = 0, Unknown = 1, ARGB = 100, XRGB, I420 = 200, NV12, YV12, Y800, YVYU = 300, YUY2, UYVY, HDYC, MJPEG = 400, H264 }; + +[Serializable] +public struct OpenSeeWebcamCapability { + public int id; + + // DirectShow + public int minCX; + public int minCY; + public int maxCX; + public int maxCY; + public int granularityCX; + public int granularityCY; + public int minInterval; + public int maxInterval; + public int rating; + public OpenSeeWebcamFormat format; + + // Blackmagic + public int bmTimescale; + public int bmFrameduration; + public int bmModecode; +} + +[Serializable] +public class OpenSeeWebcam { + public OpenSeeWebcamType type = OpenSeeWebcamType.Unknown; + public int id; + public string name; + + // DirectShow + public string path; + + // Blackmagic + public long bmId; + public int bmFlags; + + // General + public OpenSeeWebcamCapability[] caps; + + public List prettyCaps = null; + + private List> splitCaps = null; + + private int CompareCaps(OpenSeeWebcamCapability a, OpenSeeWebcamCapability b) { + if (a.rating < b.rating) + return -1; + if (a.rating > b.rating) + return 1; + if (a.minCX * a.minCY > b.minCX * b.minCY) + return -1; + if (a.minCX * a.minCY < b.minCX * b.minCY) + return 1; + if (a.minInterval < b.minInterval) + return -1; + if (a.minInterval > b.minInterval) + return 1; + return 0; + } + + private string GetPrettyCapability(OpenSeeWebcamCapability cap) { + float fps = 10000000f / (float)cap.minInterval; + string prettyCap = cap.minCX + "x" + cap.minCY + ", " + fps.ToString("0.##") + "fps (" + cap.format.ToString() + ")"; + return prettyCap; + } + + public List GetPrettyCapabilities() { + if (splitCaps != null && prettyCaps != null) + return prettyCaps; + + splitCaps = new List>(); + + for (int i = 0; i < caps.Length; i++) { + if (caps[i].minCX == caps[i].maxCX && caps[i].minCY == caps[i].maxCY) + splitCaps.Add(new Tuple(caps[i], i)); + else { + OpenSeeWebcamCapability min = caps[i]; + OpenSeeWebcamCapability max = caps[i]; + min.maxCX = min.minCX; + min.maxCY = min.minCY; + max.minCX = max.maxCX; + max.minCY = max.maxCY; + splitCaps.Add(new Tuple(min, i)); + splitCaps.Add(new Tuple(max, i)); + } + } + + splitCaps.Sort((a, b) => CompareCaps(a.Item1, b.Item1)); + + prettyCaps = new List(); + foreach (var cap in splitCaps) { + prettyCaps.Add(GetPrettyCapability(cap.Item1)); + } + + return prettyCaps; + } + + public OpenSeeWebcamCapability GetCapabilityByPrettyIndex(int index) { + if (splitCaps == null || index >= splitCaps.Count) + throw new InvalidOperationException("Invalid capability index."); + return caps[splitCaps[index].Item2]; + } +} + +[DefaultExecutionOrder(-50)] +public class OpenSeeWebcamInfo : MonoBehaviour { + #region DllImport + [DllImport("dshowcapture_x64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "create_capture")] + private static extern System.IntPtr create_capture_x64(); + + [DllImport("dshowcapture_x64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "get_json_length")] + private static extern int get_json_length_x64(System.IntPtr cap); + + [DllImport("dshowcapture_x64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "get_json")] + private static extern void get_json_x64(System.IntPtr cap, [Out] StringBuilder namebuffer, int bufferlength); + + [DllImport("dshowcapture_x64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "destroy_capture")] + private static extern void destroy_capture_x64(System.IntPtr cap); + + [DllImport("dshowcapture_x86", CallingConvention = CallingConvention.Cdecl, EntryPoint = "create_capture")] + private static extern System.IntPtr create_capture_x86(); + + [DllImport("dshowcapture_x86", CallingConvention = CallingConvention.Cdecl, EntryPoint = "get_json_length")] + private static extern int get_json_length_x86(System.IntPtr cap); + + [DllImport("dshowcapture_x86", CallingConvention = CallingConvention.Cdecl, EntryPoint = "get_json")] + private static extern void get_json_x86(System.IntPtr cap, [Out] StringBuilder namebuffer, int bufferlength); + + [DllImport("dshowcapture_x86", CallingConvention = CallingConvention.Cdecl, EntryPoint = "destroy_capture")] + private static extern void destroy_capture_x86(System.IntPtr cap); + + /* Blackmagic */ + [DllImport("libminibmcapture64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "get_json_length")] + private static extern int bm_get_json_length_x64(); + + [DllImport("libminibmcapture64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "get_json")] + private static extern void bm_get_json_x64([Out] StringBuilder namebuffer, int bufferlength); + + [DllImport("libminibmcapture32", CallingConvention = CallingConvention.Cdecl, EntryPoint = "get_json_length")] + private static extern int bm_get_json_length_x86(); + + [DllImport("libminibmcapture32", CallingConvention = CallingConvention.Cdecl, EntryPoint = "get_json")] + private static extern void bm_get_json_x86([Out] StringBuilder namebuffer, int bufferlength); + #endregion + + public List cameras; + + private bool initialized = false; + + static private string ListCameraDetails_x64() { + System.IntPtr cap = create_capture_x64(); + int length = get_json_length_x64(cap); + StringBuilder buffer = new StringBuilder(length); + get_json_x64(cap, buffer, length); + destroy_capture_x64(cap); + return buffer.ToString(); + } + + static private string ListCameraDetails_x86() { + System.IntPtr cap = create_capture_x86(); + int length = get_json_length_x86(cap); + StringBuilder buffer = new StringBuilder(length); + get_json_x86(cap, buffer, length); + destroy_capture_x86(cap); + return buffer.ToString(); + } + + static private string ListBlackMagicDetails_x64() { + int length = bm_get_json_length_x64(); + StringBuilder buffer = new StringBuilder(length); + bm_get_json_x64(buffer, length); + return buffer.ToString(); + } + + static private string ListBlackMagicDetails_x86() { + int length = bm_get_json_length_x86(); + StringBuilder buffer = new StringBuilder(length); + bm_get_json_x86(buffer, length); + return buffer.ToString(); + } + + static public List ListCameraDetails() { + string jsonData; + string bmJsonData; + if (Environment.Is64BitProcess) { + jsonData = ListCameraDetails_x64(); + bmJsonData = ListBlackMagicDetails_x64(); + } else { + jsonData = ListCameraDetails_x86(); + bmJsonData = ListBlackMagicDetails_x86(); + } + List details = JsonConvert.DeserializeObject>(jsonData); + foreach (var cam in details) + cam.type = OpenSeeWebcamType.DirectShow; + List bmDetails = JsonConvert.DeserializeObject>(bmJsonData); + foreach (var cam in bmDetails) + cam.type = OpenSeeWebcamType.Blackmagic; + details.AddRange(bmDetails); + return details; + } + + void Start() { + Initialize(); + } + + public void Initialize() { + if (initialized) + return; + initialized = true; + cameras = ListCameraDetails(); + foreach (var camera in cameras) + camera.GetPrettyCapabilities(); + } +} +} \ No newline at end of file diff --git a/Examples/OpenSeeWebcamInfo.cs.meta b/Examples/OpenSeeWebcamInfo.cs.meta new file mode 100644 index 0000000..8fef5a0 --- /dev/null +++ b/Examples/OpenSeeWebcamInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e9598f1218283b418c7e72604be0335 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: -50 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Licenses/libminibmcapture.txt b/Licenses/libminibmcapture.txt new file mode 100644 index 0000000..05aa705 --- /dev/null +++ b/Licenses/libminibmcapture.txt @@ -0,0 +1,19 @@ +zlib License + +libminibmcapture (C) 2020 noorus + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/Unity/OpenSeeIKTarget.cs b/Unity/OpenSeeIKTarget.cs index 12d91d1..dafc7c2 100644 --- a/Unity/OpenSeeIKTarget.cs +++ b/Unity/OpenSeeIKTarget.cs @@ -2,6 +2,7 @@ namespace OpenSee { +[DefaultExecutionOrder(-1)] public class OpenSeeIKTarget : MonoBehaviour { [Header("Settings")] diff --git a/Unity/Plugins/libminibmcapture32.dll b/Unity/Plugins/libminibmcapture32.dll new file mode 100644 index 0000000..34d9c93 Binary files /dev/null and b/Unity/Plugins/libminibmcapture32.dll differ diff --git a/Unity/Plugins/libminibmcapture32.dll.meta b/Unity/Plugins/libminibmcapture32.dll.meta new file mode 100644 index 0000000..fcc39c3 --- /dev/null +++ b/Unity/Plugins/libminibmcapture32.dll.meta @@ -0,0 +1,27 @@ +fileFormatVersion: 2 +guid: 51dc8f0c65df30d4daa188cdfd1dd220 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Plugins/libminibmcapture64.dll b/Unity/Plugins/libminibmcapture64.dll new file mode 100644 index 0000000..9b7d1de Binary files /dev/null and b/Unity/Plugins/libminibmcapture64.dll differ diff --git a/Unity/Plugins/libminibmcapture64.dll.meta b/Unity/Plugins/libminibmcapture64.dll.meta new file mode 100644 index 0000000..2be2e1b --- /dev/null +++ b/Unity/Plugins/libminibmcapture64.dll.meta @@ -0,0 +1,27 @@ +fileFormatVersion: 2 +guid: fcfc753ca92169e48aa69c1ecc1b0d64 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/dshowcapture/libminibmcapture32.dll b/dshowcapture/libminibmcapture32.dll new file mode 100644 index 0000000..34d9c93 Binary files /dev/null and b/dshowcapture/libminibmcapture32.dll differ diff --git a/dshowcapture/libminibmcapture64.dll b/dshowcapture/libminibmcapture64.dll new file mode 100644 index 0000000..9b7d1de Binary files /dev/null and b/dshowcapture/libminibmcapture64.dll differ