this.ループ再生する = ループ再生する;
// タスクを起動する。
- this.デコードタスク.Value = System.Threading.Tasks.Task.Factory.StartNew( this._デコードタスクエントリ, (object) 開始位置sec );
+ this.デコードタスク = System.Threading.Tasks.Task.Factory.StartNew( this._デコードタスクエントリ, (object) 開始位置sec );
this.デコードタスク起動完了.WaitOne();
}
{
#region " 条件チェック。"
//----------------
- if( null == this.デコードタスク.Value || // 再生をまだ開始していないか、あるいはすでに再生を完了してデコードタスクを終了済みである。
+ if( null == this.デコードタスク || // 再生をまだ開始していないか、あるいはすでに再生を完了してデコードタスクを終了済みである。
null == this.SourceReaderEx || // 動画の準備に失敗した。
null == this.MediaType || // 同上
null == this.WicBitmap ) // 同上
}
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;
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 );
#region " デコードタスクが起動していたら、終了する。"
//----------------
this.デコードタスクを終了せよ.Set();
- this.デコードタスク.Value?.Wait( 2000 );
- this.デコードタスク.Value = null;
+
+ if( !this.デコードタスク.Wait( 2000 ) )
+ FDK.Log.WARNING( "デコードタスクの終了待ちがタイムアウトしました。" );
+
+ this.デコードタスク = null;
//----------------
#endregion
events[ EVID_デコードタスクを終了せよ ] = this.デコードタスクを終了せよ;
this.デコードタスク起動完了.Set();
+
this._再生タイマ.Value.リセットする( FDK.カウンタ.QPCTimer.秒をカウントに変換して返す( 再生開始位置sec ) );
while( System.Threading.WaitHandle.WaitAny( events ) == EVID_キューが空いた )
}
}
- this.デコードタスク.Value = null;
+ this.デコードタスク = null;
+
FDK.Log.Info( "デコードタスクを終了しました。" );
}
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バイト。
}
}
}