diff --git a/ISCamRecorder/ISCamRecorder.csproj b/ISCamRecorder/ISCamRecorder.csproj index 45d984e..24f4ed3 100644 --- a/ISCamRecorder/ISCamRecorder.csproj +++ b/ISCamRecorder/ISCamRecorder.csproj @@ -82,6 +82,7 @@ + MainForm.cs diff --git a/ISCamRecorder/ISCamera.cs b/ISCamRecorder/ISCamera.cs index cc620b8..1801e68 100644 --- a/ISCamRecorder/ISCamera.cs +++ b/ISCamRecorder/ISCamera.cs @@ -18,6 +18,11 @@ string _SerialNumber; // シリアル番号 VCDButtonProperty _Trigger; // トリガー設定 FrameRateCounter _Fps = new FrameRateCounter(10); // フレームレート計測 + SinkListener _SinkListener = new SinkListener(); + FrameQueueSink _PreviewSink; + FrameQueueSink _RecSink; + IFrameQueueBuffer[] _bufferlist; + public float FrameRate { get { return _Fps.FrameRate; } } /// @@ -64,10 +69,12 @@ // 表示設定 _Cam.LiveDisplayDefault = false; SetDisplaySize(); - // ic.ImageRingBufferSize = 2; + _Cam.ImageRingBufferSize = 5; _Trigger = _Cam.VCDPropertyItems.Find( VCDGUIDs.VCDID_TriggerMode, VCDGUIDs.VCDElement_SoftwareTrigger); - _Cam.Sink = new FrameQueueSink(CaptureFrame, MediaSubtypes.RGB32, 5); + _RecSink = new FrameQueueSink(_SinkListener, MediaSubtypes.RGB32); + _PreviewSink = new FrameQueueSink(CaptureFrame, MediaSubtypes.RGB32, 5); + _Cam.Sink = _PreviewSink; _Cam.LiveStart(); @@ -75,6 +82,55 @@ } /// + /// Sink変更 + /// + /// true:録画 false:プレビュー + public void ChangeSink(bool isRec) { + _Cam.LiveStop(); + if (isRec) _Cam.Sink = _RecSink; + else _Cam.Sink = _PreviewSink; + _Cam.LiveStart(); + } + + /// + /// 録画 + /// + public void RecordToMemory() { + Debug.WriteLine($"Cam {_SerialNumber} starts recoding."); + var framesToCapture = 30; + _RecSink.AllocAndQueueBuffers(framesToCapture); + while (true) { + if (framesToCapture <= _RecSink.OutputQueueSize + 1) break; + } + _bufferlist = _RecSink.PopAllOutputQueueBuffers(); + Debug.WriteLine($"Cam {_SerialNumber} buffersize {_bufferlist.Length}."); + + for (int i = 0; i < _bufferlist.Length; i++) { + + //デバイスが生成したフレーム番号が格納されます。 + string strFrameNumber = _bufferlist[i].FrameMetadata.DeviceFrameNumber.ToString(); + + //(有効な場合)デバイスのタイムスタンプが格納されます。 + // デバイス固有のタイムソースによるタイムスタンプです。 + string strDeviceTimeStamp = _bufferlist[i].FrameMetadata.DeviceTimeStamp.ToString(); + + //このフレームの最初のパケットをドライバが受信した時刻が格納されます。 + string strSampleStartTime = _bufferlist[i].FrameMetadata.DriverFrameFirstPacketTime.ToString(@"hhmmss\.fff"); + + //ドライバがこのフレームに与えたフレーム番号が格納されます。 + string strDriverFrameNumber = _bufferlist[i].FrameMetadata.DriverFrameNumber.ToString(); + + var fileName = $"Cam{_SerialNumber.Substring(_SerialNumber.Length-2)}_" + strSampleStartTime + ".jpg"; + TIS.Imaging.FrameExtensions.SaveAsJpeg(_bufferlist[i], fileName, 80); + } + + _bufferlist = null; + GC.Collect(); + + Debug.WriteLine($"Cam {_SerialNumber} ends recoding."); + } + + /// /// 表示サイズ設定 /// public void SetDisplaySize() { diff --git a/ISCamRecorder/MainForm.Designer.cs b/ISCamRecorder/MainForm.Designer.cs index e02bb7c..93ebbd1 100644 --- a/ISCamRecorder/MainForm.Designer.cs +++ b/ISCamRecorder/MainForm.Designer.cs @@ -283,7 +283,7 @@ this.TxtRecodingDulation.Name = "TxtRecodingDulation"; this.TxtRecodingDulation.Size = new System.Drawing.Size(34, 19); this.TxtRecodingDulation.TabIndex = 8; - this.TxtRecodingDulation.Text = "15"; + this.TxtRecodingDulation.Text = "3"; this.TxtRecodingDulation.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.TxtRecodingDulation.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.TxtRecodingDulation_KeyPress); // @@ -348,6 +348,7 @@ this.BtnRecodeMovie.TabIndex = 15; this.BtnRecodeMovie.Text = "動画撮影"; this.BtnRecodeMovie.UseVisualStyleBackColor = true; + this.BtnRecodeMovie.Click += new System.EventHandler(this.BtnRecodeMovie_Click); // // TxtTriggerFPS // diff --git a/ISCamRecorder/MainForm.cs b/ISCamRecorder/MainForm.cs index 49edbed..6577f63 100644 --- a/ISCamRecorder/MainForm.cs +++ b/ISCamRecorder/MainForm.cs @@ -179,5 +179,23 @@ e.Handled = true; } } + + /// + /// 動画撮影 + /// + /// + /// + private void BtnRecodeMovie_Click(object sender, EventArgs e) { + // 録画モードへ変更 + _Cameras.ForEach(c => c.ChangeSink(true)); + // 録画 + Task[] tasks = new Task[4]; + for (var i = 0; i < tasks.Length; i++) { + tasks[i] = Task.Run(_Cameras[i].RecordToMemory); + } + Task.WaitAll(tasks); + // プレビューモードへ変更 + _Cameras.ForEach(c => c.ChangeSink(false)); + } } } diff --git a/ISCamRecorder/SinkListener.cs b/ISCamRecorder/SinkListener.cs new file mode 100644 index 0000000..cbdc7f1 --- /dev/null +++ b/ISCamRecorder/SinkListener.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TIS.Imaging; + +namespace ISCamRecorder { + internal class SinkListener : IFrameQueueSinkListener { + public void FramesQueued(FrameQueueSink sink) { + if (sink.InputQueueSize == 0) { + sink.QueueBuffer(sink.PopOutputQueueBuffer()); + } + } + + public void SinkConnected(FrameQueueSink sink, FrameType frameType) { + } + + public void SinkDisconnected(FrameQueueSink sink, IFrameQueueBuffer[] dequeuedBuffers) { + + } + } +}