From: くまかみ工房 Date: Wed, 26 Oct 2016 06:19:59 +0000 (+0900) Subject: 動画のループ再生できなかった不具合を修正。 X-Git-Url: http://git.osdn.net/view?p=strokestylet%2FCsWin10Desktop3.git;a=commitdiff_plain;h=ae490d531c48b923dfe14e3d3c9de760faace6ad 動画のループ再生できなかった不具合を修正。 --- diff --git a/FDK24/メディア/動画.cs b/FDK24/メディア/動画.cs index 1e006e4..cc82e95 100644 --- a/FDK24/メディア/動画.cs +++ b/FDK24/メディア/動画.cs @@ -35,15 +35,12 @@ namespace FDK.メディア { this.動画の生成に成功した = false; - #region " デコーダを生成する。" - //---------------- + // デコーダを生成する。 this.デコーダ = new 動画デコーダ( dr, this.動画ファイルパス, this.ループ再生する, this.キューのサイズ ); this.デコーダ.現在の再生時刻100ns = () => { return this.タイマ.Value.現在のリアルタイムカウント100ns単位; }; this.デコーダ.デコードキャッシング(); - //---------------- - #endregion this.動画の生成に成功した = true; Log.Info( $"{Utilities.現在のメソッド名}: 動画を生成しました。[{変数付きファイルパス}]" ); @@ -103,8 +100,9 @@ namespace FDK.メディア { var dummy = (SharpDX.Direct2D1.Bitmap) null; var 再生時刻sec = 0.0; - if( this.デコーダ.次のビットマップの有無を確認する( out dummy, out 再生時刻sec ) && - ( this.タイマ.Value.現在のリアルタイムカウント秒単位 >= 再生時刻sec + this.デコーダ.ループした際の先頭時刻sec ) ) + bool 次がある = this.デコーダ.次のビットマップの有無を確認する( out dummy, out 再生時刻sec ); + double 現在時刻sec = this.タイマ.Value.現在のリアルタイムカウント秒単位; + if( 次がある && ( 現在時刻sec >= 再生時刻sec ) ) { // (C-a) 確認できて、かつ再生時刻になった場合 → サンプルをD2Dビットマップに転写し、描画する。 this.前回表示したD2Dビットマップ?.Dispose(); diff --git a/FDK24/メディア/動画デコーダ.cs b/FDK24/メディア/動画デコーダ.cs index ffa165f..45346fe 100644 --- a/FDK24/メディア/動画デコーダ.cs +++ b/FDK24/メディア/動画デコーダ.cs @@ -14,7 +14,7 @@ namespace FDK.メディア public class 動画デコーダ : FDK.同期.RWLockAction, IDisposable { // 外部依存Action。 - public Func 現在の再生時刻100ns = null; + public Func 現在の再生時刻100ns = null; public SharpDX.Size2 サイズdpx { @@ -33,23 +33,6 @@ namespace FDK.メディア } ); } } - public double ループした際の先頭時刻sec - { - get - { - double sec = 0.0; - this.ReadLock( () => { - sec = this.bs_ループした際の先頭時刻sec; - } ); - return sec; - } - set - { - this.WriteLock( () => { - this.bs_ループした際の先頭時刻sec = value; - } ); - } - } public 動画デコーダ( デバイスリソース dr, string 動画ファイルパス, bool ループ再生する, int キューのサイズ ) { @@ -268,6 +251,8 @@ namespace FDK.メディア } public void デコードを開始する() { + this.前フレームの再生時刻100ns = 0; + this.先頭時刻100ns = 0; this.デコードタスク = Task.Factory.StartNew( this.デコードタスクエントリ ); } /// @@ -282,28 +267,29 @@ namespace FDK.メディア 再生時刻sec = 0.0; return false; // キューが空だったか、Dequeue が一歩遅かった?(ないはずだが } - - D2Dビットマップ = item.D2Dビットマップ; // キューから出しても、代入しても、COMの参照カウントは変化しない。 - 再生時刻sec = item.再生時刻sec; - - this.前フレームの時刻sec = item.再生時刻sec; - this.キューが空いた.Set(); // キューが空いたので、このイベントを set する。 - - return true; + else + { + D2Dビットマップ = item.D2Dビットマップ; // キューから出しても、代入しても、COMの参照カウントは変化しない。 + 再生時刻sec = item.再生時刻sec; + this.キューが空いた.Set(); // キューが空いたので、このイベントを set する。 + return true; + } } public bool 次のビットマップの有無を確認する( out SharpDX.Direct2D1.Bitmap D2Dビットマップ, out double 再生時刻sec ) { QueueItem item = null; - if( ( 0 == this.SampleQueue.Count ) || ( false == this.SampleQueue.TryPeek( out item ) ) ) // キューから取り出さない。 + if( ( 0 == this.SampleQueue.Count ) || ( false == this.SampleQueue.TryPeek( out item ) ) ) // キューから取り出さない。 { D2Dビットマップ = null; 再生時刻sec = 0.0; return false; // キューが空だったか、Peek が一歩遅かった?(ないはずだが } - - D2Dビットマップ = item.D2Dビットマップ; // 代入しても、COMの参照カウントは変化しない。 - 再生時刻sec = item.再生時刻sec; - return true; + else + { + D2Dビットマップ = item.D2Dビットマップ; // 代入しても、COMの参照カウントは変化しない。 + 再生時刻sec = item.再生時刻sec; + return true; + } } protected class QueueItem : IDisposable @@ -320,7 +306,8 @@ namespace FDK.メディア protected SharpDX.MediaFoundation.SourceReaderEx SourceReaderEx; protected SharpDX.MediaFoundation.MediaType MediaType; protected bool ループ再生する = false; - protected double 前フレームの時刻sec = -1.0; + protected long 先頭時刻100ns = 0; + protected long 前フレームの再生時刻100ns = 0; protected System.Threading.Tasks.Task デコードタスク = null; protected ManualResetEvent キューが空いた = new ManualResetEvent( true ); protected AutoResetEvent タスクを終了せよ = new AutoResetEvent( false ); @@ -378,7 +365,8 @@ namespace FDK.メディア { // (A) ループ再生する場合 FDK.Log.Info( "動画をループ再生します。" ); - this.ループした際の先頭時刻sec = this.前フレームの時刻sec; // EndOfStream フラグがセットされたときは、ReadSample() で返されるサンプル時刻は無効(0 になっている)。 + this.先頭時刻100ns += this.前フレームの再生時刻100ns; + this.前フレームの再生時刻100ns = 0; this.SourceReaderEx.SetCurrentPosition( 0 ); // ストリーム再生位置を先頭へ。 return this.サンプルをひとつ取得してキューへ格納する(); // 再帰で先頭サンプルを取得して返す。 } @@ -418,15 +406,17 @@ namespace FDK.メディア //--------------------------------------------------- #endregion - if( this.現在の再生時刻100ns() < 再生時刻100ns ) // 現時点でもう再生時刻を超えてるなら、スキップする。 + if( this.現在の再生時刻100ns() < (this.先頭時刻100ns + 再生時刻100ns) ) // 現時点でもう再生時刻を超えてるなら、スキップする。 { this.サンプルをD2Dビットマップに転送する( sample, out bitmap ); // ビットマップをキューへ格納する。 this.SampleQueue.Enqueue( new QueueItem() { D2Dビットマップ = bitmap, // COM参照カウントは変化しない。 - 再生時刻sec = (double) ( 再生時刻100ns / ( 10.0 * 1000.0 * 1000.0 ) ), // 100ns単位 → 秒単位へ変換。 + 再生時刻sec = (double) ( ( this.先頭時刻100ns + 再生時刻100ns ) / ( 10.0 * 1000.0 * 1000.0 ) ), // 100ns単位 → 秒単位へ変換。 } ); + + this.前フレームの再生時刻100ns = 再生時刻100ns; } } catch( Exception e ) @@ -621,7 +611,6 @@ namespace FDK.メディア #region " バックストア。" //---------------- - private double bs_ループした際の先頭時刻sec = 0.0; private SharpDX.Size2 bs_サイズdpx = new SharpDX.Size2( 1, 1 ); //---------------- #endregion