Dafür habe ich eine C-Bibliothek übersetzt und eingebunden, mit dieser funktioniert alles.
Nun wollte ich Befehl für Befehl nach Pascal übernehmen, Dabei musste ich fesstellen, wen ich FpIOCtl() zum auslesen der Parameter und später auch für die Video-Daten verwende, ist alles io. Sobald ich aber FpIOCtl zum schreiben verwende, scheitert es.
Zuerst die zei Code-Schnipsel in C, die eignen sich ideal, da der Set und Get die gleiche struct/record für dir Daten verwenden. Somit scheidet ein Fehler aus, was die Übersetzung der struct zu record betrifft, ansonsten würde mein GetFormat in Pascal nicht funktionieren.
Code: Alles auswählen
// set format
int v4l2_sfmt(int fd, uint32_t pfmt) {
struct v4l2_format fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.pixelformat = pfmt;
fmt.fmt.pix.height = IMAGE_HEIGHT;
fmt.fmt.pix.width = IMAGE_WIDTH;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
fprintf(stderr, "Unable to set format\n");
return -1;
}
return 0;
}
// get format
int v4l2_gfmt(int fd) {
struct v4l2_format fmt;
if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) {
fprintf(stderr, "Unable to get format\n");
return -1;
}
printf("\033[33mpix.pixelformat:\t%c%c%c%c\n\033[0m",
fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF,
(fmt.fmt.pix.pixelformat >> 16) & 0xFF,
(fmt.fmt.pix.pixelformat >> 24) & 0xFF);
printf("pix.height:\t\t%d\n", fmt.fmt.pix.height);
printf("pix.width:\t\t%d\n", fmt.fmt.pix.width);
printf("pix.field:\t\t%d\n", fmt.fmt.pix.field);
return 0;}
Ich habe noch versucht direkt die ioctl() von der clib zu verwenden, aber wie erwartet ohne Erfolg. Lesen geht, Schreiben scheitert.
Code: Alles auswählen
function ioctl(fd: cint; request: culong): cint; cdecl; varargs; external; // als Test
function SetFormat(fHandle: cint; pfmt: uint32): cint;
var
fmt: Tv4l2_format;
begin
WriteLn(SizeOf(fmt));
WriteLn(SizeOf(fmt.fmt.pix));
// FillChar(fmt, SizeOf(fmt), $00);
// FillChar(fmt.fmt.pix, SizeOf(fmt.fmt.pix), $00);
fmt._type := V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.pixelformat := pfmt;
fmt.fmt.pix.Height := IMAGE_HEIGHT;
fmt.fmt.pix.Width := IMAGE_WIDTH;
fmt.fmt.pix.field := V4L2_FIELD_INTERLACED;
if IOCtl(fHandle, VIDIOC_S_FMT, @fmt) = -1 then begin
Result := -1; // Wird nicht ausgelöst, obwohl falsche Daten geschrieben.
WriteLn('Fehler: SetFormat()');
Exit;
end;
Result := 0;
end;
function GetFormat(fHandle: cint): cint;
var
fmt: Tv4l2_format;
begin
FillChar(fmt, SizeOf(fmt), $00);
fmt.fmt.pix.Height := 122;
if IOCtl(fHandle, VIDIOC_G_FMT, @fmt) = -1 then begin
Result := -1; // Der Fehler kommt hier, wen SetFormat falsch geschrieben hat.
WriteLn('Fehler: GetFormat()');
Exit;
end;
WriteLn(#27'[33mpix.pixelformatth: ',
char(fmt.fmt.pix.pixelformat and $FF),
char(fmt.fmt.pix.pixelformat shr 8 and $FF),
char(fmt.fmt.pix.pixelformat shr 16 and $FF),
char(fmt.fmt.pix.pixelformat shr 24 and $FF), #27'[0m');
WriteLn('pix.width: ', fmt.fmt.pix.Width);
WriteLn('pix.height: ', fmt.fmt.pix.Height);
WriteLn('pix.field: ', fmt.fmt.pix.field);
Result := 0;
end;
Verwende ich das C-SetFormat, gehen beide GetFormat, und beim Pascal-Setformat, scheitern beide GetFormat.
Was ich noch sagen muss, bei meinem SetFormat wird keine Fehler bei ioctrl ausgespuckt, aber es wird was falsches geschriebn, ansonsten würde ja das GetFormat funktionieren, erst da merke ich, das falsche Daten geschrieben wurden.
Code: Alles auswählen
v4l2_sfmt(video_fildes, V4L2_PIX_FMT_YUYV); // geht
SetFormat(video_fildes, V4L2_PIX_FMT_YUYV); // geht nicht
WriteLn(#10#27'[0m--- Pascal ---');
GetFormat(video_fildes); // geht
WriteLn(#10'--- C ---');
v4l2_gfmt(video_fildes); // geht
Das Auslesen später der Daten mit FpIOCtl () geht ohne Probleme.
Code: Alles auswählen
fpFD_ZERO(fds);
fpFD_SET(video_fildes, fds);
fpSelect(video_fildes + 1, @fds, nil, nil, @tv);
buf._type := V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory := V4L2_MEMORY_MMAP;
FpIOCtl(video_fildes, VIDIOC_DQBUF, @buf);