问题
I have a Delphi6 DirectShow filter (push source video filter) written with the DSPACK component library. I am having a truly vexing problem with some simple code that modifies a bitmap before outputting the modified bitmap to the destination media sample in my FillBuffer() call. The code is shown below.
As you can see it is just two simple loops that use a Byte pointer to traverse the RGB values in a 24-bit bitmap. This code worked fine when it was in a non-DirectShow test application. However, in my DirectShow filter, I don't see any change in the rendered bitmap regardless of the values used. You can even see a test line where I simply set every Byte to 0. I still saw the image unmodified. To make sure I didn't have a phantom or damaged bitmap object I added a line to print a simple sentence on the bitmap. The sentence does show on the rendered bitmap.
Even more confusing is that when this code runs I get thousands of soft page faults per second, as reported by Task Manager. If I disable this code the soft page faults go away. What could cause the code to do this? I traced through the loop and did indeed see the Byte values change value after each line, but the image remains unaffected.
Finally, if anyone knows of a fast way to do pixel access without using Scanline I'd like to know. I traced through TBitmap.Scanline and it makes a call to FreeImage. I'd like to minimize memory allocations if I could. I can't use GR32.TBitmap32 because I am using Synopse's fast jpeg decoder and it won't work with TBitmap32 objects.
UPDATE: The problem was that I was not setting the bitmap's PixelFormat property to pf24Bit before accessing the ScanLine property. See this thread for more information: Pixel modifying code runs quick in main app, really slow in Delphi 6 DirectShow filter with other problems
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;
回答1:
So how exactly you are copying IMediaSample
buffer data into TBitmap
and than backward? The most likely thing, which is actually much more likely than anything else, is that you are changing a copy, and never flip the changes back to the buffer you deliver downstream. Additionally hitting page faults on the way as a side effect of the processing (such as excessive internal memory allocations while converting the image data back and forth).
来源:https://stackoverflow.com/questions/8754620/changes-to-tbitmap-do-not-appear-in-rendered-image-in-delphi-6-directshow-filter