Я написал программу Delphi, которая создает файлы MJPEG, длина которых может составлять несколько ГБ. JPG снимаются с камеры DirectX с использованием DSPack. Эта часть отлично работает и создает файл JPG-изображений в формате:Delphi 7: Чтение блока байтов из TFileStream и копирование в TMemorySTream
FF D8 .... (данные изображения) ... FF D9 FF D8 .... (данные изображения) ... FF D9 FF D8 и т. Д.
FF D8 обозначает начало JPG и FF D9 обозначает конец. Каждый JPG составляет около 21 КБ.
Теперь я пытаюсь написать подходящий плеер MJPEG.
В процедуре FormCreate форме, я создать FileStream и отобразить первый JPG, который работает отлично:
procedure TForm1.FormCreate(Sender: TObject);
var
b: Array[0..1] of Byte;
jpg: TJPEGImage;
begin
:
:
MemoryStream:= TMemoryStream.Create;
jpg:= TJPEGImage.Create;
MJPEGStream:= TFileStream.Create(MJPEGFileName, fmOpenRead);
MJPEGStream.Position:= 0;
repeat
MJPEGStream.Read(b[0], 2); // Find end of first jpg
MemoryStream.Write(b[0], 2); // and write to memory
until (b[0] = $FF) and (b[1] = $D9);
MemoryStream.Position:= 0;
jpg.LoadFromStream(memoryStream);
Image1.Picture.Assign(jpg);
MemoryStream.Free;
jpg.Free;
end;
Я оставляю FileStream так, надеюсь, его указатель положения удерживается открытым. У меня есть кнопка в форме, цель которой состоять в том, чтобы перетащить один JPG за один раз, но, хотя первый «jog» продвигает один JPG, последующие пробежки продвигаются случайным числом раз. Вот процедура:
procedure TForm1.btnJogForwardClick(Sender: TObject);
var
b: Array[0..1] of Byte;
jpg: TJPEGImage;
begin
MemoryStream:= TMemoryStream.Create;
try
repeat
MJPEGStream.Read(b[0], 2);
MemoryStream.Write(b[0], 2);
until ((b[0] = $FF) and (b[1] = $D9));
MemoryStream.Position:= 0;
jpg:= TJPEGImage.Create;
try
try
jpg.LoadFromStream(MemoryStream);
Image1.Picture.Assign(jpg);
except
end;
finally
jpg.Free;
end;
finally
MemoryStream.Free;
end;
Я проверил с игроком третьей партии MJPEG и что может подталкивать кадр за кадром, так что я знаю, что файл MJPEG нормально. Любые предложения относительно того, почему моя процедура не является равномерным по очереди, будут оценены по достоинству.
Thanks, John.
Чтение и запись двух байтов одновременно будет очень неэффективным. Вам нужна буферизация. –
Это немного вяло, но я не уверен, как читать/писать больший блок, не теряя позиции двух конечных байтов (и оставлять указатель готовым в следующем байте Start). Хотя это медленно, я думаю, что если я не смогу заставить это работать, я бы действительно боролся с чем-то более сложным! – vwlowen
Есть ли по определению всегда четное количество байтов данных изображения? Если нет, вы пропустите маркер конца. –