UsbVideo.Mod 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524
  1. MODULE UsbVideo; (** AUTHOR "Timothée Martiel, 2015"; PURPOSE "USB video device driver"; *)
  2. IMPORT SYSTEM, Commands, Modules, Objects, Kernel, Plugins, Streams, Files, Usbdi, UsbHcdi, Usb, UsbVideoDesc, KernelLog;
  3. CONST
  4. (*! REMOVE AFTER DEBUG *)
  5. Size =120 * 160 * 2;
  6. (*! END REMOVE AFTER DEBUG *)
  7. Name = "Video Class";
  8. Description = "USB Video Class driver";
  9. Priority = 10;
  10. ProbeLength = 48;
  11. (* Video-class specific request codes *)
  12. SetCur = 01H;
  13. SetCurAll = 11H;
  14. GetCur = 81H;
  15. GetMin = 82H;
  16. GetMax = 83H;
  17. GetRes = 84H;
  18. GetLen = 85H;
  19. GetInfo = 86H;
  20. GetDef = 87H;
  21. GetCurAll = 91H;
  22. GetMinAll = 92H;
  23. GetMaxAll = 93H;
  24. GetResAll = 94H;
  25. GetDefAll = 97H;
  26. (* VideoControl interface specific request codes *)
  27. VCVideoPowerModeCtl * = 01H;
  28. VCRequestErrorCodeCtl * = 02H;
  29. (* Selector Unit specific request codes *)
  30. SUInpueSelectCtl * = 01H;
  31. (* Camera Terminal specific request codes *)
  32. CTScanningModeCtl * = 01H;
  33. CTAeModeCtl * = 02H;
  34. CTAePriorityCtl * = 03H;
  35. CTExposureTimeAbsoluteCtl * = 04H;
  36. CTExposureTimeRelativeCtl * = 05H;
  37. CTFocusAbsoluteCtl * = 06H;
  38. CTFocusRelativeCtl * = 07H;
  39. CTFocusAutoCtl * = 08H;
  40. CTIrisAbsoluteCtl * = 09H;
  41. CTIrisRelativeCtl * = 0AH;
  42. CTZoomAbsoluteCtl * = 0BH;
  43. CTZoomRelativeCtl * = 0CH;
  44. CTPantiltAbsoluteCtl * = 0DH;
  45. CTPantiltRelativeCtl * = 0EH;
  46. CTRollAbsoluteCtl * = 0FH;
  47. CTRollRelativeCtl * = 10H;
  48. CTPrivacyCtl * = 11H;
  49. CTFocusSimpleCtl * = 12H;
  50. CTWindowCtl * = 13H;
  51. CTRegionOfInterestCtl * = 14H;
  52. (* Processing Unit specific request codes *)
  53. PUBacklightCompensationCtl * = 01H;
  54. PUBrightnessCtl * = 02H;
  55. PUContrastCtl * = 03H;
  56. PUGainCtl * = 04H;
  57. PUPowerLineFrequencyCtl * = 05H;
  58. PUHueCtl * = 06H;
  59. PUSaturationCtl * = 07H;
  60. PUSharpnessCtl * = 08H;
  61. PUGammaCtl * = 09H;
  62. PUWhiteBalanceTemperatureCtl * = 0AH;
  63. PUWhiteBalanceTemperatureAutoCtl * = 0BH;
  64. PUWhiteBalanceComponentCtl * = 0CH;
  65. PUWhiteBalanceComponentAutoCtl * = 0DH;
  66. PUDigitalMultiplierCtl * = 0EH;
  67. PUDigitalMultiplierLimitCtl * = 0FH;
  68. PUHueAutoCtl * = 10H;
  69. PUAnalogVideoStandardCtl * = 11H;
  70. PUAnalogLockStatusCtl * = 12H;
  71. PUContrastAutoCtl * = 13H;
  72. (* Encoding Unit specific request codes *)
  73. EnUSelectLayerCtl * = 01H;
  74. EnUProfileToolsetCtl * = 02H;
  75. EnUVideoResolutionCtl * = 03H;
  76. EnUMinFrameIntervalCtl * = 04H;
  77. EnUSliceModeCtl * = 05H;
  78. EnURateControlModeCtl * = 06H;
  79. EnUAverageBitrateCtl * = 07H;
  80. EnUCPBSizeCtl * = 08H;
  81. EnUPeakBitRateCtl * = 09H;
  82. EnUQuantizationParamsCtl * = 0AH;
  83. EnUSyncRefFrameCtl * = 0BH;
  84. EnULTRBufferCtl * = 0CH;
  85. EnULTRPictureCtl * = 0DH;
  86. EnULTRValidationCtl * = 0EH;
  87. EnULevelIDCLimitCtl * = 0FH;
  88. EnUSeiPayloadTypeCtl * = 10H;
  89. EnUQpRangeCtl * = 11H;
  90. EnUPriorityCtl * = 12H;
  91. EnUStartOrStopLayerCtl * = 13H;
  92. EnUErrorResiliencyCtl * = 14H;
  93. (* VideoStreaming Interface specific request codes *)
  94. VSProbeCtl * = 1;
  95. VSCommitCtl * = 2;
  96. VSStillProbeCtl * = 3;
  97. VSStillCommitCtl * = 4;
  98. VSStillImageTriggerCtl * = 5;
  99. VSStreamErrorCodeCtl * = 6;
  100. VSGenerateKeyFrameCtl * = 7;
  101. VSUpdateFrameSegmentCtl * = 8;
  102. VSSynchDelayCtl * = 9;
  103. (* Request Types *)
  104. SetControlRequest = {5, 0};
  105. GetControlRequest = {7, 5, 0};
  106. SetStreamingRequest = {5, 1};
  107. GetStreamingRequest = {7, 5, 1};
  108. (* Request Error Codes *)
  109. NoError * = 000H;
  110. NotReady * = 001H;
  111. WrongState * = 002H;
  112. Power * = 003H;
  113. OutOfRange * = 004H;
  114. InvalidUnit * = 005H;
  115. InvalidControl * = 006H;
  116. InvalidRequest * = 007H;
  117. InvalidValueWithinRange * = 008H;
  118. Unknown * = 0FFH;
  119. (* Probe commit mechanism *)
  120. Negotiate * = 0;
  121. TYPE
  122. ProbeCommitCtl * = RECORD
  123. bmHint *: SET;
  124. bFormatIndex *,
  125. bFrameIndex *,
  126. dwFrameInterval *,
  127. wKeyFrameRate *,
  128. wPFrameRate *,
  129. wCompQuality *,
  130. wCompWindowSize *,
  131. wDelay *,
  132. dwMaxVideoFrameSize *,
  133. dwMaxPayloadTransferSize *,
  134. dwClockFrequency *: LONGINT;
  135. bmFramingInfo *: SET;
  136. bPreferedVersion *,
  137. bMinVersion *,
  138. bMaxVersion *,
  139. bUsage *,
  140. bBitDepthLuma *: LONGINT;
  141. bmSettings *: SET;
  142. bMaxNumberOfRefFramesPlus1 *: LONGINT;
  143. bmRateControlModes *: SET;
  144. bmLayoutPerStream *: ARRAY 2 OF SET;
  145. END;
  146. Header = RECORD
  147. pt, scr: LONGINT;
  148. id, eof, psb, still, error, eoh: BOOLEAN;
  149. ptPresent, scrPresent: BOOLEAN;
  150. END;
  151. (** USB device drivers for video functions. *)
  152. VideoDriver * = OBJECT (Usbdi.Driver)
  153. VAR
  154. controlPipe, interruptPipe: Usbdi.Pipe;
  155. controlInterface: Usbdi.InterfaceDescriptor;
  156. control: UsbVideoDesc.VideoControlDesc;
  157. topology -: POINTER TO ARRAY OF UsbVideoDesc.Unit;
  158. streamingDrivers: POINTER TO ARRAY OF StreamingDriver;
  159. status -: Usbdi.Status;
  160. getError: BOOLEAN;
  161. PROCEDURE Connect * (): BOOLEAN;
  162. BEGIN
  163. RETURN TRUE
  164. END Connect;
  165. PROCEDURE Disconnect *;
  166. END Disconnect;
  167. (* Send a control request to 'unit' (interface if unit = 0) to do a 'type' operationon the control seclector 'selector'. It uses buffer and len
  168. * to do the transfer. *)
  169. PROCEDURE ControlRequest * (type, selector, unit: LONGINT; VAR buffer: ARRAY OF CHAR; len: LONGINT);
  170. VAR
  171. requestType: SET;
  172. request, value, index: LONGINT;
  173. error: ARRAY 1 OF CHAR;
  174. BEGIN
  175. IF unit = 0 THEN
  176. (* Interface request *)
  177. KernelLog.String("Sending video interface request"); KernelLog.Ln;
  178. IF (selector # VCVideoPowerModeCtl) & (selector # VCRequestErrorCodeCtl) THEN
  179. ASSERT(unit # 0)
  180. END;
  181. value := selector * 100H;
  182. (*index := controlInterface.bInterfaceNumber;*)
  183. ELSE
  184. (* Unit request *)
  185. KernelLog.String("Sending video unit request"); KernelLog.Ln;
  186. IF (type = SetCurAll) OR (type >= GetCurAll) THEN
  187. index := unit;
  188. ELSE
  189. value := selector * 100H;
  190. index := unit * 100H (*+ controlInterface.bInterfaceNumber*)
  191. END
  192. END;
  193. request := type;
  194. CASE type OF
  195. SetCur, SetCurAll:
  196. requestType := SetControlRequest
  197. |GetCur, GetMin, GetMax, GetRes, GetLen, GetInfo, GetDef,
  198. GetCurAll, GetMinAll, GetMaxAll, GetResAll, GetDefAll:
  199. requestType := GetControlRequest
  200. END;
  201. TRACE(type, selector, unit, controlInterface.bInterfaceNumber);
  202. TRACE(requestType, request, value, index, len);
  203. status := controlPipe.Request(requestType, request, value, index, len, buffer);
  204. IF (status = Usbdi.Stalled) & (~getError) THEN
  205. KernelLog.String("Transfer stalled. Trying to get more info from device"); KernelLog.Ln;
  206. getError := TRUE;
  207. ControlRequest(GetCur, VCRequestErrorCodeCtl, 0, error, 1);
  208. getError := FALSE;
  209. status := ORD(error[0])
  210. END
  211. END ControlRequest;
  212. END VideoDriver;
  213. Sample * = POINTER TO RECORD
  214. next *: Sample;
  215. data *: POINTER TO ARRAY OF CHAR;
  216. END;
  217. (** Abstract streaming driver. Handles format-specific parts of the video driver. *)
  218. StreamingDriver * = OBJECT (Usbdi.Driver)
  219. VAR
  220. controlDriver: VideoDriver;
  221. videoPipe: Usbdi.Pipe;
  222. inputHeader -: UsbVideoDesc.VSInputHeaderDesc;
  223. formats -: POINTER TO ARRAY OF UsbVideoDesc.VSFormatDesc;
  224. samples: Sample;
  225. status: LONGINT;
  226. stream: BOOLEAN;
  227. params: POINTER TO ProbeCommitCtl;
  228. PROCEDURE Pause;
  229. (*BEGIN {EXCLUSIVE}
  230. stream := FALSE*)
  231. END Pause;
  232. PROCEDURE Resume;
  233. (*BEGIN {EXCLUSIVE}
  234. stream := TRUE*)
  235. END Resume;
  236. PROCEDURE Connect * (): BOOLEAN;
  237. BEGIN
  238. NEW(params);
  239. params.bmHint := {0};
  240. params.bFormatIndex := 1;
  241. params.bFrameIndex := 2;
  242. params.dwFrameInterval := 333333;
  243. (*params.dwMaxVideoFrameSize := 640 * 480 * 2; (* bytes *)
  244. params.bMaxNumberOfRefFramesPlus1 := 1;*)
  245. (*PrintParams(params^);*)
  246. sdr.NegotiateStreaming(params^, TRUE);
  247. PrintParams(params^);
  248. (* Set Interface 1 *)
  249. (*IF ~device(Usb.UsbDevice).SetInterface(1, 5) THEN
  250. KernelLog.String("Could not set interface"); KernelLog.Ln
  251. END;
  252. (*NegotiateStreaming(params^, TRUE);
  253. PrintParams(params^);*)
  254. videoPipe := device.GetPipe(inputHeader.bEndpointAddress);
  255. videoPipe.maxPacketSize := 800;
  256. videoPipe(UsbHcdi.Pipe).mult := 1;*)
  257. IF inputHeader.wTotalLength = 284 THEN
  258. (*WHILE ~Kernel.Expired(t) DO END;*)
  259. (*GetFrame3(Commands.GetContext());*)
  260. (*Resume*)
  261. END;
  262. RETURN TRUE
  263. END Connect;
  264. PROCEDURE Disconnect *;
  265. END Disconnect;
  266. PROCEDURE Probe (type: LONGINT; set: BOOLEAN; VAR params: ARRAY 48 OF CHAR);
  267. VAR
  268. request: LONGINT;
  269. BEGIN
  270. IF set THEN
  271. request := SetCur
  272. ELSE
  273. request := GetCur
  274. END;
  275. ControlRequest(request, type, params, 34);
  276. KernelLog.String("Probe: "); KernelLog.Int(status, 0); KernelLog.String(" "); KernelLog.Int(controlDriver.status, 0); KernelLog.Ln
  277. END Probe;
  278. PROCEDURE Commit (type: LONGINT; VAR params: ARRAY 48 OF CHAR);
  279. BEGIN
  280. ControlRequest(SetCur, type, params, 34(*48*));
  281. KernelLog.String("Commit: "); KernelLog.Int(status, 0); KernelLog.String(" "); KernelLog.Int(controlDriver.status, 0); KernelLog.Ln
  282. END Commit;
  283. PROCEDURE NegotiateStreaming (VAR params: ProbeCommitCtl; commit: BOOLEAN);
  284. VAR
  285. probeBuf: ARRAY 48 OF CHAR;
  286. BEGIN
  287. WriteProbeCommitCtl(probeBuf, 0, params);
  288. Probe(VSProbeCtl, TRUE, probeBuf);
  289. Probe(VSProbeCtl, FALSE, probeBuf);
  290. (* Override max video frame size *)
  291. (*ReadProbeCommitCtl(probeBuf, 0, params);
  292. (*IF formats[params.bFormatIndex] IS UsbVideoDesc.VSFormatUncompressedDesc THEN
  293. (*params.dwMaxVideoFrameRate := formats[params.bFormatIndex].frames[params.bFrameIndex](*UsbVideoDesc.VSFrameUncompressed*).wWidth;
  294. * formats[params.bFormatIndex].frames[params.bFrameIndex](UsbVideoDesc.VSFrameUncompressed).wHeight
  295. * formats[params.bFormatIndex](UsbVideoDesc.VSFormatUncompressedDesc).bBitsPerPixel*)
  296. ELSE*)
  297. params.dwMaxVideoFrameSize := 120 * 160 * 2;
  298. (*END;*)
  299. WriteProbeCommitCtl(probeBuf, 0, params);*)
  300. IF commit THEN
  301. Commit(VSCommitCtl,probeBuf)
  302. END;
  303. ReadProbeCommitCtl(probeBuf, 0, params);
  304. END NegotiateStreaming;
  305. PROCEDURE NegotiateStill (VAR params: ProbeCommitCtl);
  306. VAR
  307. probeBuf: ARRAY 48 OF CHAR;
  308. BEGIN
  309. WriteProbeCommitCtl(probeBuf, 0, params);
  310. Probe(VSStillProbeCtl, TRUE, probeBuf);
  311. (*ReadProbeCommitCtl(probeBuf, 0, params);
  312. params.dwMaxVideoFrameSize := 120 * 160 * 2;
  313. WriteProbeCommitCtl(probeBuf, 0, params);*)
  314. Commit(VSStillCommitCtl,probeBuf);
  315. ReadProbeCommitCtl(probeBuf, 0, params);
  316. END NegotiateStill;
  317. (** Send a control request to the streaming interface. *)
  318. PROCEDURE ControlRequest * (type, selector: LONGINT; VAR buffer: ARRAY OF CHAR; len: LONGINT);
  319. VAR
  320. requestType: SET;
  321. request, value, index: LONGINT;
  322. error: ARRAY 1 OF CHAR;
  323. BEGIN
  324. (* Interface request *)
  325. KernelLog.String("Sending video interface request"); KernelLog.Ln;
  326. value := selector * 100H;
  327. index := 1;
  328. request := type;
  329. CASE type OF
  330. SetCur, SetCurAll:
  331. requestType := SetControlRequest
  332. |GetCur, GetMin, GetMax, GetRes, GetLen, GetInfo, GetDef,
  333. GetCurAll, GetMinAll, GetMaxAll, GetResAll, GetDefAll:
  334. requestType := GetControlRequest
  335. END;
  336. status := controlDriver.controlPipe.Request(requestType, request, value, index, len, buffer);
  337. IF status = Usbdi.Stalled THEN
  338. KernelLog.String("VS Control Transfer stalled. Trying to get more info from device"); KernelLog.Ln;
  339. ControlRequest(GetCur, VCRequestErrorCodeCtl, error, 1);
  340. status := ORD(error[0])
  341. END;
  342. END ControlRequest;
  343. (** Provides a stream for reading video or still images in the selected format *)
  344. PROCEDURE Receive * (VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
  345. VAR
  346. i: LONGINT;
  347. BEGIN {EXCLUSIVE}
  348. len := 0;
  349. WHILE (samples # NIL) & (len < size) DO
  350. FOR i := 0 TO LEN(samples.data) - 1 DO
  351. buf[ofs + i] := samples.data[i]
  352. END;
  353. INC(ofs, LEN(samples.data));
  354. INC(len, LEN(samples.data));
  355. samples := samples.next
  356. END;
  357. IF len < min THEN
  358. res := Streams.EOF
  359. END
  360. END Receive;
  361. PROCEDURE EnqueueSample;
  362. BEGIN
  363. HALT(210)
  364. END EnqueueSample;
  365. (*BEGIN {ACTIVE}
  366. LOOP
  367. BEGIN {EXCLUSIVE}
  368. AWAIT(stream)
  369. END;
  370. SkipFrame
  371. END;*)
  372. END StreamingDriver;
  373. VAR
  374. dr: VideoDriver;
  375. sdr: StreamingDriver;
  376. frame: POINTER TO ARRAY OF CHAR;
  377. buf: ARRAY Size + 13 * 12 OF CHAR;
  378. headers: ARRAY 20 OF RECORD
  379. pos, size: LONGINT
  380. END;
  381. t: Kernel.MilliTimer;
  382. PROCEDURE ReadProbeCommitCtl (CONST buffer: ARRAY OF CHAR; pos: LONGINT; VAR ctl: ProbeCommitCtl);
  383. BEGIN
  384. ASSERT(LEN(buffer) - pos >= 48);
  385. ctl.bmHint := SYSTEM.VAL(SET, ORD(buffer[pos])); INC(pos);
  386. ctl.bFormatIndex := ORD(buffer[pos]); INC(pos);
  387. ctl.bFrameIndex := ORD(buffer[pos]); INC(pos);
  388. ctl.dwFrameInterval := ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H + ORD(buffer[pos + 2]) * 10000H + ORD(buffer[pos + 3]) * 1000000H; INC(pos, 4);
  389. ctl.wKeyFrameRate := ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H; INC(pos, 2);
  390. ctl.wPFrameRate := ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H; INC(pos, 2);
  391. ctl.wCompQuality := ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H; INC(pos, 2);
  392. ctl.wCompWindowSize := ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H; INC(pos, 2);
  393. ctl.wDelay := ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H; INC(pos, 2);
  394. ctl.dwMaxVideoFrameSize := ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H + ORD(buffer[pos + 2]) * 10000H + ORD(buffer[pos + 3]) * 1000000H; INC(pos, 4);
  395. ctl.dwMaxPayloadTransferSize := ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H + ORD(buffer[pos + 2]) * 10000H + ORD(buffer[pos + 3]) * 1000000H; INC(pos, 4);
  396. ctl.bmFramingInfo := SYSTEM.VAL(SET, ORD(buffer[pos])); INC(pos);
  397. ctl.bPreferedVersion := ORD(buffer[pos]); INC(pos);
  398. ctl.bMinVersion := ORD(buffer[pos]); INC(pos);
  399. ctl.bMaxVersion := ORD(buffer[pos]); INC(pos);
  400. ctl.bUsage := ORD(buffer[pos]); INC(pos);
  401. ctl.bBitDepthLuma := ORD(buffer[pos]); INC(pos);
  402. ctl.bmSettings := SYSTEM.VAL(SET, ORD(buffer[pos])); INC(pos);
  403. ctl.bMaxNumberOfRefFramesPlus1 := ORD(buffer[pos]); INC(pos);
  404. ctl.bmRateControlModes := SYSTEM.VAL(SET, ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H); INC(pos, 2);
  405. ctl.bmLayoutPerStream[0] := SYSTEM.VAL(SET, ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H + ORD(buffer[pos + 2]) * 10000H + ORD(buffer[pos + 3]) * 1000000H); INC(pos, 4);
  406. ctl.bmLayoutPerStream[1] := SYSTEM.VAL(SET, ORD(buffer[pos]) + ORD(buffer[pos + 1]) * 100H + ORD(buffer[pos + 2]) * 10000H + ORD(buffer[pos + 3]) * 1000000H); INC(pos, 4);
  407. END ReadProbeCommitCtl;
  408. PROCEDURE WriteProbeCommitCtl (VAR buffer: ARRAY OF CHAR; pos: LONGINT; CONST ctl: ProbeCommitCtl);
  409. BEGIN
  410. ASSERT(LEN(buffer) - pos >= 48);
  411. buffer[pos] := CHR(SYSTEM.VAL(LONGINT, ctl.bmHint) MOD 100H); INC(pos);
  412. buffer[pos] := CHR(ctl.bFormatIndex MOD 100H); INC(pos);
  413. buffer[pos] := CHR(ctl.bFrameIndex MOD 100H); INC(pos);
  414. buffer[pos] := CHR(ctl.dwFrameInterval MOD 100H);
  415. buffer[pos + 1] := CHR((ctl.dwFrameInterval DIV 100H) MOD 100H);
  416. buffer[pos + 2] := CHR((ctl.dwFrameInterval DIV 10000H) MOD 100H);
  417. buffer[pos + 3] := CHR((ctl.dwFrameInterval DIV 1000000H) MOD 100H); INC(pos, 4);
  418. buffer[pos] := CHR(ctl.wKeyFrameRate MOD 100H);
  419. buffer[pos + 1] := CHR((ctl.wKeyFrameRate DIV 100H) MOD 100H); INC(pos, 2);
  420. buffer[pos] := CHR(ctl.wPFrameRate MOD 100H);
  421. buffer[pos + 1] := CHR((ctl.wPFrameRate DIV 100H) MOD 100H); INC(pos, 2);
  422. buffer[pos] := CHR(ctl.wCompQuality MOD 100H);
  423. buffer[pos + 1] := CHR((ctl.wCompQuality DIV 100H) MOD 100H); INC(pos, 2);
  424. buffer[pos] := CHR(ctl.wCompWindowSize MOD 100H);
  425. buffer[pos + 1] := CHR((ctl.wCompWindowSize DIV 100H) MOD 100H); INC(pos, 2);
  426. buffer[pos] := CHR(ctl.wDelay MOD 100H);
  427. buffer[pos + 1] := CHR((ctl.wDelay DIV 100H) MOD 100H); INC(pos, 2);
  428. buffer[pos] := CHR(ctl.dwMaxVideoFrameSize MOD 100H);
  429. buffer[pos + 1] := CHR((ctl.dwMaxVideoFrameSize DIV 100H) MOD 100H);
  430. buffer[pos + 2] := CHR((ctl.dwMaxVideoFrameSize DIV 10000H) MOD 100H);
  431. buffer[pos + 3] := CHR((ctl.dwMaxVideoFrameSize DIV 1000000H) MOD 100H); INC(pos, 4);
  432. buffer[pos] := CHR(ctl.dwMaxPayloadTransferSize MOD 100H);
  433. buffer[pos + 1] := CHR((ctl.dwMaxPayloadTransferSize DIV 100H) MOD 100H);
  434. buffer[pos + 2] := CHR((ctl.dwMaxPayloadTransferSize DIV 10000H) MOD 100H);
  435. buffer[pos + 3] := CHR((ctl.dwMaxPayloadTransferSize DIV 1000000H) MOD 100H); INC(pos, 4);
  436. buffer[pos] := CHR(SYSTEM.VAL(LONGINT, ctl.bmFramingInfo) MOD 100H); INC(pos);
  437. buffer[pos] := CHR(ctl.bPreferedVersion MOD 100H); INC(pos);
  438. buffer[pos] := CHR(ctl.bMinVersion MOD 100H); INC(pos);
  439. buffer[pos] := CHR(ctl.bMaxVersion MOD 100H); INC(pos);
  440. buffer[pos] := CHR(ctl.bUsage MOD 100H); INC(pos);
  441. buffer[pos] := CHR(ctl.bBitDepthLuma MOD 100H); INC(pos);
  442. buffer[pos] := CHR(SYSTEM.VAL(LONGINT, ctl.bmSettings) MOD 100H); INC(pos);
  443. buffer[pos] := CHR(ctl.bMaxNumberOfRefFramesPlus1 MOD 100H); INC(pos);
  444. buffer[pos] := CHR(SYSTEM.VAL(LONGINT, ctl.bmRateControlModes) MOD 100H);
  445. buffer[pos + 1] := CHR((SYSTEM.VAL(LONGINT, ctl.bmRateControlModes) DIV 100H) MOD 100H); INC(pos, 2);
  446. buffer[pos] := CHR(SYSTEM.VAL(LONGINT, ctl.bmLayoutPerStream[0]) MOD 100H);
  447. buffer[pos + 1] := CHR((SYSTEM.VAL(LONGINT, ctl.bmLayoutPerStream[0]) DIV 100H) MOD 100H);
  448. buffer[pos + 2] := CHR((SYSTEM.VAL(LONGINT, ctl.bmLayoutPerStream[0]) DIV 10000H) MOD 100H);
  449. buffer[pos + 3] := CHR((SYSTEM.VAL(LONGINT, ctl.bmLayoutPerStream[0]) DIV 1000000H) MOD 100H); INC(pos, 4);
  450. buffer[pos] := CHR(SYSTEM.VAL(LONGINT, ctl.bmLayoutPerStream[1]) MOD 100H);
  451. buffer[pos + 1] := CHR((SYSTEM.VAL(LONGINT, ctl.bmLayoutPerStream[1]) DIV 100H) MOD 100H);
  452. buffer[pos + 2] := CHR((SYSTEM.VAL(LONGINT, ctl.bmLayoutPerStream[1]) DIV 10000H) MOD 100H);
  453. buffer[pos + 3] := CHR((SYSTEM.VAL(LONGINT, ctl.bmLayoutPerStream[1]) DIV 1000000H) MOD 100H); INC(pos, 4);
  454. END WriteProbeCommitCtl;
  455. PROCEDURE PrintParams (CONST p: ProbeCommitCtl);
  456. BEGIN
  457. KernelLog.String("= Probe/Commit Negotiation Parameters ="); KernelLog.Ln;
  458. KernelLog.String(" hints: "); KernelLog.Set(p.bmHint); KernelLog.Ln;
  459. KernelLog.String(" format idx: "); KernelLog.Int(p.bFormatIndex, 0); KernelLog.Ln;
  460. KernelLog.String(" frame idx: "); KernelLog.Int(p.bFrameIndex, 0); KernelLog.Ln;
  461. KernelLog.String(" frame interval: "); KernelLog.Int(p.dwFrameInterval, 0); KernelLog.Ln;
  462. KernelLog.String(" K frame rate: "); KernelLog.Int(p.wKeyFrameRate, 0); KernelLog.Ln;
  463. KernelLog.String(" P frame rate: "); KernelLog.Int(p.wPFrameRate, 0); KernelLog.Ln;
  464. KernelLog.String(" comp quality: "); KernelLog.Int(p.wCompQuality, 0); KernelLog.Ln;
  465. KernelLog.String(" comp window size: "); KernelLog.Int(p.wCompWindowSize, 0); KernelLog.Ln;
  466. KernelLog.String(" delay: "); KernelLog.Int(p.wDelay, 0); KernelLog.Ln;
  467. KernelLog.String(" max video fr size: "); KernelLog.Int(p.dwMaxVideoFrameSize, 0); KernelLog.Ln;
  468. KernelLog.String(" max pld tx size: "); KernelLog.Int(p.dwMaxPayloadTransferSize, 0); KernelLog.Ln;
  469. KernelLog.String(" clok frq: "); KernelLog.Int(p.dwClockFrequency, 0); KernelLog.Ln;
  470. KernelLog.String(" framing info: "); KernelLog.Set(p.bmFramingInfo); KernelLog.Ln;
  471. KernelLog.String(" pref'd version: "); KernelLog.Int(p.bPreferedVersion, 0); KernelLog.Ln;
  472. KernelLog.String(" min version: "); KernelLog.Int(p.bMinVersion, 0); KernelLog.Ln;
  473. KernelLog.String(" max version: "); KernelLog.Int(p.bMaxVersion, 0); KernelLog.Ln;
  474. KernelLog.String(" usage: "); KernelLog.Int(p.bUsage, 0); KernelLog.Ln;
  475. KernelLog.String(" bit depth luma: "); KernelLog.Int(p.bBitDepthLuma, 0); KernelLog.Ln;
  476. KernelLog.String(" settings: "); KernelLog.Set(p.bmSettings); KernelLog.Ln;
  477. KernelLog.String(" max # ref fr + 1: "); KernelLog.Int(p.bMaxNumberOfRefFramesPlus1, 0); KernelLog.Ln;
  478. KernelLog.String(" rate ctl modes: "); KernelLog.Set(p.bmRateControlModes); KernelLog.Ln;
  479. KernelLog.String(" layout/stream (h): "); KernelLog.Set(p.bmLayoutPerStream[0]); KernelLog.Ln;
  480. KernelLog.String(" layout/stream (l): "); KernelLog.Set(p.bmLayoutPerStream[1]); KernelLog.Ln;
  481. END PrintParams;
  482. PROCEDURE GetHeader (CONST hdr: ARRAY OF CHAR; pos: LONGINT; VAR h: Header);
  483. VAR
  484. set: SET;
  485. BEGIN
  486. set := SYSTEM.VAL(SET, ORD(hdr[pos + 1]));
  487. h.id := 0 IN set;
  488. h.eof := 1 IN set;
  489. h.ptPresent := 2 IN set;
  490. h.scrPresent := 3 IN set;
  491. h.psb := 4 IN set;
  492. h.still := 5 IN set;
  493. h.error := 6 IN set;
  494. h.eoh := 7 IN set;
  495. INC(pos);
  496. IF h.ptPresent THEN
  497. h.pt := SYSTEM.GET32(ADDRESSOF(hdr[pos]));
  498. INC(pos, 4)
  499. END;
  500. IF h.scrPresent THEN
  501. h.scr := SYSTEM.GET32(ADDRESSOF(hdr[pos]));
  502. INC(pos, 4)
  503. END
  504. END GetHeader;
  505. PROCEDURE PrintHeader (CONST hdr: ARRAY OF CHAR; pos: LONGINT; w: Streams.Writer);
  506. VAR
  507. set: SET;
  508. BEGIN
  509. IF hdr[pos] # 0CX THEN
  510. w.String("Header length incorrect ");
  511. w.Int(ORD(hdr[pos]), 0);
  512. w.String(" instead of 12.");
  513. RETURN
  514. END;
  515. set := SYSTEM.VAL(SET, ORD(hdr[pos + 1]));
  516. IF 0 IN set THEN
  517. w.String("id 1 ")
  518. ELSE
  519. w.String("id 0 ")
  520. END;
  521. IF 1 IN set THEN
  522. w.String("[EOF]")
  523. END;
  524. IF 2 IN set THEN
  525. w.String("[PT]")
  526. END;
  527. IF 3 IN set THEN
  528. w.String("[SCR]")
  529. END;
  530. IF 5 IN set THEN
  531. w.String("[Still]")
  532. END;
  533. IF 6 IN set THEN
  534. w.String("[ERROR]")
  535. END;
  536. IF 7 IN set THEN
  537. w.String("[EOH]")
  538. END;
  539. w.String(' ');
  540. w.Int(SYSTEM.GET32(ADDRESSOF(hdr[pos + 2])), 0)
  541. END PrintHeader;
  542. PROCEDURE Probe(dev : Usbdi.UsbDevice; id : Usbdi.InterfaceDescriptor) : Usbdi.Driver;
  543. VAR
  544. i, j, count: LONGINT;
  545. curr: Usbdi.UnknownDescriptor;
  546. vc: UsbVideoDesc.VideoControlDesc;
  547. ep: UsbVideoDesc.InterruptEndpointDesc;
  548. ih: UsbVideoDesc.VSInputHeaderDesc;
  549. vs: UsbVideoDesc.VSFormatDesc;
  550. vfr: UsbVideoDesc.VSFrameDesc;
  551. sid: UsbVideoDesc.StillImageDesc;
  552. cmd: UsbVideoDesc.ColorMatchingDesc;
  553. u: UsbVideoDesc.Unit;
  554. buf: ARRAY 32 OF CHAR;
  555. frame: POINTER TO ARRAY OF CHAR;
  556. params: POINTER TO ProbeCommitCtl;
  557. BEGIN
  558. (* Check if video class *)
  559. IF id.bInterfaceClass # 0EH THEN RETURN NIL END;
  560. CASE id.bInterfaceSubClass OF
  561. 1: (* Video control *)
  562. KernelLog.String("Found Video Control interface #"); KernelLog.Int(id.bInterfaceNumber, 0); KernelLog.String(" alt: "); KernelLog.Int(id.bAlternateSetting, 0); KernelLog.Ln;
  563. NEW(dr);
  564. (* Parse video control interface descriptor *)
  565. IF (id.unknown # NIL) THEN
  566. dr.control := UsbVideoDesc.ParseVideoControlDesc(id.unknown.descriptor^, 0);
  567. UsbVideoDesc.PrintVC(dr.control)
  568. END;
  569. (* Parse & resolve unit descriptors *)
  570. (*! DIRTY TEMP HACK *)
  571. dr.controlPipe := dev.GetPipe(0);
  572. RETURN dr;
  573. (*! END OF DIRTY TEMP HACK *)
  574. UsbVideoDesc.ClearUnitCache;
  575. curr := id.unknown.next;
  576. count := 0;
  577. WHILE curr # NIL DO
  578. u := UsbVideoDesc.ParseUnit(curr.descriptor^, 0);
  579. IF u = NIL THEN
  580. KernelLog.String("ERROR: Unknown Unit"); KernelLog.Ln;
  581. dr := NIL;
  582. RETURN NIL
  583. END;
  584. UsbVideoDesc.unitCache[u.bUnitID - 1] := u;
  585. curr := curr.next;
  586. INC(count)
  587. END;
  588. FOR i := 0 TO 255 DO
  589. IF UsbVideoDesc.unitCache[i] # NIL THEN
  590. UsbVideoDesc.unitCache[i].Resolve(UsbVideoDesc.unitCache)
  591. END
  592. END;
  593. NEW(dr.topology, count);
  594. j := 0;
  595. FOR i := 0 TO 255 DO
  596. IF UsbVideoDesc.unitCache[i] # NIL THEN
  597. dr.topology[j] := UsbVideoDesc.unitCache[i];
  598. (*PrintUnit(dr.topology[j]);*)
  599. INC(j)
  600. END
  601. END;
  602. (* Create contol pipes *)
  603. dr.controlPipe := dev.GetPipe(0);
  604. KernelLog.String(":: NUM ENDPOINTS "); KernelLog.Int(id.bNumEndpoints, 0); KernelLog.Ln;
  605. FOR i := 0 TO id.bNumEndpoints - 1 DO
  606. KernelLog.String("= Endpoint "); KernelLog.Int(i, 0); KernelLog.Ln;
  607. KernelLog.String(" adr: "); KernelLog.Int(id.endpoints[i].bEndpointAddress, 0); KernelLog.Ln;
  608. KernelLog.String(" type: "); KernelLog.Int(id.endpoints[i].type, 0); KernelLog.Ln;
  609. KernelLog.String(" max pkt size: "); KernelLog.Int(id.endpoints[i].wMaxPacketSize, 0); KernelLog.Ln;
  610. KernelLog.String(" mult: "); KernelLog.Int(id.endpoints[i](Usb.EndpointDescriptor).mult, 0); KernelLog.Ln;
  611. KernelLog.String(" unknowns: "); KernelLog.Boolean(id.endpoints[i].unknown = NIL); KernelLog.Ln;
  612. END;
  613. (*dr.ControlRequest(GetCur, VCRequestErrorCodeCtl, 0, buf, 1);*)
  614. (*dr.ControlRequest(GetCur, PUWhiteBalanceTemperatureAutoCtl, 3, buf, 1);
  615. KernelLog.String("Result: "); KernelLog.Int(ORD(buf[0]), 0); KernelLog.Ln;
  616. KernelLog.String("Status: "); KernelLog.Int(dr.status, 0); KernelLog.Ln;
  617. buf[0] := 0X;
  618. dr.ControlRequest(GetCur, PUWhiteBalanceTemperatureAutoCtl, 3, buf, 1);*)
  619. (*dr.ControlRequest(GetCur, PUBrightnessCtl, 3, buf, 2);
  620. KernelLog.String("Current: "); KernelLog.Int(ORD(buf[0]) + ORD(buf[1]) * 100H, 0); KernelLog.Ln;
  621. KernelLog.String("Status: "); KernelLog.Int(dr.status, 0); KernelLog.Ln;
  622. dr.ControlRequest(GetMin, PUBrightnessCtl, 3, buf, 2);
  623. KernelLog.String("Min: "); KernelLog.Int(ORD(buf[0]) + ORD(buf[1]) * 100H, 0); KernelLog.Ln;
  624. KernelLog.String("Status: "); KernelLog.Int(dr.status, 0); KernelLog.Ln;
  625. dr.ControlRequest(GetMax, PUBrightnessCtl, 3, buf, 2);
  626. KernelLog.String("Max: "); KernelLog.Int(ORD(buf[0]) + ORD(buf[1]) * 100H, 0); KernelLog.Ln;
  627. KernelLog.String("Status: "); KernelLog.Int(dr.status, 0); KernelLog.Ln;
  628. dr.ControlRequest(GetRes, PUBrightnessCtl, 3, buf, 2);
  629. KernelLog.String("Res: "); KernelLog.Int(ORD(buf[0]) + ORD(buf[1]) * 100H, 0); KernelLog.Ln;
  630. KernelLog.String("Status: "); KernelLog.Int(dr.status, 0); KernelLog.Ln;*)
  631. |2: (* Video streaming *)
  632. KernelLog.String("Found Video Streaming interface #"); KernelLog.Int(id.bInterfaceNumber, 0); KernelLog.String(" alt: "); KernelLog.Int(id.bAlternateSetting, 0); KernelLog.String(" #"); KernelLog.Int(id.numAlternateInterfaces, 0); KernelLog.Ln;
  633. FOR i := 0 TO id.numAlternateInterfaces - 1 DO
  634. KernelLog.String("= Alt Iface #"); KernelLog.Int(i, 0); KernelLog.String(" ="); KernelLog.Ln;
  635. KernelLog.String(" id: "); KernelLog.Int(id.alternateInterfaces[i].bInterfaceNumber, 0); KernelLog.Ln;
  636. KernelLog.String(" alt: "); KernelLog.Int(id.alternateInterfaces[i].bAlternateSetting, 0); KernelLog.Ln;
  637. KernelLog.String(" eps: "); KernelLog.Int(id.alternateInterfaces[i].bNumEndpoints, 0); KernelLog.Ln;
  638. FOR j := 0 TO id.alternateInterfaces[i].bNumEndpoints - 1 DO
  639. KernelLog.String(" = Endpoint "); KernelLog.Int(j, 0); KernelLog.Ln;
  640. KernelLog.String(" adr: "); KernelLog.Int(id.alternateInterfaces[i].endpoints[j].bEndpointAddress, 0); KernelLog.Ln;
  641. KernelLog.String(" attr: "); KernelLog.Hex(SYSTEM.VAL(LONGINT, id.alternateInterfaces[i].endpoints[j].bmAttributes), -2); KernelLog.Ln;
  642. KernelLog.String(" type: "); KernelLog.Int(id.alternateInterfaces[i].endpoints[j].type, 0); KernelLog.Ln;
  643. KernelLog.String(" max pkt size: "); KernelLog.Int(id.alternateInterfaces[i].endpoints[j].wMaxPacketSize, 0); KernelLog.Ln;
  644. KernelLog.String(" length: "); KernelLog.Int(id.alternateInterfaces[i].endpoints[j](Usb.EndpointDescriptor).bLength, 0); KernelLog.Ln;
  645. KernelLog.String(" bInterval: "); KernelLog.Int(id.alternateInterfaces[i].endpoints[j](Usb.EndpointDescriptor).bInterval, 0); KernelLog.Ln;
  646. KernelLog.String(" mult: "); KernelLog.Int(id.alternateInterfaces[i].endpoints[j](Usb.EndpointDescriptor).mult, 0); KernelLog.Ln;
  647. KernelLog.String(" unknowns: "); KernelLog.Boolean(id.alternateInterfaces[i].endpoints[j].unknown = NIL); KernelLog.Ln;
  648. END
  649. END;
  650. NEW(sdr);
  651. sdr.controlDriver := dr;
  652. IF id.unknown # NIL THEN
  653. ih := UsbVideoDesc.ParseVSInputHeader(id.unknown.descriptor^, 0);
  654. UsbVideoDesc.PrintVSInputHeader(ih);
  655. sdr.inputHeader := ih
  656. END;
  657. curr := id.unknown.next;
  658. (* Parse all format descriptor groups *)
  659. FOR i := 0 TO ih.bNumFormats - 1 DO
  660. vs := UsbVideoDesc.ParseVSFormat(curr.descriptor^, 0);
  661. vs.Print;
  662. curr := curr.next;
  663. FOR j := 0 TO vs.bNumFrameDescriptors - 1 DO
  664. vfr := UsbVideoDesc.ParseVSFrame(curr.descriptor^, 0);
  665. vfr.Print;
  666. curr := curr.next
  667. END;
  668. IF ORD(curr.descriptor[2]) = UsbVideoDesc.VSStillImageFrame THEN
  669. sid := UsbVideoDesc.ParseStillImageDesc(curr.descriptor^, 0);
  670. UsbVideoDesc.PrintStillImageDesc(sid);
  671. curr := curr.next
  672. END;
  673. IF ORD(curr.descriptor[2]) = UsbVideoDesc.VSColorFormat THEN
  674. cmd := UsbVideoDesc.ParseColorMatchingDesc(curr.descriptor^, 0);
  675. UsbVideoDesc.PrintColorMatchingDesc(cmd);
  676. curr := curr.next
  677. END;
  678. END;
  679. IF curr # NIL THEN KernelLog.String("WARNING: There are some VS decriptors left"); KernelLog.Ln END;
  680. KernelLog.String(":: NUM ENDPOINTS "); KernelLog.Int(id.bNumEndpoints, 0); KernelLog.Ln;
  681. FOR i := 0 TO id.bNumEndpoints - 1 DO
  682. KernelLog.String("= Endpoint "); KernelLog.Int(i, 0); KernelLog.Ln;
  683. KernelLog.String(" adr: "); KernelLog.Int(id.endpoints[i].bEndpointAddress, 0); KernelLog.Ln;
  684. KernelLog.String(" type: "); KernelLog.Int(id.endpoints[i].type, 0); KernelLog.Ln;
  685. KernelLog.String(" max pkt size: "); KernelLog.Int(id.endpoints[i].wMaxPacketSize, 0); KernelLog.Ln;
  686. KernelLog.String(" mult: "); KernelLog.Int(id.endpoints[i](Usb.EndpointDescriptor).mult, 0); KernelLog.Ln;
  687. KernelLog.String(" unknowns: "); KernelLog.Boolean(id.endpoints[i].unknown = NIL); KernelLog.Ln;
  688. END;
  689. IF dr = NIL THEN
  690. KernelLog.String("ERROR: No suitable Control Interface driver"); KernelLog.Ln;
  691. RETURN NIL
  692. END;
  693. RETURN sdr
  694. ELSE
  695. KernelLog.String("Found Unknown video interface"); KernelLog.Ln;
  696. RETURN NIL
  697. END;
  698. FOR i := 0 TO LEN(id.endpoints) - 1 DO
  699. (*KernelLog.String("endpoint "); KernelLog.Int(i, 0); KernelLog.Ln;
  700. KernelLog.String(" type: "); KernelLog.Int(id.endpoints[i].type, 0); KernelLog.Ln;
  701. KernelLog.String(" adr: "); KernelLog.Int(id.endpoints[i].bEndpointAddress, 0); KernelLog.Ln;*)
  702. curr := id.endpoints[i].unknown;
  703. WHILE curr # NIL DO
  704. ep := UsbVideoDesc.ParseEndpointDesc(curr.descriptor^, 0);
  705. (*PrintEndpoint(ep);*)
  706. (*dr.interruptPipe := dev.GetPipe(ep.bEndpointAddress);*)
  707. curr := curr.next
  708. END
  709. END;
  710. CASE id.bInterfaceProtocol OF
  711. 1: KernelLog.String("Video interface uses protocol 15"); KernelLog.Ln
  712. ELSE
  713. KernelLog.String("Undefined video interface protocol"); KernelLog.Ln
  714. END;
  715. (*KernelLog.String(" Device "); KernelLog.Address(SYSTEM.VAL(ADDRESS, dev)); KernelLog.Ln;
  716. KernelLog.String(" # of configs: "); KernelLog.Int(LEN(dev.configurations), 0); KernelLog.Ln;
  717. KernelLog.String(" configurations: ");
  718. FOR i := 0 TO LEN(dev.configurations) - 1 DO KernelLog.Int(dev.configurations[i].bNumInterfaces, 0); KernelLog.String(" ") END;
  719. KernelLog.Ln;
  720. FOR i := 0 TO dev.configurations[0].bNumInterfaces - 1 DO
  721. KernelLog.String(" Interface descriptor "); KernelLog.Int(dev.configurations[0].interfaces[i].bInterfaceNumber, 0); KernelLog.Ln;
  722. KernelLog.String(" # of endpoints: "); KernelLog.Int(dev.configurations[0].interfaces[i].bNumEndpoints, 0); KernelLog.Ln;
  723. FOR j := 0 TO dev.configurations[0].interfaces[i].bNumEndpoints - 1 DO
  724. KernelLog.String(" endpoint "); KernelLog.Int(j, 0); KernelLog.Ln;
  725. KernelLog.String(" type: "); KernelLog.Int(dev.configurations[0].interfaces[i].endpoints[j].type, 0); KernelLog.Ln;
  726. curr := dev.configurations[0].interfaces[i].endpoints[j].unknown;
  727. WHILE curr # NIL DO
  728. PrintUnknownDesc(4, curr);
  729. curr := curr.next
  730. END
  731. END
  732. END;
  733. KernelLog.String(" Interface descriptor "); KernelLog.Address(SYSTEM.VAL(ADDRESS, id)); KernelLog.Ln;
  734. KernelLog.String(" interface id: "); KernelLog.Int(id.bInterfaceNumber, 0); KernelLog.Ln;
  735. KernelLog.String(" # of endpoints: "); KernelLog.Int(id.bNumEndpoints, 0); KernelLog.Ln;
  736. KernelLog.String(" Endpoints types: ");
  737. FOR j := 0 TO id.bNumEndpoints - 1 DO KernelLog.Int(id.endpoints[j].type, 0); KernelLog.String(" ") END;
  738. KernelLog.Ln;
  739. curr := id.unknown;
  740. WHILE curr # NIL DO
  741. PrintUnknownDesc(2, curr);
  742. curr := curr.next
  743. END;
  744. KernelLog.String(" Configuration's unknown descriptor: "); KernelLog.Ln;
  745. curr := dev.configurations[0].unknown;
  746. WHILE curr # NIL DO
  747. PrintUnknownDesc(2, curr);
  748. curr := curr.next
  749. END;
  750. KernelLog.String(" Configuration's IAD: "); KernelLog.Int(LEN(dev.configurations[0].iads), 0); KernelLog.Ln;
  751. FOR i := 0 TO LEN(dev.configurations[0].iads) - 1 DO
  752. KernelLog.String(" Iad # "); KernelLog.Int(i, 0); KernelLog.Ln;
  753. KernelLog.String(" first iface: "); KernelLog.Int(dev.configurations[0].iads[i].bFirstInterface, 0); KernelLog.Ln;
  754. KernelLog.String(" # interface: "); KernelLog.Int(dev.configurations[0].iads[i].bInterfaceCount, 0); KernelLog.Ln;
  755. END;*)
  756. RETURN NIL
  757. END Probe;
  758. PROCEDURE Cleanup *;
  759. BEGIN
  760. (* Unregister the driver at the USB driver registry *)
  761. KernelLog.String("Cleaning UsbVideo module"); KernelLog.Ln;
  762. Usbdi.drivers.Remove(Name);
  763. END Cleanup;
  764. (* Test command for video streaming transfer *)
  765. PROCEDURE Transfer *;
  766. VAR
  767. desc: ARRAY 9 OF CHAR;
  768. i, j, count, max: LONGINT;
  769. size: LONGINT;
  770. t: Kernel.Timer;
  771. f: Files.File;
  772. w: Files.Writer;
  773. BEGIN
  774. KernelLog.String(":: Streaming one frame"); KernelLog.Ln;
  775. size := 120 * 160 * 2(*params.dwMaxPayloadTransferSize*);
  776. max := 10;
  777. NEW(frame, size * max);
  778. count := 0;
  779. NEW(t);
  780. REPEAT
  781. KernelLog.String("========== TRANSMITTING PAYLOAD #"); KernelLog.Int(count, 0); KernelLog.String(" =========="); KernelLog.Ln;
  782. i := sdr.videoPipe.Transfer(size, size * count, frame^);
  783. KernelLog.String(":: Transfer finished: "); KernelLog.Int(i, 0); KernelLog.Ln;
  784. t.Sleep(30);
  785. INC(count);
  786. UNTIL (count >= max) OR (i > Usbdi.ShortPacket);
  787. (*KernelLog.String(":: Analysing Received Data"); KernelLog.Ln;
  788. f := Files.New("UsbFrameImage.dat");
  789. Files.OpenWriter(w, f, 0);
  790. j := 0;
  791. i := -1;
  792. WHILE j < size * max DO
  793. IF ORD(frame[j]) = 12 THEN
  794. IF i # -1 THEN KernelLog.String(" Length: "); KernelLog.Int(i, 0); KernelLog.Ln END;
  795. KernelLog.String("Found header at "); KernelLog.Int(j, 0); KernelLog.String(" "); KernelLog.Buffer(frame^, j, 12);
  796. PrintHeader(frame^, j);
  797. INC(j, 11); i := -1
  798. ELSIF frame[j] = 0X THEN
  799. (*i := -1;*)
  800. DEC(i)
  801. ELSE
  802. w.Char(frame[j])
  803. END;
  804. INC(j);
  805. INC(i)
  806. END;
  807. (*FOR i := 0 TO max * size - 1 BY 3000 DO
  808. IF frame[i] = 0CX THEN
  809. KernelLog.String(" -> Header at "); KernelLog.Int(i, 0); KernelLog.Ln;
  810. PrintHeader(frame^, i);
  811. w.Bytes(frame^, i + 12, 3000 - 12);
  812. END
  813. END;*)
  814. w.Update;
  815. Files.Register(f);
  816. f.Close;
  817. (*IF i # -1 THEN KernelLog.String(" Length: "); KernelLog.Int(i, 0); KernelLog.Ln END;*)
  818. KernelLog.Buffer(frame^, 0, size*max);
  819. KernelLog.String(":: Analysing Received Data Done"); KernelLog.Ln;*)
  820. END Transfer;
  821. (* Test command for video streaming transfer *)
  822. PROCEDURE TransferStill * (context: Commands.Context);
  823. VAR
  824. desc: ARRAY 9 OF CHAR;
  825. params: POINTER TO ProbeCommitCtl;
  826. frame: POINTER TO ARRAY OF CHAR;
  827. i, j, count, max: LONGINT;
  828. size: LONGINT;
  829. t: Kernel.Timer;
  830. f: Files.File;
  831. w: Files.Writer;
  832. BEGIN
  833. KernelLog.String(":: Streaming one still image"); KernelLog.Ln;
  834. NEW(params);
  835. params.bmHint := {0};
  836. params.bFormatIndex := 1;
  837. params.bFrameIndex := 2;
  838. params.dwFrameInterval := 333333;
  839. (*params.dwMaxVideoFrameSize := 640 * 480 * 2; (* bytes *)
  840. params.bMaxNumberOfRefFramesPlus1 := 1;*)
  841. (*PrintParams(params^);*)
  842. sdr.NegotiateStill(params^);
  843. PrintParams(params^);
  844. (* Set Interface 1 *)
  845. IF ~sdr.device(Usb.UsbDevice).SetInterface(1, 1) THEN
  846. KernelLog.String("Could not set interface"); KernelLog.Ln
  847. END;
  848. (*size := 120 * 160 * 2(*params.dwMaxPayloadTransferSize*);
  849. max := 1;
  850. NEW(frame, size * max);*)
  851. desc[0] := 1X;
  852. sdr.ControlRequest(SetCur, VSStillImageTriggerCtl, desc, 1);
  853. (*Transfer*)
  854. (*GetStillFrame(context);*)
  855. (*count := 0;
  856. NEW(t);
  857. REPEAT
  858. KernelLog.String("========== TRANSMITTING PAYLOAD #"); KernelLog.Int(count, 0); KernelLog.String(" =========="); KernelLog.Ln;
  859. i := sdr.videoPipe.Transfer(size, size * count, frame^);
  860. KernelLog.String(":: Transfer finished: "); KernelLog.Int(i, 0); KernelLog.Ln;
  861. t.Sleep(30);
  862. INC(count);
  863. UNTIL (count >= max) OR (i > Usbdi.ShortPacket);
  864. KernelLog.String(":: Analysing Received Data"); KernelLog.Ln;
  865. f := Files.New("UsbFrameImage.dat");
  866. Files.OpenWriter(w, f, 0);
  867. j := 0;
  868. i := -1;
  869. WHILE j < size * max DO
  870. IF ORD(frame[j]) = 12 THEN
  871. IF i # -1 THEN KernelLog.String(" Length: "); KernelLog.Int(i, 0); KernelLog.Ln END;
  872. KernelLog.String("Found header at "); KernelLog.Int(j, 0); KernelLog.String(" "); KernelLog.Buffer(frame^, j, 12);
  873. PrintHeader(frame^, j);
  874. INC(j, 11); i := -1
  875. ELSIF frame[j] = 0X THEN
  876. (*i := -1;*)
  877. DEC(i)
  878. ELSE
  879. w.Char(frame[j])
  880. END;
  881. INC(j);
  882. INC(i)
  883. END;
  884. w.Update;
  885. Files.Register(f);
  886. f.Close;
  887. KernelLog.Buffer(frame^, 0, size*max);
  888. KernelLog.String(":: Analysing Received Data Done"); KernelLog.Ln;*)
  889. END TransferStill;
  890. PROCEDURE FindHeaders * (context: Commands.Context);
  891. VAR
  892. i, j, n, l: LONGINT;
  893. finished: BOOLEAN;
  894. BEGIN
  895. n := 0;
  896. i := 0;
  897. (*WHILE ORD(frame[i]) # 12 DO INC(i) END;*)
  898. WHILE (~finished) & (i < LEN(frame)) DO
  899. IF ORD(frame[i]) = 12 THEN
  900. (* Found header *)
  901. IF n < LEN(headers) THEN
  902. j := 0;
  903. WHILE (frame[i + 12 + j] # 0X) & (ORD(frame[i + 12 + j]) # 12) DO
  904. INC(j)
  905. END;
  906. headers[n].pos := i;
  907. headers[n].size := j;
  908. context.out.String("Header #"); context.out.Int(n, 0); context.out.Ln;
  909. context.out.String(" -> "); PrintHeader(frame^, i, context.out);
  910. context.out.String(" pos: "); context.out.Int(i, 0); context.out.Ln;
  911. context.out.String(" size: "); context.out.Int(j, 0); context.out.Ln;
  912. INC(n);
  913. WHILE (i + 12 + j < LEN(frame)) & (frame[i + 12 + j] = 0X) DO INC(j) END;
  914. INC(i, sdr.videoPipe.maxPacketSize);
  915. ELSE
  916. context.out.Update;
  917. context.out(*error*).String("ERROR: Too many headers, stopping analysis");
  918. context.out(*error*).Ln;
  919. context.out(*error*).Update;
  920. finished := TRUE
  921. END
  922. ELSE
  923. context.out.Update;
  924. context.out(*error*).String("ERROR: Expected header");
  925. context.out(*error*).Ln;
  926. context.out(*error*).Update;
  927. finished := TRUE
  928. END;
  929. END;
  930. context.out.String("Summary"); context.out.Ln;
  931. context.out.String(" headers: "); context.out.Int(n, 0); context.out.Ln;
  932. i := 0;
  933. WHILE i < n DO
  934. INC(l, headers[i].size);
  935. INC(i)
  936. END;
  937. context.out.String(" total size: "); context.out.Int(l, 0); context.out.Ln;
  938. context.out.Update
  939. END FindHeaders;
  940. PROCEDURE Record * (context: Commands.Context);
  941. VAR
  942. i: LONGINT;
  943. f: Files.File;
  944. w: Files.Writer;
  945. BEGIN
  946. f := Files.New("UsbFrameImage.dat");
  947. Files.OpenWriter(w, f, 0);
  948. context.arg.Int(i, FALSE);
  949. WHILE i # 0 DO
  950. IF i > 20 THEN
  951. context.out.String("ERROR: invalid header index ");
  952. context.out.Int(i, 0);
  953. context.out.String(". Skipping.");
  954. context.out.Ln
  955. ELSE
  956. w.Bytes(frame^, headers[i].pos + 12, headers[i].size)
  957. END;
  958. context.arg.Int(i, FALSE);
  959. END;
  960. w.Update;
  961. Files.Register(f);
  962. f.Close
  963. END Record;
  964. PROCEDURE Stream * (context: Commands.Context);
  965. VAR
  966. t: Kernel.MilliTimer;
  967. BEGIN
  968. LOOP
  969. Kernel.SetTimer(t, 33);
  970. GetFrame(context);
  971. (*FindHeaders(context);*)
  972. context.out.String("Data received: "); context.out.Int(sdr.videoPipe(UsbHcdi.Pipe).actLen, 0);
  973. context.out.String('/'); context.out.Int(120 * 160 * 2, 0);
  974. context.out.Ln; context.out.Update;
  975. REPEAT Objects.Yield UNTIL Kernel.Expired(t)
  976. END
  977. END Stream;
  978. PROCEDURE GetFrame * (context: Commands.Context);
  979. VAR
  980. hdr: Header;
  981. t: Kernel.MilliTimer;
  982. f: Files.File;
  983. w: Files.Writer;
  984. buf: POINTER TO ARRAY OF CHAR;
  985. actual, i, j, n, ofs, size, status, tx: LONGINT;
  986. id, start, stop, record: BOOLEAN;
  987. BEGIN
  988. size := 640 * 480 * 2;
  989. NEW(frame, size);
  990. f := Files.New('UsbFrame.Log');
  991. Files.OpenWriter(w, f, 0);
  992. tx := sdr.videoPipe.maxPacketSize * sdr.videoPipe(UsbHcdi.Pipe).mult;
  993. NEW(buf, tx);
  994. start := TRUE;
  995. Kernel.SetTimer(t, 30000);
  996. (*sdr.Pause;*)
  997. REPEAT
  998. w.String("Elapsed: ");
  999. w.Int(Kernel.Elapsed(t), 5);
  1000. w.String(" ");
  1001. status := sdr.videoPipe.Transfer(tx, 0, buf^);
  1002. INC(i);
  1003. actual := sdr.videoPipe(UsbHcdi.Pipe).actLen;
  1004. IF start THEN
  1005. id := ~hdr.id;
  1006. start := FALSE
  1007. END;
  1008. IF actual > 12 THEN
  1009. PrintHeader(buf^, 0, w);
  1010. GetHeader(buf^, 0, hdr);
  1011. IF id = hdr.id THEN
  1012. IF start THEN hdr.id := id; start := FALSE END;
  1013. w.String(" Recording ");
  1014. w.Int(actual, 0);
  1015. w.String(" bytes");
  1016. j := 12;
  1017. WHILE (j < actual) & (ofs < size) DO
  1018. frame[ofs] := buf[j];
  1019. INC(ofs);
  1020. INC(j)
  1021. END
  1022. ELSE
  1023. w.String(" Not recording")
  1024. END;
  1025. IF ~start & (hdr.id = id) & hdr.eof THEN
  1026. stop := TRUE
  1027. END;
  1028. ELSIF status = Usbdi.ShortPacket THEN
  1029. w.String("Skipping transfer: no data");
  1030. ELSE
  1031. w.String("TRANSFER ERROR ");
  1032. w.Int(status, 0);
  1033. END;
  1034. w.Ln
  1035. UNTIL (status > Usbdi.ShortPacket) OR (ofs = size) OR stop;
  1036. (*sdr.Resume;*)
  1037. w.String("recorded ");
  1038. w.Int(ofs, 0);
  1039. w.String(" bytes");
  1040. w.Ln;
  1041. w.String("missing ");
  1042. w.Int(size - ofs, 0);
  1043. w.String(" bytes");
  1044. w.Ln;
  1045. w.Update;
  1046. Files.Register(f);
  1047. f.Close
  1048. END GetFrame;
  1049. PROCEDURE GetFrame2 * (context: Commands.Context);
  1050. VAR
  1051. hdr: Header;
  1052. t: Kernel.MilliTimer;
  1053. f: Files.File;
  1054. w: Files.Writer;
  1055. buf: POINTER TO ARRAY OF CHAR;
  1056. actual, i, j, n, ofs, size, status, tx: LONGINT;
  1057. id, start, stop, record: BOOLEAN;
  1058. BEGIN
  1059. size := 640 * 480 * 2;
  1060. NEW(frame, size);
  1061. f := Files.New('UsbFrame.Log');
  1062. Files.OpenWriter(w, f, 0);
  1063. tx := 2 * sdr.videoPipe.maxPacketSize * sdr.videoPipe(UsbHcdi.Pipe).mult;
  1064. NEW(buf, tx);
  1065. start := TRUE;
  1066. Kernel.SetTimer(t, 30000);
  1067. REPEAT
  1068. w.String("Elapsed: ");
  1069. w.Int(Kernel.Elapsed(t), 5);
  1070. w.String(" ");
  1071. status := sdr.videoPipe.Transfer(tx, 0, buf^);
  1072. INC(i);
  1073. actual := sdr.videoPipe(UsbHcdi.Pipe).actLen;
  1074. IF start THEN
  1075. id := ~hdr.id;
  1076. start := FALSE
  1077. END;
  1078. IF actual > 24 THEN
  1079. PrintHeader(buf^, 0, w);
  1080. GetHeader(buf^, 0, hdr);
  1081. IF id = hdr.id THEN
  1082. IF start THEN hdr.id := id; start := FALSE END;
  1083. w.String(" Recording ");
  1084. w.Int(MIN(actual, 3000), 0);
  1085. w.String(" bytes");
  1086. j := 12;
  1087. WHILE (j < MIN(3000, actual)) & (ofs < size) DO
  1088. frame[ofs] := buf[j];
  1089. INC(ofs);
  1090. INC(j)
  1091. END
  1092. ELSE
  1093. w.String(" Not recording")
  1094. END;
  1095. IF ~start & (hdr.id = id) & hdr.eof THEN
  1096. stop := TRUE
  1097. END;
  1098. IF actual > 3000 + 12 THEN
  1099. w.String(" ");
  1100. PrintHeader(buf^, 3000, w);
  1101. GetHeader(buf^, 3000, hdr);
  1102. IF id = hdr.id THEN
  1103. w.String(" Recording ");
  1104. w.Int(actual - 3000, 0);
  1105. w.String(" bytes");
  1106. j := 12 + 3000;
  1107. WHILE (j < actual) & (ofs < size) DO
  1108. frame[ofs] := buf[j];
  1109. INC(ofs);
  1110. INC(j)
  1111. END
  1112. ELSE
  1113. w.String(" Not recording")
  1114. END;
  1115. IF ~start & (hdr.id = id) & hdr.eof THEN
  1116. stop := TRUE
  1117. END
  1118. ELSE
  1119. w.String("Skipping transfer: no data");
  1120. END
  1121. ELSIF status = Usbdi.ShortPacket THEN
  1122. w.String("Skipping transfer: no data");
  1123. ELSE
  1124. w.String("TRANSFER ERROR ");
  1125. w.Int(status, 0);
  1126. END;
  1127. w.Ln
  1128. UNTIL (status > Usbdi.ShortPacket) OR (ofs = size) OR stop;
  1129. w.String("recorded ");
  1130. w.Int(ofs, 0);
  1131. w.String(" bytes");
  1132. w.Ln;
  1133. w.String("missing ");
  1134. w.Int(size - ofs, 0);
  1135. w.String(" bytes");
  1136. w.Ln;
  1137. w.Update;
  1138. Files.Register(f);
  1139. f.Close
  1140. END GetFrame2;
  1141. PROCEDURE GetFrame3 * (context: Commands.Context);
  1142. VAR
  1143. hdr: Header;
  1144. t: Kernel.MilliTimer;
  1145. f: Files.File;
  1146. w: Files.Writer;
  1147. actual, el, i, j, n, ofs, size, status, tx: LONGINT;
  1148. id, start, stop, record: BOOLEAN;
  1149. buf: POINTER TO ARRAY OF CHAR;
  1150. BEGIN
  1151. (*context.out.String("Get Frame v3 starting... ");
  1152. context.out.Update;*)
  1153. (*NEW(frame, size);*)
  1154. (*NEW(buf, tx);
  1155. start := TRUE;*)
  1156. (*Kernel.SetTimer(t, 30000);*)
  1157. (*REPEAT
  1158. w.String("Elapsed: ");
  1159. w.Int(Kernel.Elapsed(t), 5);
  1160. w.String(" ");
  1161. status := sdr.videoPipe.Transfer(tx, 0, buf^);
  1162. INC(i);
  1163. actual := sdr.videoPipe(UsbHcdi.Pipe).actLen;
  1164. IF start THEN
  1165. id := ~hdr.id;
  1166. start := FALSE
  1167. END;
  1168. IF actual > 12 THEN
  1169. PrintHeader(buf^, 0, w);
  1170. GetHeader(buf^, 0, hdr);
  1171. IF hdr.eof THEN
  1172. stop := TRUE
  1173. END;
  1174. ELSIF status = Usbdi.ShortPacket THEN
  1175. w.String("Skipping transfer: no data");
  1176. ELSE
  1177. w.String("TRANSFER ERROR ");
  1178. w.Int(status, 0);
  1179. END;
  1180. w.Ln
  1181. UNTIL stop;*)
  1182. NEW(buf, sdr.params.dwMaxPayloadTransferSize);
  1183. (* Set Interface 1 *)
  1184. IF ~sdr.device(Usb.UsbDevice).SetInterface(1, 5) THEN
  1185. KernelLog.String("Could not set interface"); KernelLog.Ln
  1186. END;
  1187. Kernel.SetTimer(t, 30);
  1188. sdr.videoPipe := sdr.device.GetPipe(sdr.inputHeader.bEndpointAddress);
  1189. sdr.videoPipe.maxPacketSize := 800;
  1190. sdr.videoPipe(UsbHcdi.Pipe).mult := 1;
  1191. tx := sdr.videoPipe.maxPacketSize * sdr.videoPipe(UsbHcdi.Pipe).mult;
  1192. (*NEW(buf, 120 * 160 * 2 + 214 * 12);*)
  1193. WHILE ~Kernel.Expired(t) DO END;
  1194. status := sdr.videoPipe.Transfer(LEN(buf), 0, buf^);
  1195. f := Files.New('UsbFrame.Log');
  1196. Files.OpenWriter(w, f, 0);
  1197. w.String("Elapsed: ");
  1198. w.Int(el, 5);
  1199. w.String(" ");
  1200. w.Int(status, 0);
  1201. w.Ln;
  1202. context.out.String("recording... ");
  1203. context.out.Update;
  1204. w.String("Recording");
  1205. w.Ln;
  1206. actual := sdr.videoPipe(UsbHcdi.Pipe).actLen;
  1207. w.String("Transfered ");
  1208. w.Int(actual, 0);
  1209. w.String(" bytes.");
  1210. w.Ln;
  1211. i := 0;
  1212. WHILE (i + j < actual) & (ofs < Size) DO
  1213. GetHeader(buf^, i, hdr);
  1214. PrintHeader(buf^, i, w);
  1215. j := 0;
  1216. IF buf[i] # 0X THEN
  1217. WHILE j < tx - 12 DO
  1218. frame[ofs] := buf[i + j];
  1219. INC(ofs);
  1220. INC(j)
  1221. END
  1222. END;
  1223. INC(i, tx);
  1224. w.Ln
  1225. END;
  1226. w.String("recorded ");
  1227. w.Int(ofs, 0);
  1228. w.String(" bytes");
  1229. w.Ln;
  1230. w.String("missing ");
  1231. w.Int(Size - ofs, 0);
  1232. w.String(" bytes");
  1233. w.Ln;
  1234. w.Update;
  1235. Files.Register(f);
  1236. f.Close;
  1237. context.out.String("done");
  1238. context.out.Ln;
  1239. context.out.Update
  1240. END GetFrame3;
  1241. PROCEDURE SkipFrame;
  1242. VAR
  1243. hdr: Header;
  1244. buf: POINTER TO ARRAY OF CHAR;
  1245. actual, i, j, n, ofs, size, status, tx: LONGINT;
  1246. id, start, stop, record: BOOLEAN;
  1247. BEGIN
  1248. tx := sdr.videoPipe.maxPacketSize * sdr.videoPipe(UsbHcdi.Pipe).mult;
  1249. NEW(buf, tx);
  1250. start := TRUE;
  1251. REPEAT
  1252. status := sdr.videoPipe.Transfer(tx, 0, buf^);
  1253. INC(i);
  1254. actual := sdr.videoPipe(UsbHcdi.Pipe).actLen;
  1255. IF start THEN
  1256. id := ~hdr.id;
  1257. start := FALSE
  1258. END;
  1259. IF actual > 12 THEN
  1260. GetHeader(buf^, 0, hdr);
  1261. IF id = hdr.id THEN
  1262. IF start THEN hdr.id := id; start := FALSE END;
  1263. j := 12;
  1264. WHILE (j < actual) & (ofs < size) DO
  1265. INC(ofs);
  1266. INC(j)
  1267. END
  1268. END;
  1269. IF ~start & (hdr.id = id) & hdr.eof THEN
  1270. stop := TRUE
  1271. END;
  1272. END;
  1273. UNTIL (status > Usbdi.ShortPacket) OR (ofs = size) OR stop;
  1274. END SkipFrame;
  1275. PROCEDURE GetStillFrame * (context: Commands.Context);
  1276. VAR
  1277. hdr: Header;
  1278. t: Kernel.MilliTimer;
  1279. f: Files.File;
  1280. w: Files.Writer;
  1281. buf: POINTER TO ARRAY OF CHAR;
  1282. actual, i, j, n, ofs, size, status, tx: LONGINT;
  1283. id, start, stop, record: BOOLEAN;
  1284. BEGIN
  1285. size := 120 * 160 * 2;
  1286. NEW(frame, size);
  1287. f := Files.New('UsbFrame.Log');
  1288. Files.OpenWriter(w, f, 0);
  1289. tx := sdr.videoPipe.maxPacketSize * sdr.videoPipe(UsbHcdi.Pipe).mult;
  1290. NEW(buf, tx);
  1291. start := TRUE;
  1292. Kernel.SetTimer(t, 30000);
  1293. REPEAT
  1294. w.String("Elapsed: ");
  1295. w.Int(Kernel.Elapsed(t), 5);
  1296. w.String(" ");
  1297. status := sdr.videoPipe.Transfer(tx, 0, buf^);
  1298. INC(i);
  1299. actual := sdr.videoPipe(UsbHcdi.Pipe).actLen;
  1300. IF actual > 12 THEN
  1301. PrintHeader(buf^, 0, w);
  1302. GetHeader(buf^, 0, hdr);
  1303. IF (start OR (id = hdr.id)) & hdr.still THEN
  1304. IF start THEN hdr.id := id; start := FALSE END;
  1305. w.String(" Recording ");
  1306. w.Int(actual, 0);
  1307. w.String(" bytes");
  1308. j := 12;
  1309. WHILE (j < actual) & (ofs < size) DO
  1310. frame[ofs] := buf[j];
  1311. INC(ofs);
  1312. INC(j)
  1313. END
  1314. END;
  1315. IF ~start & (hdr.id = id) & hdr.still & hdr.eof THEN
  1316. stop := TRUE
  1317. END;
  1318. ELSIF status = Usbdi.ShortPacket THEN
  1319. w.String("Skipping transfer: no data");
  1320. ELSE
  1321. w.String("TRANSFER ERROR ");
  1322. w.Int(status, 0);
  1323. END;
  1324. w.Ln
  1325. UNTIL (status > Usbdi.ShortPacket) OR (ofs = size) OR stop;
  1326. w.String("recorded ");
  1327. w.Int(ofs, 0);
  1328. w.String(" bytes");
  1329. w.Ln;
  1330. w.String("missing ");
  1331. w.Int(size - ofs, 0);
  1332. w.String(" bytes");
  1333. w.Ln;
  1334. w.Update;
  1335. Files.Register(f);
  1336. f.Close
  1337. END GetStillFrame;
  1338. PROCEDURE Photo * (context: Commands.Context);
  1339. VAR
  1340. i: LONGINT;
  1341. t: Kernel.MilliTimer;
  1342. BEGIN
  1343. FOR i := 1 TO 60 DO
  1344. Kernel.SetTimer(t, 33);
  1345. GetFrame(context);
  1346. REPEAT Objects.Yield UNTIL Kernel.Expired(t)
  1347. END;
  1348. TransferStill(context);
  1349. context.out.String("CAPTURING");
  1350. context.out.Ln;
  1351. GetStillFrame(context)
  1352. END Photo;
  1353. PROCEDURE SaveFrame * (context: Commands.Context);
  1354. VAR
  1355. f: Files.File;
  1356. w: Files.Writer;
  1357. BEGIN
  1358. KernelLog.Buffer(frame^, 0, LEN(frame));
  1359. context.out.String(" :: Saving frame... ");
  1360. context.out.Update;
  1361. f := Files.New("UsbFrameImage.dat");
  1362. Files.OpenWriter(w, f, 0);
  1363. w.Bytes(frame^, 0, LEN(frame));
  1364. w.Update;
  1365. Files.Register(f);
  1366. f.Close;
  1367. context.out.String("done");
  1368. context.out.Ln;
  1369. context.out.Update
  1370. END SaveFrame;
  1371. BEGIN
  1372. KernelLog.String("UsbVideo@Body"); KernelLog.Ln;
  1373. TRACE(SIZEOF(ProbeCommitCtl), SIZEOF(SHORTINT), SIZEOF(INTEGER), SIZEOF(LONGINT), SIZEOF(HUGEINT));
  1374. Modules.InstallTermHandler(Cleanup);
  1375. Usbdi.drivers.Add(Probe, Name, Description, Priority);
  1376. NEW(frame, Size)
  1377. END UsbVideo.
  1378. UsbVideo.Transfer ~
  1379. UsbVideo.TransferStill ~
  1380. UsbVideo.FindHeaders ~
  1381. UsbVideo.Record ~
  1382. UsbVideo.Stream ~
  1383. UsbVideo.GetFrame ~
  1384. UsbVideo.GetFrame2 ~
  1385. UsbVideo.GetFrame3 ~
  1386. UsbVideo.GetStillFrame ~
  1387. UsbVideo.SaveFrame ~
  1388. UsbVideo.Photo ~
  1389. SystemTools.List modules ~
  1390. SystemTools.Free UsbVideo UsbVideoDesc ~
  1391. UsbInfo.TraceOn Copying ~
  1392. UsbInfo.TraceNone ~