Delphi 6 DirectShow过滤器中的渲染图像中不会出现对TBitmap的更改,并会生成大量软页面错误 [英] Changes to TBitmap do not appear in rendered image in Delphi 6 DirectShow filter and generates lots of soft page faults
问题描述
正如您所看到的,它只是两个简单的循环,它们使用Byte指针遍历24位位图中的RGB值。此代码在非DirectShow测试应用程序中正常工作。但是,在我的DirectShow过滤器中,无论使用哪个值,都不会在渲染的位图中看到任何更改。你甚至可以看到一个测试线,我简单地设置每个字节为0.我仍然看到图像未修改。为了确保我没有幻影或损坏的位图对象,我添加了一行来在位图上打印一个简单的句子。更复杂的是,当这段代码运行时,我得到了成千上万个 soft 的每秒的页面错误,由任务管理器报告。如果我禁用此代码,则 soft 页面错误消失。什么可能导致代码做到这一点?我追踪了循环,并确实看到每行后的字节值更改值,但图像保持不变。
最后,如果有人知道一个快速的方法像素访问不使用Scanline我想知道。我追踪了TBitmap.Scanline并调用了FreeImage。我想尽可能减少内存分配。我无法使用GR32.TBitmap32,因为我使用的是Synopse的快速jpeg解码器,它不能用于TBitmap32对象。
$ b
更新:问题在于,在访问ScanLine属性之前,我没有将位图的 PixelFormat 属性设置为pf24Bit。有关详细信息,请参阅此主题:
在主应用程序中快速执行像素修改代码,在Delphi 6 DirectShow过滤器中真的很慢程序brightnessTurboBoost(var clip:TBitmap; rangeExpansionPowerOf2:integer; shiftValue:Byte);
var
p0:PByte;
x,y:整数;如果(rangeExpansionPowerOf2 = 0)和(shiftValue = 0)则
开始
,则
exit; //这些参数设置不会改变像素值。
for y:= 0 to clip.Height-1 do
begin
p0:= clip.scanline [y];
//由于
//单独的扫描行可能被填充以进行CPU对齐,因此不能只将整个缓冲区作为大块字节来执行。
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);
//测试擦图像(没有工作,仍然看图像)。
// p0 ^:= 0;
Inc(p0);
end;
end;
clip.Canvas.TextOut(10,10,'你好有人吗?');
end;
> IMediaSample 将数据缓冲到 TBitmap
而不是向后?最有可能的事情,实际上比其他任何事情都更可能的是,你正在改变一个副本,而不是把这些改变反转回到你下游传递的缓冲区。另外,在处理的副作用(例如,在来回转换图像数据时过度的内存分配)上打印页面错误。
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;
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).
这篇关于Delphi 6 DirectShow过滤器中的渲染图像中不会出现对TBitmap的更改,并会生成大量软页面错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!