未验证 提交 450ce380 编写于 作者: O Omar Raad 提交者: GitHub

Fix video capture for 32/64 arch (#1474)

* Update structs to support both 32/64 systems

* Remove TODOs

* Simplify Resolution

* Split classes into files
上级 5ce2bb28
...@@ -5,31 +5,10 @@ ...@@ -5,31 +5,10 @@
#pragma warning disable SA1300 // Element should begin with upper-case letter #pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1307 // Field should begin with upper-case letter #pragma warning disable SA1307 // Field should begin with upper-case letter
internal enum VideoSettings : int
{
VIDIOC_QUERYCAP = -2140645888,
VIDIOC_ENUM_FMT = -1069525502,
VIDIOC_CROPCAP = -1070836166,
VIDIOC_G_CROP = -1072409029,
VIDIOC_S_CROP = 1075074620,
VIDIOC_G_FMT = -1060350460,
VIDIOC_S_FMT = -1060350459,
VIDIOC_REQBUFS = -1072409080,
VIDIOC_QUERYBUF = -1069263351,
VIDIOC_STREAMON = 1074026002,
VIDIOC_STREAMOFF = 1074026003,
VIDIOC_QBUF = -1069263345,
VIDIOC_DQBUF = -1069263343,
VIDIOC_ENUM_FRAMESIZES = -1070836150,
VIDIOC_G_CTRL = -1073195493,
VIDIOC_S_CTRL = -1073195492,
VIDIOC_QUERYCTRL = -1069263324,
}
/// <summary> /// <summary>
/// videodev2.h Request Definition /// videodev2.h Request Definition
/// </summary> /// </summary>
internal class RawVideoSettings internal class V4l2Request
{ {
public static int VIDIOC_QUERYCAP = Interop._IOR('V', 0, typeof(v4l2_capability)); public static int VIDIOC_QUERYCAP = Interop._IOR('V', 0, typeof(v4l2_capability));
public static int VIDIOC_ENUM_FMT = Interop._IOWR('V', 2, typeof(v4l2_fmtdesc)); public static int VIDIOC_ENUM_FMT = Interop._IOWR('V', 2, typeof(v4l2_fmtdesc));
...@@ -57,4 +36,4 @@ internal class RawVideoSettings ...@@ -57,4 +36,4 @@ internal class RawVideoSettings
public static int VIDIOC_S_PRIORITY = Interop._IOW('V', 68, typeof(uint)); public static int VIDIOC_S_PRIORITY = Interop._IOW('V', 68, typeof(uint));
public static int VIDIOC_ENUM_FRAMESIZES = Interop._IOWR('V', 74, typeof(v4l2_frmsizeenum)); public static int VIDIOC_ENUM_FRAMESIZES = Interop._IOWR('V', 74, typeof(v4l2_frmsizeenum));
public static int VIDIOC_PREPARE_BUF = Interop._IOWR('V', 93, typeof(v4l2_buffer)); public static int VIDIOC_PREPARE_BUF = Interop._IOWR('V', 93, typeof(v4l2_buffer));
} }
\ No newline at end of file
...@@ -132,17 +132,35 @@ internal enum v4l2_colorspace : uint ...@@ -132,17 +132,35 @@ internal enum v4l2_colorspace : uint
V4L2_COLORSPACE_RAW = 11, V4L2_COLORSPACE_RAW = 11,
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Explicit)]
internal struct v4l2_pix_format internal struct v4l2_pix_format
{ {
[FieldOffset(0)]
public uint width; public uint width;
[FieldOffset(4)]
public uint height; public uint height;
[FieldOffset(8)]
public PixelFormat pixelformat; public PixelFormat pixelformat;
[FieldOffset(12)]
public v4l2_field field; public v4l2_field field;
[FieldOffset(16)]
public uint bytesperline; public uint bytesperline;
[FieldOffset(20)]
public uint sizeimage; public uint sizeimage;
[FieldOffset(24)]
public v4l2_colorspace colorspace; public v4l2_colorspace colorspace;
[FieldOffset(28)]
public uint priv; public uint priv;
[FieldOffset(32)]
public uint flags;
[FieldOffset(36)]
public uint ycbcr_enc;
[FieldOffset(36)]
public uint hsv_enc;
[FieldOffset(40)]
public uint quantization;
[FieldOffset(44)]
public uint xfer_func;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
...@@ -174,39 +192,33 @@ internal unsafe struct v4l2_window ...@@ -174,39 +192,33 @@ internal unsafe struct v4l2_window
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct v4l2_vbi_format internal unsafe struct v4l2_vbi_format
{ {
public uint sampling_rate; public uint sampling_rate;
public uint offset; public uint offset;
public uint samples_per_line; public uint samples_per_line;
public uint sample_format; public uint sample_format;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public fixed int start[2];
public uint[] start; public fixed uint count[2];
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] count;
public uint flags; public uint flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public fixed uint reserved[2];
public uint[] reserved;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct v4l2_sliced_vbi_format internal unsafe struct v4l2_sliced_vbi_format
{ {
public uint service_set; public ushort service_set;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] public fixed ushort service_lines[48];
public ushort[] service_lines;
public uint io_size; public uint io_size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public fixed uint reserved[2];
public uint[] reserved;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct v4l2_sdr_format internal unsafe struct v4l2_sdr_format
{ {
public PixelFormat pixelformat; public PixelFormat pixelformat;
public uint buffersize; public uint buffersize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] public fixed byte reserved[24];
public byte[] reserved;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
...@@ -216,20 +228,26 @@ internal struct v4l2_meta_format ...@@ -216,20 +228,26 @@ internal struct v4l2_meta_format
public uint buffersize; public uint buffersize;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Explicit)]
internal struct fmt internal unsafe struct fmt
{ {
[FieldOffset(0)]
public v4l2_pix_format pix; public v4l2_pix_format pix;
[FieldOffset(0)]
public v4l2_window win; public v4l2_window win;
[FieldOffset(0)]
public v4l2_vbi_format vbi; public v4l2_vbi_format vbi;
[FieldOffset(0)]
public v4l2_sliced_vbi_format sliced; public v4l2_sliced_vbi_format sliced;
[FieldOffset(0)]
public v4l2_sdr_format sdr; public v4l2_sdr_format sdr;
[FieldOffset(0)]
public v4l2_meta_format meta; public v4l2_meta_format meta;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 200)] [FieldOffset(0)]
public byte[] raw; public fixed byte raw[200];
} }
[StructLayout(LayoutKind.Sequential, Size = 204)] [StructLayout(LayoutKind.Sequential)]
internal struct v4l2_format internal struct v4l2_format
{ {
public v4l2_buf_type type; public v4l2_buf_type type;
...@@ -309,8 +327,8 @@ internal struct v4l2_buffer ...@@ -309,8 +327,8 @@ internal struct v4l2_buffer
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct timeval public struct timeval
{ {
public uint tv_sec; public nint tv_sec;
public uint tv_usec; public nint tv_usec;
} }
public timeval timestamp; public timeval timestamp;
...@@ -325,7 +343,7 @@ internal struct v4l2_buffer ...@@ -325,7 +343,7 @@ internal struct v4l2_buffer
[FieldOffset(0)] [FieldOffset(0)]
public uint offset; public uint offset;
[FieldOffset(0)] [FieldOffset(0)]
public uint userptr; public nuint userptr;
} }
public m_union m; public m_union m;
...@@ -335,16 +353,21 @@ internal struct v4l2_buffer ...@@ -335,16 +353,21 @@ internal struct v4l2_buffer
public uint reserved; public uint reserved;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Explicit)]
internal struct v4l2_frmsizeenum internal unsafe struct v4l2_frmsizeenum
{ {
[FieldOffset(0)]
public uint index; public uint index;
[FieldOffset(4)]
public PixelFormat pixel_format; public PixelFormat pixel_format;
[FieldOffset(8)]
public v4l2_frmsizetypes type; public v4l2_frmsizetypes type;
[FieldOffset(12)]
public v4l2_frmsize_discrete discrete; public v4l2_frmsize_discrete discrete;
[FieldOffset(12)]
public v4l2_frmsize_stepwise stepwise; public v4l2_frmsize_stepwise stepwise;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] [FieldOffset(36)]
public uint[] reserved; public fixed uint reserved[2];
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
......
...@@ -111,14 +111,14 @@ namespace Iot.Device.Media ...@@ -111,14 +111,14 @@ namespace Iot.Device.Media
{ {
id = type id = type
}; };
V4l2Struct(VideoSettings.VIDIOC_QUERYCTRL, ref query); V4l2Struct(V4l2Request.VIDIOC_QUERYCTRL, ref query);
// Get current value // Get current value
v4l2_control ctrl = new v4l2_control v4l2_control ctrl = new v4l2_control
{ {
id = type, id = type,
}; };
V4l2Struct(VideoSettings.VIDIOC_G_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_G_CTRL, ref ctrl);
return new VideoDeviceValue( return new VideoDeviceValue(
type.ToString(), type.ToString(),
...@@ -144,7 +144,7 @@ namespace Iot.Device.Media ...@@ -144,7 +144,7 @@ namespace Iot.Device.Media
}; };
List<PixelFormat> result = new List<PixelFormat>(); List<PixelFormat> result = new List<PixelFormat>();
while (V4l2Struct(VideoSettings.VIDIOC_ENUM_FMT, ref fmtdesc) != -1) while (V4l2Struct(V4l2Request.VIDIOC_ENUM_FMT, ref fmtdesc) != -1)
{ {
result.Add(fmtdesc.pixelformat); result.Add(fmtdesc.pixelformat);
fmtdesc.index++; fmtdesc.index++;
...@@ -158,7 +158,7 @@ namespace Iot.Device.Media ...@@ -158,7 +158,7 @@ namespace Iot.Device.Media
/// </summary> /// </summary>
/// <param name="format">Pixel format.</param> /// <param name="format">Pixel format.</param>
/// <returns>Supported resolution.</returns> /// <returns>Supported resolution.</returns>
public override IEnumerable<(uint Width, uint Height)> GetPixelFormatResolutions(PixelFormat format) public override IEnumerable<Resolution> GetPixelFormatResolutions(PixelFormat format)
{ {
Initialize(); Initialize();
...@@ -168,10 +168,66 @@ namespace Iot.Device.Media ...@@ -168,10 +168,66 @@ namespace Iot.Device.Media
pixel_format = format pixel_format = format
}; };
List<(uint Width, uint Height)> result = new List<(uint Width, uint Height)>(); List<Resolution> result = new List<Resolution>();
while (V4l2Struct(VideoSettings.VIDIOC_ENUM_FRAMESIZES, ref size) != -1) while (V4l2Struct(V4l2Request.VIDIOC_ENUM_FRAMESIZES, ref size) != -1)
{ {
result.Add((size.discrete.width, size.discrete.height)); Resolution resolution;
switch (size.type)
{
case v4l2_frmsizetypes.V4L2_FRMSIZE_TYPE_DISCRETE:
resolution = new Resolution
{
Type = ResolutionType.Discrete,
MinHeight = size.discrete.height,
MaxHeight = size.discrete.height,
StepHeight = 0,
MinWidth = size.discrete.width,
MaxWidth = size.discrete.width,
StepWidth = 0,
};
break;
case v4l2_frmsizetypes.V4L2_FRMSIZE_TYPE_CONTINUOUS:
resolution = new Resolution
{
Type = ResolutionType.Continuous,
MinHeight = size.stepwise.min_height,
MaxHeight = size.stepwise.max_height,
StepHeight = 1,
MinWidth = size.stepwise.min_width,
MaxWidth = size.stepwise.max_width,
StepWidth = 1,
};
break;
case v4l2_frmsizetypes.V4L2_FRMSIZE_TYPE_STEPWISE:
resolution = new Resolution
{
Type = ResolutionType.Stepwise,
MinHeight = size.stepwise.min_height,
MaxHeight = size.stepwise.max_height,
StepHeight = size.stepwise.step_height,
MinWidth = size.stepwise.min_width,
MaxWidth = size.stepwise.max_width,
StepWidth = size.stepwise.step_width,
};
break;
default:
resolution = new Resolution
{
Type = ResolutionType.Discrete,
MinHeight = 0,
MaxHeight = 0,
StepHeight = 0,
MinWidth = 0,
MaxWidth = 0,
StepWidth = 0,
};
break;
}
result.Add(resolution);
size.index++; size.index++;
} }
...@@ -184,12 +240,12 @@ namespace Iot.Device.Media ...@@ -184,12 +240,12 @@ namespace Iot.Device.Media
{ {
// Start data stream // Start data stream
v4l2_buf_type type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buf_type type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE;
Interop.ioctl(_deviceFileDescriptor, (int)VideoSettings.VIDIOC_STREAMON, new IntPtr(&type)); Interop.ioctl(_deviceFileDescriptor, V4l2Request.VIDIOC_STREAMON, new IntPtr(&type));
byte[] dataBuffer = GetFrameData(buffers); byte[] dataBuffer = GetFrameData(buffers);
// Close data stream // Close data stream
Interop.ioctl(_deviceFileDescriptor, (int)VideoSettings.VIDIOC_STREAMOFF, new IntPtr(&type)); Interop.ioctl(_deviceFileDescriptor, V4l2Request.VIDIOC_STREAMOFF, new IntPtr(&type));
UnmappingFrameBuffers(buffers); UnmappingFrameBuffers(buffers);
...@@ -205,7 +261,7 @@ namespace Iot.Device.Media ...@@ -205,7 +261,7 @@ namespace Iot.Device.Media
type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE,
memory = v4l2_memory.V4L2_MEMORY_MMAP, memory = v4l2_memory.V4L2_MEMORY_MMAP,
}; };
V4l2Struct(VideoSettings.VIDIOC_DQBUF, ref frame); V4l2Struct(V4l2Request.VIDIOC_DQBUF, ref frame);
// Get data from pointer // Get data from pointer
IntPtr intptr = buffers[frame.index].Start; IntPtr intptr = buffers[frame.index].Start;
...@@ -213,7 +269,7 @@ namespace Iot.Device.Media ...@@ -213,7 +269,7 @@ namespace Iot.Device.Media
Marshal.Copy(source: intptr, destination: dataBuffer, startIndex: 0, length: (int)buffers[frame.index].Length); Marshal.Copy(source: intptr, destination: dataBuffer, startIndex: 0, length: (int)buffers[frame.index].Length);
// Requeue the buffer // Requeue the buffer
V4l2Struct(VideoSettings.VIDIOC_QBUF, ref frame); V4l2Struct(V4l2Request.VIDIOC_QBUF, ref frame);
return dataBuffer; return dataBuffer;
} }
...@@ -227,7 +283,7 @@ namespace Iot.Device.Media ...@@ -227,7 +283,7 @@ namespace Iot.Device.Media
type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE,
memory = v4l2_memory.V4L2_MEMORY_MMAP memory = v4l2_memory.V4L2_MEMORY_MMAP
}; };
V4l2Struct(VideoSettings.VIDIOC_REQBUFS, ref req); V4l2Struct(V4l2Request.VIDIOC_REQBUFS, ref req);
// Mapping the applied buffer to user space // Mapping the applied buffer to user space
V4l2FrameBuffer[] buffers = new V4l2FrameBuffer[BufferCount]; V4l2FrameBuffer[] buffers = new V4l2FrameBuffer[BufferCount];
...@@ -239,7 +295,7 @@ namespace Iot.Device.Media ...@@ -239,7 +295,7 @@ namespace Iot.Device.Media
type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE,
memory = v4l2_memory.V4L2_MEMORY_MMAP memory = v4l2_memory.V4L2_MEMORY_MMAP
}; };
V4l2Struct(VideoSettings.VIDIOC_QUERYBUF, ref buffer); V4l2Struct(V4l2Request.VIDIOC_QUERYBUF, ref buffer);
buffers[i].Length = buffer.length; buffers[i].Length = buffer.length;
buffers[i].Start = Interop.mmap(IntPtr.Zero, (int)buffer.length, MemoryMappedProtections.PROT_READ | MemoryMappedProtections.PROT_WRITE, MemoryMappedFlags.MAP_SHARED, _deviceFileDescriptor, (int)buffer.m.offset); buffers[i].Start = Interop.mmap(IntPtr.Zero, (int)buffer.length, MemoryMappedProtections.PROT_READ | MemoryMappedProtections.PROT_WRITE, MemoryMappedFlags.MAP_SHARED, _deviceFileDescriptor, (int)buffer.m.offset);
...@@ -254,7 +310,7 @@ namespace Iot.Device.Media ...@@ -254,7 +310,7 @@ namespace Iot.Device.Media
type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, type = v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE,
memory = v4l2_memory.V4L2_MEMORY_MMAP memory = v4l2_memory.V4L2_MEMORY_MMAP
}; };
V4l2Struct(VideoSettings.VIDIOC_QBUF, ref buffer); V4l2Struct(V4l2Request.VIDIOC_QBUF, ref buffer);
} }
return buffers; return buffers;
...@@ -278,7 +334,7 @@ namespace Iot.Device.Media ...@@ -278,7 +334,7 @@ namespace Iot.Device.Media
} }
} }
}; };
V4l2Struct(VideoSettings.VIDIOC_S_FMT, ref format); V4l2Struct(V4l2Request.VIDIOC_S_FMT, ref format);
// Set exposure type // Set exposure type
v4l2_control ctrl = new v4l2_control v4l2_control ctrl = new v4l2_control
...@@ -286,83 +342,83 @@ namespace Iot.Device.Media ...@@ -286,83 +342,83 @@ namespace Iot.Device.Media
id = VideoDeviceValueType.ExposureType, id = VideoDeviceValueType.ExposureType,
value = (int)Settings.ExposureType value = (int)Settings.ExposureType
}; };
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set exposure time // Set exposure time
// If exposure type is auto, this field is invalid // If exposure type is auto, this field is invalid
ctrl.id = VideoDeviceValueType.ExposureTime; ctrl.id = VideoDeviceValueType.ExposureTime;
ctrl.value = Settings.ExposureTime; ctrl.value = Settings.ExposureTime;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set brightness // Set brightness
ctrl.id = VideoDeviceValueType.Brightness; ctrl.id = VideoDeviceValueType.Brightness;
ctrl.value = Settings.Brightness; ctrl.value = Settings.Brightness;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set contrast // Set contrast
ctrl.id = VideoDeviceValueType.Contrast; ctrl.id = VideoDeviceValueType.Contrast;
ctrl.value = Settings.Contrast; ctrl.value = Settings.Contrast;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set saturation // Set saturation
ctrl.id = VideoDeviceValueType.Saturation; ctrl.id = VideoDeviceValueType.Saturation;
ctrl.value = Settings.Saturation; ctrl.value = Settings.Saturation;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set sharpness // Set sharpness
ctrl.id = VideoDeviceValueType.Sharpness; ctrl.id = VideoDeviceValueType.Sharpness;
ctrl.value = Settings.Sharpness; ctrl.value = Settings.Sharpness;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set gain // Set gain
ctrl.id = VideoDeviceValueType.Gain; ctrl.id = VideoDeviceValueType.Gain;
ctrl.value = Settings.Gain; ctrl.value = Settings.Gain;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set gamma // Set gamma
ctrl.id = VideoDeviceValueType.Gamma; ctrl.id = VideoDeviceValueType.Gamma;
ctrl.value = Settings.Gamma; ctrl.value = Settings.Gamma;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set power line frequency // Set power line frequency
ctrl.id = VideoDeviceValueType.PowerLineFrequency; ctrl.id = VideoDeviceValueType.PowerLineFrequency;
ctrl.value = (int)Settings.PowerLineFrequency; ctrl.value = (int)Settings.PowerLineFrequency;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set white balance effect // Set white balance effect
ctrl.id = VideoDeviceValueType.WhiteBalanceEffect; ctrl.id = VideoDeviceValueType.WhiteBalanceEffect;
ctrl.value = (int)Settings.WhiteBalanceEffect; ctrl.value = (int)Settings.WhiteBalanceEffect;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set white balance temperature // Set white balance temperature
ctrl.id = VideoDeviceValueType.WhiteBalanceTemperature; ctrl.id = VideoDeviceValueType.WhiteBalanceTemperature;
ctrl.value = Settings.WhiteBalanceTemperature; ctrl.value = Settings.WhiteBalanceTemperature;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set color effect // Set color effect
ctrl.id = VideoDeviceValueType.ColorEffect; ctrl.id = VideoDeviceValueType.ColorEffect;
ctrl.value = (int)Settings.ColorEffect; ctrl.value = (int)Settings.ColorEffect;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set scene mode // Set scene mode
ctrl.id = VideoDeviceValueType.SceneMode; ctrl.id = VideoDeviceValueType.SceneMode;
ctrl.value = (int)Settings.SceneMode; ctrl.value = (int)Settings.SceneMode;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set rotate // Set rotate
ctrl.id = VideoDeviceValueType.Rotate; ctrl.id = VideoDeviceValueType.Rotate;
ctrl.value = Settings.Rotate; ctrl.value = Settings.Rotate;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set horizontal flip // Set horizontal flip
ctrl.id = VideoDeviceValueType.HorizontalFlip; ctrl.id = VideoDeviceValueType.HorizontalFlip;
ctrl.value = Settings.HorizontalFlip ? 1 : 0; ctrl.value = Settings.HorizontalFlip ? 1 : 0;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
// Set vertical flip // Set vertical flip
ctrl.id = VideoDeviceValueType.VerticalFlip; ctrl.id = VideoDeviceValueType.VerticalFlip;
ctrl.value = Settings.VerticalFlip ? 1 : 0; ctrl.value = Settings.VerticalFlip ? 1 : 0;
V4l2Struct(VideoSettings.VIDIOC_S_CTRL, ref ctrl); V4l2Struct(V4l2Request.VIDIOC_S_CTRL, ref ctrl);
} }
private void FillVideoConnectionSettings() private void FillVideoConnectionSettings()
...@@ -488,7 +544,7 @@ namespace Iot.Device.Media ...@@ -488,7 +544,7 @@ namespace Iot.Device.Media
/// <param name="request">V4L2 request value</param> /// <param name="request">V4L2 request value</param>
/// <param name="struct">The struct need to be read or set</param> /// <param name="struct">The struct need to be read or set</param>
/// <returns>The ioctl result</returns> /// <returns>The ioctl result</returns>
private int V4l2Struct<T>(VideoSettings request, ref T @struct) private int V4l2Struct<T>(int request, ref T @struct)
where T : struct where T : struct
{ {
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(@struct)); IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(@struct));
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Iot.Device.Media
{
/// <summary>
/// The resolution of a video device.
/// </summary>
public class Resolution
{
/// <summary>
/// Resolution's type
/// </summary>
public ResolutionType Type { get; set; }
/// <summary>
/// Resolution's minimum height
/// </summary>
public uint MinHeight { get; set; }
/// <summary>
/// Resolution's maximum height
/// </summary>
public uint MaxHeight { get; set; }
/// <summary>
/// Resolution's step for height
/// </summary>
public uint StepHeight { get; set; }
/// <summary>
/// Resolution's minimum width
/// </summary>
public uint MinWidth { get; set; }
/// <summary>
/// Resolution's maximum width
/// </summary>
public uint MaxWidth { get; set; }
/// <summary>
/// Resolution's step for width
/// </summary>
public uint StepWidth { get; set; }
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Iot.Device.Media
{
/// <summary>
/// The resolution type of a video device.
/// </summary>
public enum ResolutionType : uint
{
/// <summary>
/// Discrete
/// </summary>
Discrete = v4l2_frmsizetypes.V4L2_FRMSIZE_TYPE_DISCRETE,
/// <summary>
/// Continuous
/// </summary>
Continuous = v4l2_frmsizetypes.V4L2_FRMSIZE_TYPE_CONTINUOUS,
/// <summary>
/// Stepwise
/// </summary>
Stepwise = v4l2_frmsizetypes.V4L2_FRMSIZE_TYPE_STEPWISE
}
}
...@@ -75,7 +75,7 @@ namespace Iot.Device.Media ...@@ -75,7 +75,7 @@ namespace Iot.Device.Media
/// </summary> /// </summary>
/// <param name="format">Pixel format.</param> /// <param name="format">Pixel format.</param>
/// <returns>Supported resolution.</returns> /// <returns>Supported resolution.</returns>
public abstract IEnumerable<(uint Width, uint Height)> GetPixelFormatResolutions(PixelFormat format); public abstract IEnumerable<Resolution> GetPixelFormatResolutions(PixelFormat format);
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
......
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>net5.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
......
...@@ -20,7 +20,7 @@ Console.WriteLine(); ...@@ -20,7 +20,7 @@ Console.WriteLine();
// Get the resolutions of the format // Get the resolutions of the format
foreach (var resolution in device.GetPixelFormatResolutions(PixelFormat.YUYV)) foreach (var resolution in device.GetPixelFormatResolutions(PixelFormat.YUYV))
{ {
Console.Write($"{resolution.Width}x{resolution.Height} "); Console.Write($"[{resolution.MinWidth}x{resolution.MinHeight}]->[{resolution.MaxWidth}x{resolution.MaxHeight}], Step [{resolution.StepWidth},{resolution.StepHeight}] ");
} }
Console.WriteLine(); Console.WriteLine();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册