Generell mal die Frage, hast du den Beispielcode mal probiert ? Weil im Code von dir fehlt eigentlich alles, was den V4L Teil initialisieren soll.
Wenn du Dateien hochlädst, bitte ohne Exekutable, libs, etc. Das spart mächtig Platz und mir unnötigen Balast.
Dein Code:
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
VideoCapture, YUV2RGB ;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
LabelError: TLabel;
PaintBox1: TPaintBox;
Video: TVideo4L2Device;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure VideoFrame(Sender: TObject; Buffer: pointer; Size: integer;
Error: boolean);
procedure VideoFrameSynchronized(Sender: TObject; Buffer: pointer;
Size: integer; Error: boolean);
private
BMP: TBitmap;
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
BMP := TBitmap.Create;
BMP.Width := PaintBox1.Width;
BMP.Height := PaintBox1.Height;
BMP.PixelFormat := pf24bit;
//BMP.PixelFormat := pf32bit;
// pf24bit; // Byte order: BGR. pf32bit gives inverted RGB order for some reason
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Video.Open := True;
Video.Capture := True;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Video.Free;
BMP.Free;
end;
procedure TForm1.VideoFrame(Sender: TObject; Buffer: pointer;
Size: integer; Error: boolean);
begin
end;
procedure TForm1.VideoFrameSynchronized(Sender: TObject; Buffer: pointer;
Size: integer; Error: boolean);
begin
if Size <> (PaintBox1.Width * PaintBox1.Height * 2{YUYV}) then
begin
LabelError.Caption := 'Invalid buffer length ' + IntToStr(Size);
end;
if Error then
begin
LabelError.Caption := 'Frame with recoverable error received';
end;
BMP.BeginUpdate;
YUYV_to_BGRA(PLongWord(Buffer), PLongWord(BMP.RawImage.Data), BMP.Width * BMP.Height);
//YUYV_to_BGRA16(PLongWord(Buffer), PWord(BMP.RawImage.Data), BMP.Width * BMP.Height);
BMP.EndUpdate;
PaintBox1.Canvas.Draw(0, 0, BMP);
end;
end.
Ich hätte mir so etwas erwartet im Create
Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
begin
// v4l
Video:=TVideo4L2Device.Create(Self);
// A lot of low budgetcameras use this YUYV Format
Video.PixelFormat := V4L2_PIX_FMT_YUYV;
// Set the resoloution and other parameters depending of the camaera
Video.Width := 640;
Video.Height := 480;
Video.FrameRate := 6;
Video.BufferCount := 2;
Video.Device:= '/dev/video0';
Video.OnFrameSynchronized := @VideoFrameSynchronized;
// BMP for on-form preview
BMP:=TBitmap.Create;
BMP.PixelFormat:=pf24bit;
PaintBox.Width := Video.Width;
PaintBox.Height := Video.Height;
BMP.SetSize(Video.Width,Video.Height);
end;
Weil du erzeugst weder das Video Objekt noch wird es von dir initialisiert. Ohne das das Objekt initialisiert ist geht einmal nichts. Man darf dann auch den Debugger nehmen und sich einen Breakpoint in die VideoFrameSynchronized setzen. Dann sieht man, ob die überhaupt angesprungen wird. Wenn nicht, so ist vorher noch ein Fehler drinnen.