Ich habe ein Delphi-Programm geschrieben, das MJPEG-Dateien erstellt, die mehrere GB groß sein können. Die JPGs werden von einer DirectX-Kamera mit DSPack abgerufen. Dieser Teil funktioniert gut und erstellt eine Datei von JPG-Bildern im Format:Delphi 7: Lesen eines Byteblocks aus einem TFileStream & Kopieren nach TMemorySTream
FF D8 .... (Bilddaten) ... FF D9 FF D8 .... (Bilddaten) ... FF D9 FF D8 usw.
FF D8 markiert den Beginn eines JPG und FF D9 markiert das Ende. Jedes JPG ist etwa 21 KB groß.
Jetzt versuche ich einen passenden MJPEG-Player zu schreiben.
In der Formcreate Prozedur des Formulars, erstelle ich einen Filestream und die erste JPG anzeigen, die gut funktioniert:
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;
ich das Filestream offen lassen, so, hoffentlich, wird seine Position Zeiger beibehalten. Ich habe einen Knopf auf dem Formular, mit der Absicht, einen JPG nach dem anderen zu joggen, aber, obwohl der erste 'jog' einen JPG vorschiebt, schreiten die nachfolgenden jogs eine zufällige Anzahl von Malen vor. Hier ist die Prozedur:
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;
Ich habe mit einem 3rd-Party-MJPEG-Player überprüft und die in der Lage Frame für Frame joggen, damit ich weiß, dass die MJPEG-Datei in Ordnung ist. Irgendwelche Vorschläge, warum meine Prozedur nicht gleichmäßig Frame für Frame fortschreitet, würde geschätzt werden.
Danke, John.
Lesen und Schreiben von zwei Bytes gleichzeitig ist sehr ineffizient. Du brauchst etwas Pufferung. –
Es ist ein bisschen träge, aber ich bin mir nicht sicher, wie man einen größeren Block lesen/schreiben kann, ohne die Position der beiden Endbytes zu verlieren (und den Zeiger beim nächsten Startbyte bereit zu halten). Obwohl es langsam ist, denke ich, wenn ich das nicht zur Arbeit bringen kann, würde ich wirklich mit etwas komplizierteren kämpfen! – vwlowen
Gibt es definitionsgemäß immer eine gerade Anzahl von Bilddatenbytes? Wenn nicht, verpassen Sie den Endmarker. –