Toon posts:

[Video capturing] Kan niet meerdere video sources openen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Wij zijn met een project bezig waarbij gebruik wordt gemaakt van een aantal camera'tjes. Deze camera's worden in combinatie met V4L2 gebruikt.

We hebben zelf een programma gemaakt (in Kylix) die vervolgens captures gaat maken van die camera's.

Op zich gaat alles goed wanneer je 1 source opent. Je kan dan zelfs meerdere applicaties tegelijk openen en op alle applicaties is dan hetzelfde beeld van die camera te zien. (Ik lees trouwens zo'n capture uit met de READ functie).

Maar nu is het probleem dat als je meer dan 1 camera tegelijk opent, het systeem alleen nog maar uitgaat van de laatste camera die geopend is. Dus overal zal je dan dat beeld zien.

Nu is het geval dat ons systeem bestaat uit meerdere applicaties. We hebben binnen 1 applicatie dus niet de beschikking over de controle om te bepalen dat nu camera 1 geopend mag worden daarna camera 2, enz..... (zodat ze dus eerst weer gesloten worden voordat de andere weer geopend wordt).

Is er voor dit probleem een oplossing?

Ik dacht namelijk juist dat V4L2 een oplossing was voor dit soort problemen.

Verwijderd

Maar read() je dan alles naar dezelfde buffer ofzo? Zo niet, dan is er toch iets fout in je driver, bijvoorbeeld dat je een shared buffer gebruikt tussen de verschillende instances van de driver voor de kaarten.

edit:
Laat anders de code eens zien waarmee je de kaart opent, waarmee je buffers uitleest e.d... Ik heb het idee dat je iets basaals foutdoet. Dit heeft niks met v4l2 te maken, volgens mij...

[ Voor 33% gewijzigd door Verwijderd op 24-10-2003 13:27 ]


Verwijderd

Topicstarter
Ik begrijp niet precies wat je bedoeld maar ik zal wel ff wat code laat zien:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
function TV4L2.OpenCamera(CameraType: TCameraType; Index: DWORD): Integer;
var V4l2_Input: PV4l2_Input;
    V4l2_Format: PV4l2_Format;
    FileDevice: Integer;
begin
  // Open de camera
  Result := -1;

  if CameraType = ctPins then
  begin
    FFileDevicePinCamera := open(PChar(CAMERA_DEVICE_NAME), O_RDONLY); // or O_NONBLOCK);
    FileDevice := FFileDevicePinCamera;
  end
  else
  begin
    FFileDeviceHeadCamera := open(PChar(CAMERA_DEVICE_NAME), O_RDONLY); // or O_NONBLOCK);
    FileDevice := FFileDeviceHeadCamera;
  end;

  if FileDevice < 0 then
  begin
    Result := errno;
    Exit;
  end;

  // Stel de input channel in
  V4l2_Input := AllocMem(SizeOf(V4l2_Input^));
  try
    if ioctl(FileDevice, VIDIOC_G_INPUT, V4l2_Input) <> 0 then
    begin
      Result := errno;
      Exit;
    end;

    V4l2_Input^.Index := Index;
    V4l2_Input^.InputType := V4L2_INPUT_TYPE_CAMERA;
    V4l2_Input^.Std := DWORD($1);

    if ioctl(FileDevice, VIDIOC_S_INPUT, V4l2_Input) <> 0 then
    begin
      Result := errno;
      Exit;
    end;
  finally
    FreeMem(V4l2_Input);
  end;

  // Stel het formaat in
  V4l2_Format := AllocMem(SizeOf(V4l2_Format^));
  try
    V4l2_Format^.BufType := DWORD(V4L2_BUF_TYPE_VIDEO_CAPTURE);
    if ioctl(FileDevice, VIDIOC_G_FMT, V4l2_Format) < 0 then
    begin
      Result := errno;
      Exit;
    end;

    V4l2_Format^.Pix.Width := CAPTURE_WIDTH;
    V4l2_Format^.Pix.Height := CAPTURE_HEIGHT;
    V4l2_Format^.Pix.PixelFormat := V4L2_PIX_FMT_BGR32;
    V4l2_Format^.Pix.Field := DWORD(V4L2_FIELD_ANY);
    V4l2_Format^.Pix.BytesPerLine := CAPTURE_WIDTH * CAPTURE_BYTES_PIXEL;
    V4l2_Format^.Pix.SizeImage := CAPTURE_WIDTH * CAPTURE_HEIGHT * CAPTURE_BYTES_PIXEL;
    //V4l2_Format^.Pix.ColorSpace := 7;
    V4l2_Format^.Pix.Priv := 0;

    if ioctl(FileDevice, VIDIOC_S_FMT, V4l2_Format) < 0 then
    begin
      Result := errno;
      Exit;
    end;
  finally
    FreeMem(V4l2_Format);
  end;
end;



function TV4L2.TakePinFallPhoto(var PhotoBitmap: TBitmap): Boolean;
var Status: Integer;
begin
  Result := False;

  Status := __read(FFileDevicePinCamera, PhotoBitmap.ScanLine[0]^, CAPTURE_WIDTH * CAPTURE_HEIGHT * CAPTURE_BYTES_PIXEL);
  if Status < 0 then
    BowlingLane.WriteToLog('V4L2: Error making pinfallphoto at TakePinFallPhoto: ' + IntToStr(errno))
  else
    Result := True;
 end;


function TV4l2.GetHeadPhoto(var HeadPhoto: TBitmap): Boolean;
var Status: Integer;
    i: Integer;
    Row: Integer;
    PSL: PByteArray;
begin
  Result := False;

  Status := __read(FFileDeviceHeadCamera, FBitmap.ScanLine[0]^, CAPTURE_WIDTH * CAPTURE_HEIGHT * CAPTURE_BYTES_PIXEL);
  if Status < 0 then
    BowlingLane.WriteToLog('V4L2: Error making head photo at GetHeadPhoto: ' + IntToStr(errno))
  else
  begin
    Result := True;

    i := Integer(FPointerCropBufferHead);
    for Row := 0 to CAPTURE_HEAD_HEIGHT - 1 do
    begin
      PSL := FBitmap.ScanLine[Row];
      Move(PSL^[((CAPTURE_WIDTH - CAPTURE_HEAD_WIDTH) DIV 2) * CAPTURE_BYTES_PIXEL], Ptr(i)^, CAPTURE_HEAD_WIDTH * CAPTURE_BYTES_PIXEL);
      i := I + CAPTURE_HEAD_WIDTH * CAPTURE_BYTES_PIXEL;
    end;

    Move(FPointerCropBufferHead^, HeadPhoto.ScanLine[0]^, CAPTURE_HEAD_WIDTH * CAPTURE_HEAD_HEIGHT * CAPTURE_BYTES_PIXEL);
  end;
end;



Vervolgens worden er bijv 2 camera's geopend:
Delphi:
1
2
    V4L2.OpenCamera(ctPins, 0);
    V4L2.OpenCamera(ctHead, 1);


Nu is het probleem dat die altijd van de laatste opencamera actie het index nummer pakt van de video source.

Dus nu is bij de pins camera ook het beeld te zien van de head camera.

Verwijderd

Je gebruikt dezelfde buffer voor de read() in beide devices. That is, ik zie niet dat de buffers per-cam zijn.

Je kan het beste een object voor elke camera aanmaken met de file descriptor, buffer en cam info (if needed).

Verwijderd

Topicstarter
Verwijderd schreef op 24 October 2003 @ 15:27:
Je gebruikt dezelfde buffer voor de read() in beide devices. That is, ik zie niet dat de buffers per-cam zijn.

Je kan het beste een object voor elke camera aanmaken met de file descriptor, buffer en cam info (if needed).
Ik gebruik een object waar o.a. de filedescriptors instaan van de 2 camera's. Maar wat ik niet begrijp is dat je zegt dat ik "dezelfde buffers" voor de read gebruik?

Als ik die read functie uitvoer krijg ik een X aantal bytes terug die ik vervolgens toeken aan verschillende bitmaps. Hierdoor zou het juist geen probleem moeten zijn.

Maar waar kan ik dan aangeven dat ik verschillende buffers wil gebruiken voor die reads? (volgens mij niet met de read methode)

[ Voor 42% gewijzigd door Verwijderd op 24-10-2003 15:39 ]


Verwijderd

Topicstarter
Is er niemand die een oplossing weet? (Het is namelijk nu een heel groot probleem voor ons.)

Verwijderd

Check je mail. :P.

edit:
Voor de niet-begrijpers: we hebben onderling via email wat info uitgewisseld. Ik gok momenteel dat hij vier inputs aan een BTTV chip heeft hangen. Echter, je kan maar een input tegelijk gebruiken per chip, en dus zal elke sessie op dezelfde BTTV chip ook dezelfde input ontvangen. Dit is een chip-tekortkoming en heeft niks met programmeerfouten te maken. Om dit op te lossen moet je dus input switchen voor elke sessie voordat je read() doet, of je moet een BTTV chip per input doen (= duur!)... /me wacht op tokkie's uitsluitsel. :).

[ Voor 94% gewijzigd door Verwijderd op 27-10-2003 13:22 ]

Pagina: 1