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