public void 描画する(DeviceContext dc, Matrix3x2 換行列2D, float 透明度0to1 = 1.0f) { if (null == this._VideoSource) { return; } long 次のフレームの表示予定時刻100ns = this._VideoSource.Peek(); // 次のフレームがなければ負数 if (0 <= 次のフレームの表示予定時刻100ns) { if ((null != this._最後に描画したフレーム) && (次のフレームの表示予定時刻100ns < this._最後に描画したフレーム.表示時刻100ns)) { // (A) 次のフレームが前のフレームより過去 → ループしたので、タイマをリセットしてから描画する。 this._再生タイマ.リセットする(QPCTimer.秒をカウントに変換して返す(FDKUtilities.換_100ns単位からsec単位へ(次のフレームの表示予定時刻100ns))); this._次のフレームを読み込んで描画する(dc, 換行列2D, 透明度0to1); } else if (次のフレームの表示予定時刻100ns <= this._再生タイマ.現在のリアルタイムカウント100ns) { // (B) 次のフレームの表示時刻に達したので描画する。 this._次のフレームを読み込んで描画する(dc, 換行列2D, 透明度0to1); } else { // (C) 次のフレームの表示時刻にはまだ達していない → 最後に描画したフレームを再描画しておく this.最後のフレームを再描画する(dc, 換行列2D, 透明度0to1); } } else { // (D) デコードが追い付いてない、またはループせず再生が終わっている → 何も表示しない。デコードが追い付いてないなら点滅するだろう。 this._最後に描画したフレーム?.Dispose(); this._最後に描画したフレーム = null; } }
// 再生、停止、再開 public void 再生を開始する(double 再生開始時刻sec = 0.0) { this._VideoSource?.Start(再生開始時刻sec); this._再生タイマ.リセットする(QPCTimer.秒をカウントに変換して返す(再生開始時刻sec)); this.再生中 = true; }