Изменения в TBitmap не отображаются на визуализированном изображении в фильтре Delphi 6 DirectShow и генерируют множество программных сбоев страниц - PullRequest
4 голосов
/ 06 января 2012

У меня есть фильтр Delphi6 DirectShow (push-фильтр видео), написанный с использованием библиотеки компонентов DSPACK.У меня действительно неприятная проблема с каким-то простым кодом, который изменяет растровое изображение перед тем, как выводить измененное растровое изображение в целевой образец медиа в моем вызове FillBuffer ().Код показан ниже.

Как вы можете видеть, это всего лишь два простых цикла, которые используют байтовый указатель для прохождения значений RGB в 24-битном растровом изображении.Этот код работал нормально, когда он был в тестовом приложении, отличном от DirectShow.Однако в моем фильтре DirectShow я не вижу никаких изменений в отображаемом растровом изображении независимо от используемых значений.Вы даже можете увидеть тестовую строку, где я просто установил каждый байт в 0. Я все еще видел изображение без изменений.Чтобы убедиться, что у меня нет фантомного или поврежденного растрового объекта, я добавил строку для печати простого предложения на растровом изображении.Предложение показывает на отображаемом растровом изображении.

Еще более запутанным является то, что при выполнении этого кода я получаю тысячи мягких ошибок страницы в секунду, как сообщает TaskМенеджер.Если я отключу этот код, ошибки на странице soft исчезнут.Что может заставить код сделать это?Я проследил весь цикл и действительно видел значение изменения байтовых значений после каждой строки, но изображение остается неизменным.

Наконец, если кто-нибудь знает о быстром способе доступа к пикселям без использования Scanline, я бы хотелзнать.Я проследил через TBitmap.Scanline, и он вызывает FreeImage.Я хотел бы минимизировать распределение памяти, если бы мог.Я не могу использовать GR32.TBitmap32, потому что я использую быстрый jpeg-декодер Synopse, и он не будет работать с объектами TBitmap32.

UPDATE : проблема заключалась в том, что я не устанавливал растровое изображение PixelFormat свойство pf24Bit перед доступом к свойству ScanLine.См. Эту ветку для получения дополнительной информации: Пиксельный модифицирующий код работает быстро в главном приложении, очень медленно в фильтре 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;

1 Ответ

1 голос
/ 06 января 2012

Итак, как именно вы копируете данные буфера IMediaSample в TBitmap, а затем наоборот?Наиболее вероятная вещь, которая на самом деле гораздо более вероятна, чем что-либо еще, заключается в том, что вы меняете копию и никогда не возвращаете изменения обратно в буфер, который вы доставляете вниз по течению.Кроме того, попадание на страницу с ошибками в качестве побочного эффекта обработки (например, чрезмерное выделение внутренней памяти при преобразовании данных изображения назад и вперед).

...