Changes to TBitmap do not appear in rendered image in Delphi 6 DirectShow filter and generates lots of soft page faults

StackOverflow https://stackoverflow.com/questions/8762777

Question

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;
Was it helpful?

Solution

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top