Added new OpenSeeWebcamInfo component and started adding support for black magic devices.

This commit is contained in:
Emiliana 2020-09-29 17:01:18 +02:00
parent ab4d8af2ad
commit 8ea4fa4070
10 changed files with 320 additions and 0 deletions

View file

@ -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<string> prettyCaps = null;
private List<Tuple<OpenSeeWebcamCapability, int>> 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<string> GetPrettyCapabilities() {
if (splitCaps != null && prettyCaps != null)
return prettyCaps;
splitCaps = new List<Tuple<OpenSeeWebcamCapability, int>>();
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<OpenSeeWebcamCapability, int>(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<OpenSeeWebcamCapability, int>(min, i));
splitCaps.Add(new Tuple<OpenSeeWebcamCapability, int>(max, i));
}
}
splitCaps.Sort((a, b) => CompareCaps(a.Item1, b.Item1));
prettyCaps = new List<string>();
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<OpenSeeWebcam> 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<OpenSeeWebcam> ListCameraDetails() {
string jsonData;
string bmJsonData;
if (Environment.Is64BitProcess) {
jsonData = ListCameraDetails_x64();
bmJsonData = ListBlackMagicDetails_x64();
} else {
jsonData = ListCameraDetails_x86();
bmJsonData = ListBlackMagicDetails_x86();
}
List<OpenSeeWebcam> details = JsonConvert.DeserializeObject<List<OpenSeeWebcam>>(jsonData);
foreach (var cam in details)
cam.type = OpenSeeWebcamType.DirectShow;
List<OpenSeeWebcam> bmDetails = JsonConvert.DeserializeObject<List<OpenSeeWebcam>>(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();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2e9598f1218283b418c7e72604be0335
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: -50
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -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.

View file

@ -2,6 +2,7 @@
namespace OpenSee {
[DefaultExecutionOrder(-1)]
public class OpenSeeIKTarget : MonoBehaviour
{
[Header("Settings")]

Binary file not shown.

View file

@ -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:

Binary file not shown.

View file

@ -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:

Binary file not shown.

Binary file not shown.