デバイスの再接続方法とフレーム落ちの確認
概要
ここではライブストリーミングが停止した場合のカウント方法とPCから接続が切れた(デバイスロストした)時に自動的に復帰する方法と、接続したデバイスから送信したフレームがどの部分でフレーム落ちしているのか確認するための方法についても記載しています。
サンプルプログラム
Software | IC Imaging Control 3.5, Visual Studio™ 2019 |
---|---|
サンプル(C#) | reconnect_camera_cs_3.5.zip |
実行結果
Form1_Loadイベント
private void Form1_Load(object sender, EventArgs e)
{
//デバイスロストのカウントの初期化
count = 0;
if ( !icImagingControl1.LoadShowSaveDeviceState("lastSelectedDeviceState.xml") )
{
MessageBox.Show("No device was selected.", "Reconnect Camera", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Close();
}
else
{
//呼び出したデバイスの設定情報を保存
icImagingControl1.SaveDeviceStateToFile("device.xml");
}
}
フォームを立ち上げた時の処理として、まず初めにグローバル変数として宣言したcountを初期化します。その後、LoadShowSaveDeviceStateメソッドを使ってデバイスダイアログを呼び出します。
デバイスダイアログでエラーなく呼び出した場合にはSaveDeviceStateToFileメソッドを使って、オープンしたデバイス情報をxmlファイルに保存します。このxmlファイルはデバイスロストしたときにカメラを自動的にオープンするために使用します。
DeviceListChangedイベント
private void IcImagingControl1_DeviceListChanged(object sender, EventArgs e)
{
try
{
// デバイスが動作中であれば停止します。
if (icImagingControl1.LiveVideoRunning)
icImagingControl1.LiveStop();
// コンフィギュレーションファイルを Load します。
icImagingControl1.LoadDeviceStateFromFile("device.xml", true);
// ライブビデオを再開します。
if (icImagingControl1.DeviceValid)
icImagingControl1.LiveStart();
//デバイスロストの回数をカウント
count++;
label1.Text = "デバイスロスト: " + count + "回";
}
catch
{
label1.Text = "デバイスロスト";
}
}
DeviceListChangedイベントはDevicesで得られる有効なデバイスに変化があったときに発火するイベントです。 例えば、デバイスロストやデバイスが追加されたタイミングで発火しますので、このイベントハンドラー内にデバイスロストしたときの処理と再開するときの処理をロジックに組み込めばいいことになります。 上記の例ではForm_Loadイベント内で保存したxmlファイルを読み込み、xmlファイルに保存されているファイルがない場合にはtry-catchの例外処理として処理されるようにし、上手く読み込めた場合にはLiveStardtで自動的に開始するロジックとなっています。そうすることで、カメラがPCで認識できなくなった場合(例えば、USBケーブルやイーサネットのケーブルが抜けた場合)、再度ケーブルを指し直すことでソフトウェアのボタンをクリックするなどのGUIを操作することなく、自動的にライブスタートを再開することができます。
フレーム落ちの検出
private void Timer1_Tick(object sender, EventArgs e)
{
if (icImagingControl1.DeviceValid)
{
//DirectShow/ICImagingControlに引き渡される前のドライバに送出されたフレーム数
ulong _framesDelivered = icImagingControl1.DriverFrameDropInformation.FramesDelivered;
//アプリケーション側でドロップしたフレーム数。コールバック中にドライバからアプリケーションのバッファへのコピーに時 間がかかる事が主な要因です。
ulong _framesDroppedDueToApplicationQueue = icImagingControl1.DriverFrameDropInformation.FramesDroppedDueToApplicationQueue;
//データ転送途中にドロップしたフレーム数。受信したデータが不完全であったり、データ帯域幅が十分でないことが原因とし て考えられます。
ulong _framesDroppedDueToPacketLoss = icImagingControl1.DriverFrameDropInformation.FramesDroppedDueToPacketLoss;
//ドライバでドロップしたフレーム数。取得したフォーマットを出力するフォーマットに画像を変換するのが間にあっていない ことが考えらえます。
ulong _framesDroppedDueToTransforms = icImagingControl1.DriverFrameDropInformation.FramesDroppedDueToTransforms;
//原因が特定できないドロップしたフレーム数。ドライバがフレームドロップ情報を提供していない事が考えられます。
ulong _framesDroppedDueUnspecified = icImagingControl1.DriverFrameDropInformation.FramesDroppedDueUnspecified;
label7.Text = _framesDelivered.ToString() + "回";
label8.Text = _framesDroppedDueToApplicationQueue.ToString() + "回";
label9.Text = _framesDroppedDueToPacketLoss.ToString() + "回";
label10.Text = _framesDroppedDueToTransforms.ToString() + "回";
label11.Text = _framesDroppedDueUnspecified.ToString() + "回";
}
}
IC Imaging Control3.5からデバイスドライバにどのくらいドロップアウト(フレーム落ち)したのかアクセスできるプロパティ機能が追加されています。ドライバが送信したフレーム数、ドロップしたフレーム数、またパイプライン内でのドロップが発生した場所についての情報が含まれます。 DriverFrameDropInformationDataクラスの各プロパティの説明は下記の通りです。
プロパティ | 説明 |
---|---|
FramesDelivered | DirectShow/ICImagingControlに引き渡される前のドライバに送出されたフレーム数(トータルのフレーム数) |
FramesDroppedDueToApplicationQueue | アプリケーション側でドロップしたフレーム数。コールバック中にドライバからアプリケーションのバッファへのコピーに時間がかかる事が主な要因です。(通信品質) |
FramesDroppedDueToPacketLoss | データ転送途中にドロップしたフレーム数。受信したデータが不完全であったり、データ帯域幅が十分でないことが原因として考えられます。(PCの性能) |
FramesDroppedDueToTransforms | ドライバでドロップしたフレーム数。取得したフォーマットを出力するフォーマットに画像を変換するのが間にあっていないことが考えらえます。(アプリ起因) |
FramesDroppedDueUnspecified | 原因が特定できないドロップしたフレーム数。ドライバがフレームドロップ情報を提供していない事が考えられます。 |