diff --git a/ISCamRecorder/CvCamera.cs b/ISCamRecorder/CvCamera.cs
index 754afad..1bb71fa 100644
--- a/ISCamRecorder/CvCamera.cs
+++ b/ISCamRecorder/CvCamera.cs
@@ -122,7 +122,7 @@
///
public void SaveToFile() {
if (_RecFrames.Count < 1) return;
- Debug.WriteLine($"{_CamID} starts saving with {CameraFPS:0.0}fps.");
+ Common.DebugOut($"{_CamID} starts saving with {CameraFPS:0.0}fps.");
// 保存先確保
var outDir2 = Path.Combine(_MF.OutputDir, _CamID);
Directory.CreateDirectory(outDir2);
@@ -140,7 +140,7 @@
writer.Release();
_RecFrames.Clear();
- Debug.WriteLine($"{_CamID} ends saving.");
+ Common.DebugOut($"{_CamID} ends saving.");
}
///
diff --git a/ISCamRecorder/ISCamera.cs b/ISCamRecorder/ISCamera.cs
index a154853..088e483 100644
--- a/ISCamRecorder/ISCamera.cs
+++ b/ISCamRecorder/ISCamera.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
+using System.Threading;
using System.IO;
using System.Diagnostics;
using TIS.Imaging;
@@ -26,8 +26,11 @@
SinkListener _SinkListener = new SinkListener(); // Sinkリスナー
IFrameQueueBuffer[] _bufferlist = null; // 録画バッファ
bool _Recoding = false; // 録画中フラグ
+
+ public ManualResetEvent Ready { get; private set; } // 録画準備完了シグナル
+ public float CameraFPS { get; private set; } = 0; // カメラFPS
+ public bool DeviceValid { get { return _Cam?.DeviceValid ?? false; } } // デバイス有効・無効
- public float CameraFPS { get; private set; } = 0;
///
/// コンストラクタ
@@ -41,6 +44,7 @@
_CamID = $"Cam{_SerialNumber.Substring(_SerialNumber.Length - 2)}";
_RecSink = new FrameQueueSink(_SinkListener, MediaSubtypes.RGB32);
_PreviewSink = new FrameQueueSink(CaptureFrame, MediaSubtypes.RGB32, 5);
+ Ready = new ManualResetEvent(false);
}
///
@@ -61,14 +65,14 @@
try {
if (File.Exists(ICCF_FILE)){
_Cam.LoadDeviceState(ICCFImport.Import(ICCF_FILE), false);
- Debug.WriteLine($"{_CamID} loaded config {ICCF_FILE}");
+ Common.DebugOut($"{_CamID} loaded config {ICCF_FILE}");
} else {
- //Debug.WriteLine($"Can't find config {ICCF_FILE}");
+ //Common.DebugOut($"Can't find config {ICCF_FILE}");
_Cam.VideoFormat = _Cam.VideoFormats.FirstOrDefault(
c => c.Name.Equals(CAMERA_FORMAT));
_Cam.DeviceFrameRate = _Cam.DeviceFrameRates.FirstOrDefault(
c => (c > FRAME_RATE - 0.1F && c < FRAME_RATE + 0.1F));
- Debug.WriteLine($"{_CamID} sets {_Cam.VideoFormat}, {_Cam.DeviceFrameRate:0.0}fps");
+ Common.DebugOut($"{_CamID} sets {_Cam.VideoFormat}, {_Cam.DeviceFrameRate:0.0}fps");
}
} catch (ICException iex) {
MessageBox.Show(iex.Message, $"{_CamID} Error",
@@ -137,20 +141,32 @@
///
public void RecordToMemory(float recodingLimit) {
if (!_Cam.DeviceValid) return;
- Debug.WriteLine($"{_CamID} starts recoding.");
- _Recoding = true;
- ClearBuffer();
+ _Recoding = false;
+
// メモリ確保
+ ClearBuffer();
var framesToCapture = (int)(recodingLimit * CameraFPS) + 1;
_RecSink.AllocAndQueueBuffers(framesToCapture);
+ Ready.Set();
+ Common.DebugOut($"{_CamID} ready for recoding.");
+
+ // 撮影待機
+ while (!_Recoding) { Thread.Sleep(0); }
+
// 撮影
+ Common.DebugOut($"{_CamID} starts recoding.");
while (_Recoding) {
if (framesToCapture <= _RecSink.OutputQueueSize + 1) break;
}
// 画像バッファに変換
_bufferlist = _RecSink.PopAllOutputQueueBuffers();
_Recoding = false;
- Debug.WriteLine($"{_CamID} ends recoding with {_bufferlist.Length} buffers.");
+ Common.DebugOut($"{_CamID} ends recoding with {_bufferlist.Length} frames.");
+ }
+
+ // 録画開始
+ public void StartRecoding() {
+ _Recoding = true;
}
///
@@ -159,7 +175,7 @@
///
public void SaveToFile() {
if (!_Cam.DeviceValid) return;
- Debug.WriteLine($"{_CamID} starts saving with {CameraFPS}fps.");
+ Common.DebugOut($"{_CamID} starts saving with {CameraFPS}fps.");
// 保存先確保
var outDir2 = Path.Combine(_MF.OutputDir, _CamID);
Directory.CreateDirectory(outDir2);
@@ -196,7 +212,7 @@
// 終了処理
writer.End();
ClearBuffer();
- Debug.WriteLine($"{_CamID} ends saving.");
+ Common.DebugOut($"{_CamID} ends saving.");
}
///
diff --git a/ISCamRecorder/MainForm.cs b/ISCamRecorder/MainForm.cs
index 13b5939..5b60566 100644
--- a/ISCamRecorder/MainForm.cs
+++ b/ISCamRecorder/MainForm.cs
@@ -5,6 +5,7 @@
using System.Drawing;
using System.Linq;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
@@ -237,7 +238,7 @@
_RecodingThread = Task.Run(RecodingThread);
} else if (State == STATE.Recoding) {
// 中断
- Debug.WriteLine("Stop recoding");
+ Common.DebugOut("Stop recoding");
_Cameras.ForEach(c => c.StopRecoding());
}
}
@@ -247,8 +248,7 @@
///
private void RecodingThread()
{
- // 録画開始
- _Sounds[0].Play();
+ // 録画準備
this.Invoke((MethodInvoker)delegate {
for (var i = 0; i < _Cameras.Count; i++) {
if (Setting.RecCameras[i]) _Cameras[i].ChangeSink(true);
@@ -258,18 +258,30 @@
State = STATE.Recoding;
this.UpdateControlState();
});
- _Sensor.StartRecoding(TxtSubjectName.Text);
- // 録画
+ // 録画スレッド開始
Task[] tasks = new Task[_Cameras.Count];
+ List waits = new List();
for (var i = 0; i < _Cameras.Count; i++) {
if (Setting.RecCameras[i]) {
var cam = _Cameras[i];
+ if (cam.DeviceValid) waits.Add(cam.Ready);
tasks[i] = Task.Run(() => cam.RecordToMemory(Setting.RecodingLimit));
} else {
tasks[i] = Task.Run(() => { });
}
}
+
+ // 録画準備待機
+ ManualResetEvent.WaitAll(waits.ToArray());
+ Common.DebugOut("全カメラ準備完了");
+
+ // 録画開始
+ _Cameras.ForEach(c => c.StartRecoding());
+ _Sensor.StartRecoding(TxtSubjectName.Text);
+ _Sounds[0].Play();
+
+ // 録画終了待機
Task.WaitAll(tasks);
// 保存準備
@@ -304,7 +316,7 @@
this.UpdateControlState();
});
_Sounds[2].Play();
- Debug.WriteLine("_RecodingThread ends");
+ Common.DebugOut("_RecodingThread ends");
}
///
@@ -369,11 +381,11 @@
const int timeout = 2000;
_SerialThread.Wait(timeout);
- Debug.WriteLine("_SerialThread ends");
+ Common.DebugOut("_SerialThread ends");
_CvCameraThread.Wait(timeout);
- Debug.WriteLine("_CvCameraThread ends");
+ Common.DebugOut("_CvCameraThread ends");
_TriggerThread.Wait(timeout);
- Debug.WriteLine("_TriggerThread ends");
+ Common.DebugOut("_TriggerThread ends");
this.Invoke((MethodInvoker)delegate {
this.Close();
diff --git a/ISCamRecorder/Program.cs b/ISCamRecorder/Program.cs
index d3e3f8e..aeb7900 100644
--- a/ISCamRecorder/Program.cs
+++ b/ISCamRecorder/Program.cs
@@ -4,8 +4,10 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
+using System.Diagnostics;
namespace ISCamRecorder {
+
internal static class Program {
///
/// アプリケーションのメイン エントリ ポイントです。
@@ -27,4 +29,14 @@
Application.Run(new MainForm());
}
}
+
+ // 共通クラス
+ public static class Common {
+
+ public static void DebugOut(string msg) {
+ var now = DateTime.Now;
+ var timeStr = String.Format("{0:HH:mm:ss.fff}", now);
+ Debug.WriteLine($"[{timeStr}] {msg}");
+ }
+ }
}
diff --git a/ISCamRecorder/SensorData.cs b/ISCamRecorder/SensorData.cs
index 6a89d14..e1666b9 100644
--- a/ISCamRecorder/SensorData.cs
+++ b/ISCamRecorder/SensorData.cs
@@ -60,7 +60,7 @@
var portname = GetSerialPort();
if (portname.Length < 1) {
#if DEBUG
- Debug.WriteLine($"No Serial Connection.");
+ Common.DebugOut($"No Serial Connection.");
#else
MessageBox.Show("シリアルデバイスに接続できません", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
@@ -82,10 +82,10 @@
try {
_Serial.Open();
} catch (Exception ex) {
- Debug.WriteLine(ex.Message);
+ Common.DebugOut(ex.Message);
return false;
}
- Debug.WriteLine($"Serial Connect {portname}.");
+ Common.DebugOut($"Serial Connect {portname}.");
return true;
}
@@ -174,7 +174,7 @@
baseline[0] = (float)ValuesB.Average();
baseline[1] = (float)ValuesR.Average();
baseline[2] = (float)ValuesG.Average();
- //Debug.WriteLine($"逆血閾値 {_ReverseBloodThreshold} Baseline B,R,G={baseline[0]:0.0}, {baseline[1]:0.0}, {baseline[2]:0.0}");
+ //Common.DebugOut($"逆血閾値 {_ReverseBloodThreshold} Baseline B,R,G={baseline[0]:0.0}, {baseline[1]:0.0}, {baseline[2]:0.0}");
}
if (_IsRecoding) {
@@ -187,7 +187,7 @@
count = detectData.Where(v => v >= _ReverseBloodThreshold).Count();
else
count = detectData.Where(v => v <= _ReverseBloodThreshold).Count();
- //Debug.WriteLine($"逆血検出数 {count}");
+ //Common.DebugOut($"逆血検出数 {count}");
if (!_IsReverseBlood && count >= _MF.Setting.RBDetectCount) {
_IsReverseBlood = true;
_MF.ReverseBlood();