4

DSPACK コンポーネント ライブラリで記述された Delphi6 DirectShow フィルタ (プッシュ ソース ビデオ フィルタ) があります。FillBuffer() 呼び出しで、変更されたビットマップを宛先メディア サンプルに出力する前に、ビットマップを変更するいくつかの単純なコードで、本当に厄介な問題が発生しています。コードを以下に示します。

ご覧のとおり、Byte ポインターを使用して 24 ビット ビットマップの RGB 値をトラバースする 2 つの単純なループです。このコードは、DirectShow 以外のテスト アプリケーションでは問題なく動作しました。ただし、私の DirectShow フィルターでは、使用されている値に関係なく、レンダリングされたビットマップに変化が見られません。単純にすべてのバイトを 0 に設定したテスト行も確認できます。画像はまだ変更されていません。ファントムまたは破損したビットマップ オブジェクトがないことを確認するために、ビットマップに簡単な文を出力する行を追加しました。文、レンダリングされたビットマップに表示されます。

さらにややこしいのは、このコードを実行すると、タスク マネージャーから報告されるように、毎秒数千のソフトページ フォールトが発生することです。このコードを無効にすると、ソフトページ フォールトがなくなります。コードがこれを行う原因は何ですか? ループをトレースしたところ、各行の後に Byte 値が変化することが実際に確認されましたが、画像は影響を受けません。

最後に、Scanline を使用せずにピクセル アクセスを行う高速な方法を誰かが知っている場合は、教えてください。TBitmap.Scanline をトレースすると、FreeImage が呼び出されます。可能であれば、メモリ割り当てを最小限に抑えたいと思います。GR32.TBitmap32 を使用できません。Synopse の高速 jpeg デコーダーを使用しており、TBitmap32 オブジェクトでは機能しないためです。

UPDATE : 問題は、ScanLine プロパティにアクセスする前に、ビットマップのPixelFormatプロパティを pf24Bit に設定していなかったことです。詳細については、このスレッドを参照してください:ピクセル変更コードはメイン アプリですばやく実行されますが、Delphi 6 DirectShow フィルターでは他の問題で非常に遅くなります

procedure brightnessTurboBoost(var clip: TBitmap; rangeExpansionPowerOf2: integer; shiftValue: Byte);
var
   p0: PByte;
   x,y: Integer;
begin
   if (rangeExpansionPowerOf2 = 0) and (shiftValue = 0) then
       exit; // These parameter settings will not change the pixel values.

   for y := 0 to clip.Height-1 do
   begin
       p0 := clip.scanline[y];

       // Can't just do the whole buffer as a big block of bytes since the
       //  individual scan lines may be padded for CPU alignment.
       for x := 0 to (clip.Width - 1) * 3 do
       begin
           if rangeExpansionPowerOf2 >= 1 then
               p0^ := IntToByte((p0^ shl rangeExpansionPowerOf2) + shiftValue)
           else
               p0^ := IntToByte(p0^ + shiftValue);

// Test wiping the image (didn't work, still see image).
// p0^ := 0;
           Inc(p0);
       end;
   end;

   clip.Canvas.TextOut(10, 10, 'HELLO THERE IS THERE ANYONE THERE?');
end;
4

1 に答える 1

1

IMediaSampleでは、バッファデータを逆方向にコピーするのとは正確にどのようにコピーしTBitmapているのでしょうか? 最も可能性が高いのは、実際には他の何よりも可能性が高いのは、コピーを変更していて、変更を下流に配信するバッファーに決して戻さないことです。さらに、処理の副作用として、途中でページ フォールトが発生します (イメージ データの変換中に過剰な内部メモリが割り当てられるなど)。

于 2012-01-06T18:42:11.390 に答える