OSDN Git Service

動画の描画を少し高速化。
[strokestylet/CsWin10Desktop3.git] / FDK24 / メディア / 動画.cs
index e3c36f0..3819189 100644 (file)
@@ -52,7 +52,7 @@ namespace FDK.メディア
                        this.ループ再生する = ループ再生する;
 
                        // タスクを起動する。
-                       this.デコードタスク.Value = System.Threading.Tasks.Task.Factory.StartNew( this._デコードタスクエントリ, (object) 開始位置sec );
+                       this.デコードタスク = System.Threading.Tasks.Task.Factory.StartNew( this._デコードタスクエントリ, (object) 開始位置sec );
                        this.デコードタスク起動完了.WaitOne();
                }
 
@@ -71,7 +71,7 @@ namespace FDK.メディア
                {
                        #region " 条件チェック。"
                        //----------------
-                       if( null == this.デコードタスク.Value || // 再生をまだ開始していないか、あるいはすでに再生を完了してデコードタスクを終了済みである。
+                       if( null == this.デコードタスク ||       // 再生をまだ開始していないか、あるいはすでに再生を完了してデコードタスクを終了済みである。
                                null == this.SourceReaderEx ||          // 動画の準備に失敗した。
                                null == this.MediaType ||                       // 同上
                                null == this.WicBitmap )                        // 同上
@@ -139,7 +139,7 @@ namespace FDK.メディア
                }
                protected ConcurrentQueue<FrameQueueItem> フレームキュー = null;
                protected bool ループ再生する = false;
-               protected FDK.同期.RWLock<System.Threading.Tasks.Task> デコードタスク = new 同期.RWLock<System.Threading.Tasks.Task>();
+               protected System.Threading.Tasks.Task デコードタスク = null;
                protected System.Threading.AutoResetEvent デコードタスク起動完了 = null;
                protected System.Threading.ManualResetEvent キューが空いた = null;
                protected System.Threading.AutoResetEvent デコードタスクを終了せよ = null;
@@ -151,7 +151,7 @@ namespace FDK.メディア
 
                protected override void On活性化( デバイスリソース dr )
                {
-                       this.デコードタスク.Value = null;  // タスクが起動していないときは null であることを保証する。
+                       this.デコードタスク = null;  // タスクが起動していないときは null であることを保証する。
                        this.デコードタスク起動完了 = new System.Threading.AutoResetEvent( false );
                        this.キューが空いた = new System.Threading.ManualResetEvent( true );
                        this.デコードタスクを終了せよ = new System.Threading.AutoResetEvent( false );
@@ -342,8 +342,11 @@ namespace FDK.メディア
                        #region " デコードタスクが起動していたら、終了する。"
                        //----------------
                        this.デコードタスクを終了せよ.Set();
-                       this.デコードタスク.Value?.Wait( 2000 );
-                       this.デコードタスク.Value = null;
+
+                       if( !this.デコードタスク.Wait( 2000 ) )
+                               FDK.Log.WARNING( "デコードタスクの終了待ちがタイムアウトしました。" );
+
+                       this.デコードタスク = null;
                        //----------------
                        #endregion
 
@@ -425,6 +428,7 @@ namespace FDK.メディア
                        events[ EVID_デコードタスクを終了せよ ] = this.デコードタスクを終了せよ;
 
                        this.デコードタスク起動完了.Set();
+
                        this._再生タイマ.Value.リセットする( FDK.カウンタ.QPCTimer.秒をカウントに変換して返す( 再生開始位置sec ) );
 
                        while( System.Threading.WaitHandle.WaitAny( events ) == EVID_キューが空いた )
@@ -444,7 +448,8 @@ namespace FDK.メディア
                                }
                        }
 
-                       this.デコードタスク.Value = null;
+                       this.デコードタスク = null;
+
                        FDK.Log.Info( "デコードタスクを終了しました。" );
                }
 
@@ -694,12 +699,20 @@ namespace FDK.メディア
                                                        byte* src = scanLine0;
                                                        byte* dest = (byte*) bitmapLock.Data.DataPointer.ToPointer();
 
-                                                       for( int y = 0; y < this.サイズdpx.Height; y++ )
+                                                       if( pitch != bitmapStride )
+                                                       {
+                                                               for( int y = 0; y < this.サイズdpx.Height; y++ )
+                                                               {
+                                                                       // ARGB32 to G8B8R8X8 ではデータ変換が不要なので、一行を一気にコピー。
+                                                                       動画.CopyMemory( dest, src, (int) this.サイズdpx.Width * 4 );   // ARGB=4バイト。
+                                                                       src += pitch;
+                                                                       dest += bitmapStride;   // bitmapStride は byte 単位
+                                                               }
+                                                       }
+                                                       else
                                                        {
-                                                               // ARGB32 to G8B8R8X8 ではデータ変換が不要なので、一行を一気にコピー。
-                                                               動画.CopyMemory( dest, src, (int) this.サイズdpx.Width * 4 );   // ARGB=4バイト。
-                                                               src += pitch;
-                                                               dest += bitmapStride;   // bitmapStride は byte 単位
+                                                               // ARGB32 to G8B8R8X8 ではデータ変換が不要、かつ pitch と bitmapStride が等しいので、全行を一括してコピー。
+                                                               動画.CopyMemory( dest, src, (int) ( this.サイズdpx.Width * this.サイズdpx.Height * 4 ) );   // ARGB=4バイト。
                                                        }
                                                }
                                        }