1 #include "CamDevice.h" 2 #include "CamSensor.h" 3 #include "CamDeframer.h" 4 #include "CamDebug.h" 5 #include "AddOn.h" 6 7 #include <OS.h> 8 #include <Autolock.h> 9 #include <usb/USBDevice.h> 10 11 //#define DEBUG_WRITE_DUMP 12 //#define DEBUG_DISCARD_DATA 13 //#define DEBUG_READ_DUMP 14 //#define DEBUG_DISCARD_INPUT 15 16 #undef B_WEBCAM_DECLARE_SENSOR 17 #define B_WEBCAM_DECLARE_SENSOR(sensorclass,sensorname) \ 18 extern "C" CamSensor *Instantiate##sensorclass(CamDevice *cam); 19 #include "CamInternalSensors.h" 20 #undef B_WEBCAM_DECLARE_SENSOR 21 typedef CamSensor *(*SensorInstFunc)(CamDevice *cam); 22 struct { const char *name; SensorInstFunc instfunc; } kSensorTable[] = { 23 #define B_WEBCAM_DECLARE_SENSOR(sensorclass,sensorname) \ 24 { #sensorname, &Instantiate##sensorclass }, 25 #include "CamInternalSensors.h" 26 { NULL, NULL }, 27 }; 28 #undef B_WEBCAM_DECLARE_SENSOR 29 30 // ----------------------------------------------------------------------------- 31 CamDevice::CamDevice(CamDeviceAddon &_addon, BUSBDevice* _device) 32 : fInitStatus(B_NO_INIT), 33 fCamDeviceAddon(_addon), 34 fDevice(_device), 35 fSupportedDeviceIndex(-1), 36 fTransferEnabled(false), 37 fLocker("WebcamDeviceLock"), 38 fSensor(NULL) 39 { 40 // fill in the generic flavor 41 memset(&fFlavorInfo, 0, sizeof(fFlavorInfo)); 42 _addon.WebCamAddOn()->FillDefaultFlavorInfo(&fFlavorInfo); 43 // if we use id matching, cache the index to the list 44 if (fCamDeviceAddon.SupportedDevices()) 45 { 46 fSupportedDeviceIndex = fCamDeviceAddon.Sniff(_device); 47 fFlavorInfoNameStr = ""; 48 fFlavorInfoNameStr << fCamDeviceAddon.SupportedDevices()[fSupportedDeviceIndex].vendor << " USB Webcam"; 49 fFlavorInfoInfoStr = ""; 50 fFlavorInfoInfoStr << fCamDeviceAddon.SupportedDevices()[fSupportedDeviceIndex].vendor; 51 fFlavorInfoInfoStr << " (" << fCamDeviceAddon.SupportedDevices()[fSupportedDeviceIndex].product << ") USB Webcam"; 52 fFlavorInfo.name = (char *)fFlavorInfoNameStr.String(); 53 fFlavorInfo.info = (char *)fFlavorInfoInfoStr.String(); 54 } 55 #ifdef DEBUG_WRITE_DUMP 56 fDumpFD = open("/boot/home/webcam.out", O_CREAT|O_RDWR, 0644); 57 #endif 58 #ifdef DEBUG_READ_DUMP 59 fDumpFD = open("/boot/home/webcam.out", O_RDONLY, 0644); 60 #endif 61 fBufferLen = 1*B_PAGE_SIZE; 62 fBuffer = (uint8 *)malloc(fBufferLen); 63 } 64 65 // ----------------------------------------------------------------------------- 66 CamDevice::~CamDevice() 67 { 68 close(fDumpFD); 69 free(fBuffer); 70 if (fDeframer) 71 delete fDeframer; 72 } 73 74 // ----------------------------------------------------------------------------- 75 status_t 76 CamDevice::InitCheck() 77 { 78 return fInitStatus; 79 } 80 81 // ----------------------------------------------------------------------------- 82 bool 83 CamDevice::Matches(BUSBDevice* _device) 84 { 85 return (_device) == (fDevice); 86 } 87 88 // ----------------------------------------------------------------------------- 89 BUSBDevice* 90 CamDevice::GetDevice() 91 { 92 return fDevice; 93 } 94 95 // ----------------------------------------------------------------------------- 96 void 97 CamDevice::Unplugged() 98 { 99 fDevice = NULL; 100 fBulkIn = NULL; 101 } 102 103 // ----------------------------------------------------------------------------- 104 bool 105 CamDevice::IsPlugged() 106 { 107 return (fDevice != NULL); 108 } 109 110 // ----------------------------------------------------------------------------- 111 const char * 112 CamDevice::BrandName() 113 { 114 if (fCamDeviceAddon.SupportedDevices() && (fSupportedDeviceIndex > -1)) 115 return fCamDeviceAddon.SupportedDevices()[fSupportedDeviceIndex].vendor; 116 return "<unknown>"; 117 } 118 119 // ----------------------------------------------------------------------------- 120 const char * 121 CamDevice::ModelName() 122 { 123 if (fCamDeviceAddon.SupportedDevices() && (fSupportedDeviceIndex > -1)) 124 return fCamDeviceAddon.SupportedDevices()[fSupportedDeviceIndex].product; 125 return "<unknown>"; 126 } 127 128 // ----------------------------------------------------------------------------- 129 bool 130 CamDevice::SupportsBulk() 131 { 132 return false; 133 } 134 135 // ----------------------------------------------------------------------------- 136 bool 137 CamDevice::SupportsIsochronous() 138 { 139 return false; 140 } 141 142 // ----------------------------------------------------------------------------- 143 status_t 144 CamDevice::StartTransfer() 145 { 146 status_t err = B_OK; 147 PRINT((CH "()" CT)); 148 if (fTransferEnabled) 149 return EALREADY; 150 fPumpThread = spawn_thread(_DataPumpThread, "USB Webcam Data Pump", 50, this); 151 if (fPumpThread < B_OK) 152 return fPumpThread; 153 if (fSensor) 154 err = fSensor->StartTransfer(); 155 if (err < B_OK) 156 return err; 157 fTransferEnabled = true; 158 resume_thread(fPumpThread); 159 PRINT((CH ": transfer enabled" CT)); 160 return B_OK; 161 } 162 163 // ----------------------------------------------------------------------------- 164 status_t 165 CamDevice::StopTransfer() 166 { 167 status_t err = B_OK; 168 PRINT((CH "()" CT)); 169 if (!fTransferEnabled) 170 return EALREADY; 171 if (fSensor) 172 err = fSensor->StopTransfer(); 173 if (err < B_OK) 174 return err; 175 fTransferEnabled = false; 176 wait_for_thread(fPumpThread, &err); 177 return B_OK; 178 } 179 180 // ----------------------------------------------------------------------------- 181 status_t 182 CamDevice::SetVideoFrame(BRect frame) 183 { 184 fVideoFrame = frame; 185 return B_OK; 186 } 187 188 // ----------------------------------------------------------------------------- 189 status_t 190 CamDevice::SetScale(float scale) 191 { 192 return B_OK; 193 } 194 195 // ----------------------------------------------------------------------------- 196 status_t 197 CamDevice::SetVideoParams(float brightness, float contrast, float hue, float red, float green, float blue) 198 { 199 return B_OK; 200 } 201 202 // ----------------------------------------------------------------------------- 203 size_t 204 CamDevice::MinRawFrameSize() 205 { 206 return 0; 207 } 208 209 // ----------------------------------------------------------------------------- 210 size_t 211 CamDevice::MaxRawFrameSize() 212 { 213 return 0; 214 } 215 216 // ----------------------------------------------------------------------------- 217 bool 218 CamDevice::ValidateStartOfFrameTag(const uint8 *tag, size_t taglen) 219 { 220 return true; 221 } 222 223 // ----------------------------------------------------------------------------- 224 bool 225 CamDevice::ValidateEndOfFrameTag(const uint8 *tag, size_t taglen, size_t datalen) 226 { 227 return true; 228 } 229 230 // ----------------------------------------------------------------------------- 231 status_t 232 CamDevice::GetFrameBitmap(BBitmap **bm) 233 { 234 return EINVAL; 235 } 236 237 // ----------------------------------------------------------------------------- 238 status_t 239 CamDevice::FillFrameBuffer(BBuffer *buffer) 240 { 241 return EINVAL; 242 } 243 244 // ----------------------------------------------------------------------------- 245 bool 246 CamDevice::Lock() 247 { 248 return fLocker.Lock(); 249 } 250 251 // ----------------------------------------------------------------------------- 252 void 253 CamDevice::Unlock() 254 { 255 fLocker.Unlock(); 256 } 257 258 // ----------------------------------------------------------------------------- 259 ssize_t 260 CamDevice::WriteReg(uint16 address, uint8 *data, size_t count) 261 { 262 return ENOSYS; 263 } 264 265 // ----------------------------------------------------------------------------- 266 ssize_t 267 CamDevice::WriteReg8(uint16 address, uint8 data) 268 { 269 return WriteReg(address, &data, sizeof(uint8)); 270 } 271 272 // ----------------------------------------------------------------------------- 273 ssize_t 274 CamDevice::WriteReg16(uint16 address, uint16 data) 275 { 276 // XXX: ENDIAN??? 277 return WriteReg(address, (uint8 *)&data, sizeof(uint16)); 278 } 279 280 // ----------------------------------------------------------------------------- 281 ssize_t 282 CamDevice::ReadReg(uint16 address, uint8 *data, size_t count, bool cached) 283 { 284 return ENOSYS; 285 } 286 287 // ----------------------------------------------------------------------------- 288 /* 289 status_t 290 CamDevice::GetStatusIIC() 291 { 292 return ENOSYS; 293 } 294 */ 295 // ----------------------------------------------------------------------------- 296 /*status_t 297 CamDevice::WaitReadyIIC() 298 { 299 return ENOSYS; 300 } 301 */ 302 // ----------------------------------------------------------------------------- 303 ssize_t 304 CamDevice::WriteIIC(uint8 address, uint8 *data, size_t count) 305 { 306 return ENOSYS; 307 } 308 309 // ----------------------------------------------------------------------------- 310 ssize_t 311 CamDevice::WriteIIC8(uint8 address, uint8 data) 312 { 313 return WriteIIC(address, &data, 1); 314 } 315 316 // ----------------------------------------------------------------------------- 317 ssize_t 318 CamDevice::ReadIIC(uint8 address, uint8 *data) 319 { 320 return ENOSYS; 321 } 322 323 // ----------------------------------------------------------------------------- 324 CamSensor * 325 CamDevice::CreateSensor(const char *name) 326 { 327 int i; 328 for (i = 0; kSensorTable[i].name; i++) { 329 if (!strcmp(kSensorTable[i].name, name)) 330 return kSensorTable[i].instfunc(this); 331 } 332 return NULL; 333 } 334 335 // ----------------------------------------------------------------------------- 336 void 337 CamDevice::SetDataInput(BDataIO *input) 338 { 339 fDataInput = input; 340 } 341 342 // ----------------------------------------------------------------------------- 343 status_t 344 CamDevice::DataPumpThread() 345 { 346 if (SupportsBulk()) { 347 PRINT((CH ": using Bulk" CT)); 348 while (fTransferEnabled) { 349 ssize_t len = -1; 350 BAutolock lock(fLocker); 351 if (!lock.IsLocked()) 352 break; 353 if (!fBulkIn) 354 break; 355 #ifndef DEBUG_DISCARD_INPUT 356 len = fBulkIn->BulkTransfer(fBuffer, fBufferLen); 357 #endif 358 359 //PRINT((CH ": got %d bytes" CT, len)); 360 #ifdef DEBUG_WRITE_DUMP 361 write(fDumpFD, fBuffer, len); 362 #endif 363 #ifdef DEBUG_READ_DUMP 364 if ((len = read(fDumpFD, fBuffer, fBufferLen)) < fBufferLen) 365 lseek(fDumpFD, 0LL, SEEK_SET); 366 #endif 367 368 if (len <= 0) { 369 PRINT((CH ": BulkIn: %s" CT, strerror(len))); 370 break; 371 } 372 373 #ifndef DEBUG_DISCARD_DATA 374 if (fDataInput) { 375 fDataInput->Write(fBuffer, len); 376 // else drop 377 } 378 #endif 379 //snooze(2000); 380 } 381 } 382 if (SupportsIsochronous()) { 383 ;//XXX: TODO 384 } 385 return B_OK; 386 } 387 388 // ----------------------------------------------------------------------------- 389 int32 390 CamDevice::_DataPumpThread(void *_this) 391 { 392 CamDevice *dev = (CamDevice *)_this; 393 return dev->DataPumpThread(); 394 } 395 396 // ----------------------------------------------------------------------------- 397 void 398 CamDevice::DumpRegs() 399 { 400 } 401 402 // ----------------------------------------------------------------------------- 403 CamDeviceAddon::CamDeviceAddon(WebCamMediaAddOn* webcam) 404 : fWebCamAddOn(webcam), 405 fSupportedDevices(NULL) 406 { 407 } 408 409 // ----------------------------------------------------------------------------- 410 CamDeviceAddon::~CamDeviceAddon() 411 { 412 } 413 414 // ----------------------------------------------------------------------------- 415 const char * 416 CamDeviceAddon::BrandName() 417 { 418 return "<unknown>"; 419 } 420 421 // ----------------------------------------------------------------------------- 422 status_t 423 CamDeviceAddon::Sniff(BUSBDevice *device) 424 { 425 PRINT((CH ": Sniffing for %s" CT, BrandName())); 426 if (!fSupportedDevices) 427 return ENODEV; 428 if (!device) 429 return EINVAL; 430 for (uint32 i = 0; fSupportedDevices[i].vendor; i++) 431 { 432 /* PRINT((CH "{%u,%u,%u,0x%x,0x%x} <> {%u,%u,%u,0x%x,0x%x}" CT, 433 device.Class(), device.Subclass(), device.Protocol(), device.VendorID(), device.ProductID(), 434 fSupportedDevices[i].desc.dev_class, fSupportedDevices[i].desc.dev_subclass, fSupportedDevices[i].desc.dev_protocol, fSupportedDevices[i].desc.vendor, fSupportedDevices[i].desc.product));*/ 435 /* if (device.Class() != fSupportedDevices[i].desc.dev_class) 436 continue; 437 if (device.Subclass() != fSupportedDevices[i].desc.dev_subclass) 438 continue; 439 if (device.Protocol() != fSupportedDevices[i].desc.dev_protocol) 440 continue;*/ 441 if (device->VendorID() != fSupportedDevices[i].desc.vendor) 442 continue; 443 if (device->ProductID() != fSupportedDevices[i].desc.product) 444 continue; 445 return i; 446 } 447 return ENODEV; 448 } 449 450 // ----------------------------------------------------------------------------- 451 CamDevice * 452 CamDeviceAddon::Instantiate(CamRoster &roster, BUSBDevice *from) 453 { 454 return NULL; 455 } 456 457 // ----------------------------------------------------------------------------- 458 void 459 CamDeviceAddon::SetSupportedDevices(const usb_named_support_descriptor *devs) 460 { 461 fSupportedDevices = devs; 462 } 463 464