Commit 8a094dd9 by liulongfei

1. 添加NDI流添加空流选项

2. 裁切录制
parent 5067ead6
......@@ -191,7 +191,10 @@ namespace VIZ.H2V.Module
return;
List<NDIStreamInfoModel> list = new List<NDIStreamInfoModel>();
NDIStreamInfoModel selected = null;
NDIStreamInfoModel none = new NDIStreamInfoModel();
list.Add(none);
NDIStreamInfoModel selected = none;
foreach (NDIStreamInfo info in ndiStream.StreamInfos)
{
......@@ -313,6 +316,10 @@ namespace VIZ.H2V.Module
INDIViewService service = ApplicationDomainEx.ServiceManager.GetService<INDIViewService>(this.ViewKey);
service.DisplayName = this.ViewConfig.DisplayName;
if (string.IsNullOrWhiteSpace(this.ViewConfig.StreamName))
{
service.ClearVideoControl(new ClearVideoControlContext(true, true));
}
return true;
}
......
......@@ -123,7 +123,7 @@ namespace VIZ.H2V.Module
return;
// 清理视频控件
ClearVideoControlContext clear_context = new ClearVideoControlContext(true);
ClearVideoControlContext clear_context = new ClearVideoControlContext(false, true);
this.Support.ClearVideoControl(clear_context);
AlgorithmSender.NoMode(manager, this.Support.ID, this.Support.ViewConfig.IsSendToCrop);
......
......@@ -62,7 +62,7 @@ namespace VIZ.H2V.Module
this.Detect();
// 清理视图控件
ClearVideoControlContext clear_context = new ClearVideoControlContext(true);
ClearVideoControlContext clear_context = new ClearVideoControlContext(false, true);
this.Support.ClearVideoControl(clear_context);
}
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Common;
namespace VIZ.H2V.Module
{
/// <summary>
/// 录制控制器
/// </summary>
public interface IRecordingController
{
/// <summary>
/// 添加数据
/// </summary>
/// <param name="frame">帧</param>
/// <param name="data">数据</param>
void Append(IVideoFrame frame, ClipBoxInfo data);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VIZ.H2V.Module
{
/// <summary>
/// 录制支持
/// </summary>
public interface IRecordingSupport
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
using VIZ.Framework.Common;
using OpenCvSharp;
using System.Windows.Controls;
namespace VIZ.H2V.Module
{
/// <summary>
/// NDI视图录制
/// </summary>
public class NDIViewRecording : VideoControlRecording
{
public NDIViewRecording()
{
this.defaultBoxInfo = new ClipBoxInfo();
this.defaultBoxInfo.SrcRect = new SharpDX.Mathematics.Interop.RawRectangleF(555, 0, 555 + 810, 1080);
}
/// <summary>
/// 之前的裁切信息
/// </summary>
private ClipBoxInfo beforeBoxInfo;
/// <summary>
/// 默认的裁切信息
/// </summary>
private ClipBoxInfo defaultBoxInfo;
/// <summary>
/// 包装
/// </summary>
/// <param name="recordingFrame">录制帧</param>
public override Mat Packaging(VideoControlRecordingFrame recordingFrame)
{
ClipBoxInfo boxInfo = recordingFrame.DataFrame as ClipBoxInfo;
boxInfo = boxInfo ?? this.beforeBoxInfo ?? this.defaultBoxInfo;
Mat mat = new Mat(recordingFrame.VideoFrame.Height, recordingFrame.VideoFrame.Width, MatType.CV_8UC4, recordingFrame.VideoFrame.DataStream.DataPointer);
int x = (int)boxInfo.SrcRect.Left;
int y = (int)boxInfo.SrcRect.Top;
int w = (int)(boxInfo.SrcRect.Right - boxInfo.SrcRect.Left);
int h = (int)(boxInfo.SrcRect.Bottom - boxInfo.SrcRect.Top);
Mat cut = mat[new Rect(x, y, w, h)];
Mat dst = new Mat();
Cv2.CvtColor(cut, dst, ColorConversionCodes.BGRA2BGR);
recordingFrame.VideoFrame.DataStream.Dispose();
mat.Dispose();
cut.Dispose();
this.beforeBoxInfo = boxInfo;
return dst;
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Common;
namespace VIZ.H2V.Module
{
/// <summary>
/// 录制控制器
/// </summary>
public class RecordingController : IRecordingController
{
public static RecordingController Single;
/// <summary>
/// 录制控制器
/// </summary>
/// <param name="support">控制器支持</param>
public RecordingController(IRecordingSupport support)
{
this.Support = support;
this.Recording = new NDIViewRecording();
this.Recording.MaxFrameCount = 30 * 25;
Single = this;
}
/// <summary>
/// 支持
/// </summary>
public IRecordingSupport Support { get; private set; }
/// <summary>
/// NDI视频录制
/// </summary>
private NDIViewRecording Recording;
/// <summary>
/// 添加数据
/// </summary>
/// <param name="frame">帧</param>
/// <param name="data">数据</param>
public void Append(IVideoFrame frame, ClipBoxInfo data)
{
this.Recording.Append(frame, data);
}
/// <summary>
/// 保存
/// </summary>
public void Save()
{
string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "recording");
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
string path = Path.Combine(dir, $"{DateTime.Now.ToString("yyyy_MM_dd__HH_mm_ss")}.avi");
this.Recording.Save(path, 25, 810, 1080);
}
}
}
......@@ -14,15 +14,22 @@ namespace VIZ.H2V.Module
/// <summary>
/// 清理视图控件上下文
/// </summary>
/// <param name="defaultValue">默认值</param>
public ClearVideoControlContext(bool defaultValue)
/// <param name="isClearVideoFrame">是否清理视频帧</param>
/// <param name="defaultClearPluginValue">默认清理插件值</param>
public ClearVideoControlContext(bool isClearVideoFrame, bool defaultClearPluginValue)
{
this.IsClearTrackingBox = defaultValue;
this.IsClearClipBox = defaultValue;
this.IsClearSideCheckPolygon = defaultValue;
this.IsClearVideoFrame = isClearVideoFrame;
this.IsClearTrackingBox = defaultClearPluginValue;
this.IsClearClipBox = defaultClearPluginValue;
this.IsClearSideCheckPolygon = defaultClearPluginValue;
}
/// <summary>
/// 是否清理视频帧
/// </summary>
public bool IsClearVideoFrame { get; set; }
/// <summary>
/// 是否清理跟踪框
/// </summary>
public bool IsClearTrackingBox { get; set; }
......
......@@ -75,5 +75,11 @@ namespace VIZ.H2V.Module
/// </summary>
/// <param name="context">切换模式上下文</param>
void ChangeStrategyMode(ChangeStrategyContext context);
/// <summary>
/// 清理视频控件
/// </summary>
/// <param name="context">清理视频控件上下文</param>
void ClearVideoControl(ClearVideoControlContext context);
}
}
......@@ -70,6 +70,16 @@ namespace VIZ.H2V.Module
{
this.IsActive = true;
}
#if DEBUG
// ====================================================================
// 录制测试
//if (this.ViewKey == NDIViewKeys.CAM_1)
//{
// this.ReecordingController = new RecordingController(this);
//}
// ====================================================================
#endif
}
/// <summary>
......@@ -249,7 +259,7 @@ namespace VIZ.H2V.Module
return;
// 清理视频控件
ClearVideoControlContext clear_context = new ClearVideoControlContext(true);
ClearVideoControlContext clear_context = new ClearVideoControlContext(false, true);
this.ClearVideoControl(clear_context);
// 切换自动模式
......@@ -280,7 +290,7 @@ namespace VIZ.H2V.Module
return;
// 清理视频控件
ClearVideoControlContext clear_context = new ClearVideoControlContext(true);
ClearVideoControlContext clear_context = new ClearVideoControlContext(false, true);
this.ClearVideoControl(clear_context);
// 算法重启
......@@ -306,7 +316,7 @@ namespace VIZ.H2V.Module
return;
// 清理视频控件
ClearVideoControlContext clear_context = new ClearVideoControlContext(true);
ClearVideoControlContext clear_context = new ClearVideoControlContext(false, true);
this.ClearVideoControl(clear_context);
// 停止重启
......@@ -335,7 +345,7 @@ namespace VIZ.H2V.Module
// 清理显示框
if (!this.AlgorithmConfig.IsShowBorder)
{
ClearVideoControlContext clear_context = new ClearVideoControlContext(false);
ClearVideoControlContext clear_context = new ClearVideoControlContext(false, false);
clear_context.IsClearSideCheckPolygon = true;
this.ClearVideoControl(clear_context);
......
......@@ -4,6 +4,7 @@ using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
using System.Windows.Media;
using log4net;
using Newtonsoft.Json;
......@@ -100,9 +101,6 @@ namespace VIZ.H2V.Module
if (view == null)
return;
// 更新画面
view.video.UpdateVideoFrame(e.Frame);
// 更新手动裁切框
// 仅手动模式下处理 & 需要进行裁切 & 3D鼠标准备完毕 时才处理
if (this.StrategyMode == AlgorithmStrategyMode.manual_mode && this.IsUseClip)
......@@ -110,6 +108,21 @@ namespace VIZ.H2V.Module
this.UpdateClipBoxWithManual();
}
#if DEBUG
// ====================================================================
// 录制测试
//if (this.ReecordingController != null)
//{
// ClipBoxInfo temp = new ClipBoxInfo();
// temp.SrcRect = new RawRectangleF((float)(this.ClipBoxX ?? 555), 0, (float)((this.ClipBoxX ?? 555) + 810), 1080);
// this.ReecordingController.Append(e.Frame, temp);
//}
// ====================================================================
#endif
// 更新画面
view.video.UpdateVideoFrame(e.Frame);
// 如果当前模式为手动模式且处于接收裁切信号状态,并且需要进行裁切,那么发送手动裁切信号
if (e.Frame != null && this.ViewConfig.StrategyMode == AlgorithmStrategyMode.manual_mode && this.ViewStatus == NDIViewStatus.CropRoi && this.IsUseClip)
{
......
......@@ -98,6 +98,15 @@ namespace VIZ.H2V.Module
/// </summary>
private IManualController ManualController;
#if DEBUG
/// <summary>
/// 录制控制器
/// </summary>
private IRecordingController ReecordingController;
#endif
// ======================================================================================
// === Property ===
// ======================================================================================
......
......@@ -15,7 +15,13 @@ namespace VIZ.H2V.Module
/// <summary>
/// NDI视图模型
/// </summary>
public partial class NDIViewModel : ViewModelBase, INDIViewService, IAlgorithmSupport, IManualSupport
/// <remarks>
/// INDIViewService -- NDI视图服务
/// IAlgorithmSupport -- 算法支持
/// IManualSupport -- 手动控制支持
/// IRecordingSupport -- 录制支持
/// </remarks>
public partial class NDIViewModel : ViewModelBase, INDIViewService, IAlgorithmSupport, IManualSupport, IRecordingSupport
{
/// <summary>
/// 日志
......@@ -75,6 +81,7 @@ namespace VIZ.H2V.Module
this.AlgorithmControllerDic.Add(AlgorithmStrategyType.Cableway, new AlgorithmController_Cableway(this));
this.ManualController = new ManualController(this);
}
/// <summary>
......@@ -144,7 +151,7 @@ namespace VIZ.H2V.Module
// ----------------------------------------------------------------------------------------------
// 清理视频控件
ClearVideoControlContext clear_context = new ClearVideoControlContext(true);
ClearVideoControlContext clear_context = new ClearVideoControlContext(false, true);
// 当前处于裁切状态时不需要清理裁切框
clear_context.IsClearClipBox = this.ViewStatus != NDIViewStatus.CropRoi;
this.ClearVideoControl(clear_context);
......@@ -239,6 +246,11 @@ namespace VIZ.H2V.Module
if (view == null)
return;
// 清理视频帧
if (context.IsClearVideoFrame)
{
view.video.ClearVideoFrame();
}
// 清理跟踪框
if (context.IsClearTrackingBox)
{
......
using log4net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VIZ.Framework.Module;
using VIZ.H2V.Domain;
using VIZ.H2V.Storage;
namespace VIZ.H2V.Module
{
/// <summary>
/// 应用程序启动 -- 初始化视频录制
/// </summary>
public class AppSetup_Recording : AppSetupBase
{
/// <summary>
/// 日志
/// </summary>
private static ILog log = LogManager.GetLogger(typeof(AppSetup_InitCsv));
/// <summary>
/// 描述
/// </summary>
public override string Detail { get; } = "应用程序启动 -- 初始化视频录制";
/// <summary>
/// 执行启动
/// </summary>
/// <param name="context">应用程序启动上下文</param>
/// <returns>是否成功执行</returns>
public override bool Setup(AppSetupContext context)
{
return true;
}
/// <summary>
/// 执行关闭
/// </summary>
/// <param name="context">应用程序启动上下文</param>
public override void Shutdown(AppSetupContext context)
{
if (RecordingController.Single == null)
return;
RecordingController.Single.Save();
}
}
}
......@@ -22,6 +22,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
......@@ -30,6 +31,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
......@@ -39,6 +41,7 @@
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
......@@ -48,6 +51,7 @@
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="Gma.System.MouseKeyHook, Version=5.6.130.0, Culture=neutral, processorArchitecture=MSIL">
......@@ -65,14 +69,34 @@
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="OpenCvSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL">
<HintPath>..\packages\OpenCvSharp4.4.6.0.20220608\lib\net48\OpenCvSharp.dll</HintPath>
</Reference>
<Reference Include="SharpDX, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\packages\SharpDX.4.2.0\lib\net45\SharpDX.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Management" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Security" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
......@@ -210,6 +234,10 @@
<Compile Include="NDIView\Controller\Manual\IManualController.cs" />
<Compile Include="NDIView\Controller\Manual\IManualSupport.cs" />
<Compile Include="NDIView\Controller\Manual\ManualController.cs" />
<Compile Include="NDIView\Controller\Recording\IRecordingController.cs" />
<Compile Include="NDIView\Controller\Recording\IRecordingSupport.cs" />
<Compile Include="NDIView\Controller\Recording\NDIViewRecording.cs" />
<Compile Include="NDIView\Controller\Recording\RecordingController.cs" />
<Compile Include="NDIView\Enum\NDIViewScene.cs" />
<Compile Include="NDIView\Info\ChangeStrategyContext.cs" />
<Compile Include="NDIView\Info\ClearVideoControlContext.cs" />
......@@ -219,6 +247,7 @@
<Compile Include="NDIView\VieweModel\NDIViewModel.Property.cs" />
<Compile Include="NDIView\VieweModel\NDIViewModel.cs" />
<Compile Include="Setup\Provider\AppSetup_Algorithm.cs" />
<Compile Include="Setup\Provider\AppSetup_Recording.cs" />
<Compile Include="Setup\Provider\AppSetup_InitUDP.cs" />
<Compile Include="Setup\Provider\AppSetup_Navigation3D_TCP.cs" />
<Compile Include="SystemSetting\ViewModel\HotkeySettingPanelViewModel.cs" />
......
......@@ -5,5 +5,11 @@
<package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.39" targetFramework="net48" />
<package id="MouseKeyHook" version="5.6.0" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net48" />
<package id="OpenCvSharp4" version="4.6.0.20220608" targetFramework="net48" />
<package id="SharpDX" version="4.2.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Memory" version="4.5.4" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
</packages>
\ No newline at end of file
......@@ -38,6 +38,13 @@ namespace VIZ.H2V
// 初始化3D鼠标
AppSetup.AppendLoad(new AppSetup_Navigation3D());
#if DEBUG
// ====================================================================
// 录制测试
//AppSetup.AppendSetup(new AppSetup_Recording());
// ====================================================================
#endif
// 执行启动流程
AppSetupContext context = AppSetup.Setup();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment