У меня есть приложение Delphi 6 Pro, которое обрабатывает входящие jpeg-кадры с сервера потокового видео.Код работает, но недавно я заметил, что со временем он генерирует огромное количество ошибок программных страниц.После некоторого исследования ошибки страницы появляются из-за одной конкретной графической операции.Обратите внимание, что несжатые растровые изображения имеют размер 320 x 240 или около 300 КБ, поэтому это не связано с обработкой больших изображений.Количество сгенерированных ошибок страниц недопустимо.В течение часа он может легко превысить 1000000 страниц.
Я создал урезанный тестовый пример, который выполняет код, который я включил ниже, по таймеру, 10 раз в секунду.Ошибки страницы появляются, когда я пытаюсь назначить TJpegImage TBitmap в методе GetBitmap ().Я знаю это, потому что я закомментировал эту строку и ошибки страницы не происходят.Метод assign () запускает операцию распаковки со стороны TJpegImage, когда он помещает распакованные биты во вновь созданное растровое изображение, которое возвращает GetBitmap ().Когда я запускаю утилиту pfmon от Microsoft (монитор ошибок страниц), я получаю огромное количество строк ошибок программных ошибок страниц, связанных с RtlFillMemoryUlong, так что это происходит во время операции заполнения буфера памяти.Сводная часть отчета pfmon, в которой показано, какая DLL вызвала ошибку страницы, не отображает имена DLL в крайнем левом столбце.Я пробовал это в другой системе, и там тоже происходит.
Может кто-нибудь предложить исправление или обходной путь?Вот кодОбратите внимание, что IReceiveBufferForClientSocket - это простой объект класса, который содержит байты в накопительном буфере.
function GetBitmap(theJpegImage: TJpegImage): Graphics.TBitmap;
begin
Result := TBitmap.Create;
Result.Assign(theJpegImage);
end;
// ---------------------------------------------------------------
procedure processJpegFrame(intfReceiveBuffer: IReceiveBufferForClientSocket);
var
theBitmap: TBitmap;
theJpegStream, theBitmapStream: TMemoryStream;
theJpegImage: TJpegImage;
begin
theBitmap := nil;
theJpegImage := TJPEGImage.Create;
theJpegStream:= TMemoryStream.Create;
theBitmapStream := TMemoryStream.Create;
try // 2
// ************************ BEGIN JPEG FRAME PROCESSING
// Load the JPEG image from the receive buffer.
theJpegStream.Size := intfReceiveBuffer.numBytesInBuffer;
Move(intfReceiveBuffer.bufPtr^, theJpegStream.Memory^, intfReceiveBuffer.numBytesInBuffer);
theJpegImage.LoadFromStream(theJpegStream);
// Convert to bitmap.
theBitmap := GetBitmap(theJpegImage);
finally
// Free memory objects.
if Assigned(theBitmap) then
theBitmap.Free;
if Assigned(theJpegImage) then
theJpegImage.Free;
if Assigned(theBitmapStream) then
theBitmapStream.Free;
if Assigned(theJpegStream) then
theJpegStream.Free;
end; // try()
end;
// ---------------------------------------------------------------
procedure TForm1.Timer1Timer(Sender: TObject);
begin
processJpegFrame(FIntfReceiveBufferForClientSocket);
end;
// ---------------------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
var
S: string;
begin
FIntfReceiveBufferForClientSocket := TReceiveBufferForClientSocket.Create(1000000);
S := loadStringFromFile('c:\test.jpg');
FIntfReceiveBufferForClientSocket.assign(S);
end;
// ---------------------------------------------------------------
Спасибо, Роберт