video streaming using websocket. but,streaming is very slower than 0.1fps.
Dependencies: BaseUsbHost EthernetInterface WebSocketClient mbed-rtos mbed
Fork of BaseUsbHost_example by
UvcCam.cpp
00001 // UvcCam.cpp 2013/2/11 00002 #include "mbed.h" 00003 #include "rtos.h" 00004 #include "BaseUsbHost.h" 00005 //#define DEBUG 00006 #include "BaseUsbHostDebug.h" 00007 #define TEST 00008 #include "BaseUsbHostTest.h" 00009 #include "UvcCam.h" 00010 #include <string> 00011 00012 UvcCam::UvcCam(int formatIndex, int frameIndex, uint32_t interval, ControlEp* ctlEp) 00013 { 00014 uint8_t buf[34]; 00015 int rc; 00016 int alt; 00017 int cfg2; 00018 00019 if (ctlEp == NULL) { // root hub 00020 DBG_OHCI(LPC_USB->HcRhPortStatus1); 00021 TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200); 00022 ctlEp = new ControlEp(); 00023 TEST_ASSERT_TRUE(ctlEp); 00024 } 00025 bool r = check(ctlEp); 00026 TEST_ASSERT(r); 00027 m_ctlEp = ctlEp; 00028 00029 rc = ctlEp->GetDescriptor(1, 0, buf, sizeof(StandardDeviceDescriptor)); 00030 TEST_ASSERT(rc == USB_OK); 00031 StandardDeviceDescriptor* sd = reinterpret_cast<StandardDeviceDescriptor*>(buf); 00032 VERBOSE("vid: %04x\n", sd->idVendor); 00033 VERBOSE("pid: %04x\n", sd->idProduct); 00034 string s = ctlEp->GetStringDescriptor(sd->iManufacturer); 00035 VERBOSE("iManufacturer: %s\n", s.c_str()); 00036 s = ctlEp->GetStringDescriptor(sd->iProduct); 00037 VERBOSE("iProduct: %s\n", s.c_str()); 00038 vid = sd->idVendor; 00039 pid = sd->idProduct; 00040 00041 UvcCfg* cfg = new UvcCfg(formatIndex, frameIndex, ctlEp); 00042 TEST_ASSERT(cfg); 00043 00044 int param_len = 34; 00045 TEST_ASSERT(cfg->bcdUVC >= 0x0100); 00046 if (cfg->bcdUVC == 0x0100) { // UVC ver. 1.0 00047 param_len = 26; 00048 } 00049 00050 int addr = m_ctlEp->GetAddr(); 00051 m_isoEp = new IsochronousEp(addr, cfg->bEndpointAddress, cfg->wMaxPacketSize); 00052 TEST_ASSERT_TRUE(m_isoEp); 00053 00054 //#define USE_PROBE 00055 00056 #ifdef USE_PROBE 00057 rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1); 00058 TEST_ASSERT(rc == USB_OK); 00059 DBG_BYTES("GET_INFO Prob", buf, 1); 00060 00061 rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, param_len); 00062 TEST_ASSERT(rc == USB_OK); 00063 DBG_BYTES("GET_DEF Probe", buf, param_len); 00064 00065 rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, param_len); 00066 TEST_ASSERT(rc == USB_OK); 00067 DBG_BYTES("GET_MIN Probe", buf, param_len); 00068 00069 rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, param_len); 00070 TEST_ASSERT(rc == USB_OK); 00071 DBG_BYTES("GET_MAX Probe", buf, param_len); 00072 00073 rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, param_len); 00074 TEST_ASSERT(rc == USB_OK); 00075 DBG_BYTES("GET_CUR Probe", buf, param_len); 00076 #endif // USE_PROBE 00077 00078 rc = Control(GET_INFO, VS_COMMIT_CONTROL, 1, buf, 1); 00079 TEST_ASSERT(rc == USB_OK); 00080 DBG_BYTES("GET_INFO Commit", buf, 1); 00081 00082 memset(buf, 0, param_len); 00083 buf[2] = cfg->FormatIndex; 00084 buf[3] = cfg->FrameIndex; 00085 *reinterpret_cast<uint32_t*>(buf+4) = interval; 00086 00087 DBG_BYTES("SET_CUR Commit", buf, param_len); 00088 rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len); 00089 TEST_ASSERT(rc == USB_OK); 00090 00091 rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len); 00092 TEST_ASSERT(rc == USB_OK); 00093 TEST_ASSERT_EQUAL(buf[2], cfg->FormatIndex); 00094 TEST_ASSERT_EQUAL(buf[3], cfg->FrameIndex); 00095 TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval); 00096 DBG_BYTES("GET_CUR Commit", buf, param_len); 00097 00098 rc = m_ctlEp->GetConfiguration(&cfg2); 00099 TEST_ASSERT_EQUAL(rc, USB_OK); 00100 DBG("config: %d\n", cfg2); 00101 00102 rc = m_ctlEp->SetConfiguration(1); 00103 TEST_ASSERT_EQUAL(rc, USB_OK); 00104 00105 rc = m_ctlEp->GetConfiguration(&cfg2); 00106 TEST_ASSERT_EQUAL(rc, USB_OK); 00107 DBG("config: %d\n", cfg2); 00108 TEST_ASSERT_EQUAL(cfg2, 1); 00109 00110 rc = m_ctlEp->GetInterface(cfg->bInterface, &alt); 00111 TEST_ASSERT_EQUAL(rc, USB_OK); 00112 DBG("alt: %d\n", alt); 00113 00114 rc = m_ctlEp->SetInterfaceAlternate(cfg->bInterface, cfg->bAlternate); 00115 TEST_ASSERT_EQUAL(rc, USB_OK); 00116 00117 rc = m_ctlEp->GetInterface(cfg->bInterface, &alt); 00118 TEST_ASSERT_EQUAL(rc, USB_OK); 00119 DBG("alt: %d\n", alt); 00120 TEST_ASSERT_EQUAL(alt, cfg->bAlternate); 00121 delete cfg; 00122 00123 for(int i = 0; i < 16; i++) { 00124 report_cc_count[i] = 0; 00125 report_ps_cc_count[i] = 0; 00126 } 00127 00128 LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable 00129 LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable 00130 } 00131 00132 bool UvcCam::check(ControlEp* ctlEp) 00133 { 00134 if (ctlEp == NULL) { 00135 return false; 00136 } 00137 uint8_t buf[18]; 00138 int r = ctlEp->GetDescriptor(1, 0, buf, 8); 00139 if (r != USB_OK) { 00140 return false; 00141 } 00142 DBG_HEX(buf, 8); 00143 const uint8_t desc[] = {0x12,0x01,0x00,0x02,0xef,0x02,0x01}; 00144 if (memcmp(buf, desc, sizeof(desc)) != 0) { 00145 return false; 00146 } 00147 r = ctlEp->GetDescriptor(1, 0, buf, sizeof(buf)); 00148 if (r != USB_OK) { 00149 return false; 00150 } 00151 DBG_HEX(buf, 18); 00152 return true; 00153 } 00154 00155 #define DESCRIPTOR_TYPE_DEVICE 1 00156 #define DESCRIPTOR_TYPE_CONFIGURATION 2 00157 #define DESCRIPTOR_TYPE_STRING 3 00158 #define DESCRIPTOR_TYPE_INTERFACE 4 00159 #define DESCRIPTOR_TYPE_ENDPOINT 5 00160 00161 #define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0b 00162 00163 #define DESCRIPTOR_TYPE_HID 0x21 00164 #define DESCRIPTOR_TYPE_REPORT 0x22 00165 #define DESCRIPTOR_TYPE_PHYSICAL 0x23 00166 #define DESCRIPTOR_TYPE_CS_INTERFACE 0x24 00167 #define DESCRIPTOR_TYPE_CS_ENDPOINT 0x25 00168 #define DESCRIPTOR_TYPE_HUB 0x29 00169 00170 #define CLASS_AUDIO 0x02 00171 #define CLASS_HUB 0x09 00172 00173 #define IF_EQ_THEN_PRINTF(A,B) if (A == B) {VERBOSE("%s\n", #A); 00174 #define ENDIF } 00175 00176 #define CC_AUDIO 0x01 00177 #define SC_AUDIOCONTROL 0x01 00178 #define SC_AUDIOSTREAMING 0x02 00179 00180 #define AC_HEADER 0x01 00181 #define AC_INPUT_TERMINAL 0x02 00182 #define AC_OUTPUT_TERMINAL 0x03 00183 #define AC_FEATURE_UNIT 0x06 00184 00185 // Input Terminal Types 00186 #define ITT_CAMERA 0x0201 00187 00188 static int LE16(const uint8_t* d) 00189 { 00190 return d[0] | (d[1] << 8); 00191 } 00192 00193 static int LE24(const uint8_t* d) { 00194 return d[0] | (d[1]<<8) | (d[2] << 16); 00195 } 00196 00197 static int LE32(const uint8_t* d) { 00198 return d[0] |(d[1]<<8) | (d[2] << 16) |(d[3] << 24) ; 00199 } 00200 00201 struct GUID { 00202 uint8_t data[16]; 00203 string to_string() { 00204 string s; 00205 for(int i = 0; i < 16; i++) { 00206 char buf[3]; 00207 snprintf(buf, sizeof(buf), "%02x", data[i]); 00208 s += buf; 00209 if (i == 3 || i == 5 || i == 7 || i == 9) { 00210 s += "-"; 00211 } 00212 } 00213 return s; 00214 } 00215 bool isFormat(const char* fmt) { 00216 int len = strlen(fmt); 00217 return memcmp(data, fmt, len) == 0; 00218 } 00219 }; 00220 00221 UvcCfg::UvcCfg(int formatIndex, int frameIndex, ControlEp* ctlEp):wMaxPacketSize(0),_ctlEp(ctlEp) 00222 { 00223 TEST_ASSERT(ctlEp); 00224 switch(formatIndex) { 00225 case UVC_MJPEG: _payload = UVC_MJPEG; break; 00226 case UVC_YUY2: _payload = UVC_YUY2; break; 00227 default: _payload = UVC_MJPEG; break; 00228 } 00229 00230 switch(frameIndex) { 00231 case UVC_160x120: _width = 160; _height = 120; break; 00232 case UVC_176x144: _width = 176; _height = 144; break; 00233 case UVC_320x176: _width = 320; _height = 176; break; 00234 case UVC_320x240: _width = 320; _height = 240; break; 00235 case UVC_352x288: _width = 352; _height = 288; break; 00236 case UVC_432x240: _width = 432; _height = 240; break; 00237 case UVC_640x480: _width = 640; _height = 480; break; 00238 case UVC_544x288: _width = 544; _height = 288; break; 00239 case UVC_640x360: _width = 640; _height = 360; break; 00240 case UVC_752x416: _width = 752; _height = 416; break; 00241 case UVC_800x448: _width = 800; _height = 448; break; 00242 case UVC_800x600: _width = 800; _height = 600; break; 00243 default: _width = 160; _height = 120; break; 00244 } 00245 int index = 0; 00246 uint8_t temp[4]; 00247 int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, temp, sizeof(temp)); 00248 TEST_ASSERT(rc == USB_OK); 00249 DBG_BYTES("Config Descriptor 4bytes", temp, sizeof(temp)); 00250 TEST_ASSERT(temp[0] == 9); 00251 TEST_ASSERT(temp[1] == 0x02); 00252 int TotalLength = LE16(temp+2); 00253 DBG("TotalLength: %d\n", TotalLength); 00254 00255 uint8_t* buf = new uint8_t[TotalLength]; 00256 TEST_ASSERT(buf); 00257 rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, TotalLength); 00258 TEST_ASSERT(rc == USB_OK); 00259 if (rc != USB_OK) { 00260 delete[] buf; 00261 return; 00262 } 00263 _parserConfigurationDescriptor(buf, TotalLength); 00264 delete[] buf; 00265 } 00266 00267 void UvcCfg::_parserAudioControl(uint8_t* buf, int len) { 00268 int subtype = buf[2]; 00269 IF_EQ_THEN_PRINTF(AC_HEADER, subtype) 00270 VERBOSE("ADC: %04x\n", LE16(buf+3)); 00271 VERBOSE("TotalLength: %d\n", LE16(buf+5)); 00272 VERBOSE("InCollection: %d\n", buf[7]); 00273 for (int n = 1; n <= buf[7]; n++) { 00274 VERBOSE("aInterfaceNr(%d): %d\n", n, buf[8+n-1]); 00275 } 00276 ENDIF 00277 IF_EQ_THEN_PRINTF(AC_INPUT_TERMINAL, subtype) 00278 VERBOSE("TerminalID: %d\n", buf[3]); 00279 VERBOSE("TerminalType: %04X\n", LE16(buf+4)); 00280 VERBOSE("AssocTermianl: %d\n", buf[6]); 00281 VERBOSE("NrChannels: %d\n", buf[7]); 00282 ENDIF 00283 IF_EQ_THEN_PRINTF(AC_OUTPUT_TERMINAL, subtype) 00284 VERBOSE("TerminalID: %d\n", buf[3]); 00285 VERBOSE("TerminalType: %04X\n", LE16(buf+4)); 00286 VERBOSE("AssocTermianl: %d\n", buf[6]); 00287 ENDIF 00288 IF_EQ_THEN_PRINTF(AC_FEATURE_UNIT, subtype) 00289 VERBOSE("UnitID: %d\n", buf[3]); 00290 VERBOSE("SourceID: %d\n", buf[4]); 00291 VERBOSE("ControlSize: %d\n", buf[5]); 00292 ENDIF 00293 } 00294 00295 #define AS_GENERAL 0x01 00296 #define AS_FORMAT_TYPE 0x02 00297 00298 void UvcCfg::_parserAudioStream(uint8_t* buf, int len) { 00299 int subtype = buf[2]; 00300 IF_EQ_THEN_PRINTF(AS_GENERAL, subtype) 00301 VERBOSE("TerminalLink: %d\n", buf[3]); 00302 VERBOSE("Delay: %d\n", buf[4]); 00303 VERBOSE("FormatTag: %04x\n", LE16(buf+5)); 00304 ENDIF 00305 IF_EQ_THEN_PRINTF(AS_FORMAT_TYPE, subtype) 00306 VERBOSE("FormatType: %d\n", buf[3]); 00307 VERBOSE("NrChannels: %d\n", buf[4]); 00308 VERBOSE("SubFrameSize: %d\n", buf[5]); 00309 VERBOSE("BitResolution: %d\n", buf[6]); 00310 VERBOSE("SamFreqType: %d\n", buf[7]); 00311 VERBOSE("SamFreq(1): %d\n", LE24(buf+8)); 00312 ENDIF 00313 } 00314 00315 #define CC_VIDEO 0x0e 00316 00317 #define SC_VIDEOCONTROL 0x01 00318 #define SC_VIDEOSTREAMING 0x02 00319 00320 #define VC_HEADER 0x01 00321 #define VC_INPUT_TERMINAL 0x02 00322 #define VC_OUTPUT_TERMINAL 0x03 00323 #define VC_SELECTOR_UNIT 0x04 00324 #define VC_PROCESSING_UNIT 0x05 00325 #define VC_EXTENSION_UNIT 0x06 00326 00327 void UvcCfg::_parserVideoControl(uint8_t* buf, int len) { 00328 int subtype = buf[2]; 00329 IF_EQ_THEN_PRINTF(VC_HEADER, subtype) 00330 bcdUVC = LE16(buf+3); 00331 VERBOSE("UVC: %04x\n", bcdUVC); 00332 VERBOSE("TotalLength: %d\n", LE16(buf+5)); 00333 VERBOSE("ClockFrequency: %d\n", LE32(buf+7)); 00334 VERBOSE("InCollection: %d\n", buf[11]); 00335 VERBOSE("aInterfaceNr(1): %d\n", buf[12]); 00336 ENDIF 00337 IF_EQ_THEN_PRINTF(VC_INPUT_TERMINAL, subtype) 00338 VERBOSE("TerminalID: %d\n", buf[3]); 00339 uint16_t tt = LE16(buf+4); 00340 VERBOSE("TerminalType: %04X\n", tt); 00341 VERBOSE("AssocTerminal: %d\n", buf[6]); 00342 VERBOSE("Terminal: %d\n", buf[7]); 00343 if (tt == ITT_CAMERA) { // camera 00344 int bControlSize = buf[14]; 00345 VERBOSE("ControlSize: %d\n", bControlSize); 00346 for(int i = 0; i < bControlSize; i++) { 00347 uint8_t bControls = buf[15+i]; 00348 VERBOSE("Controls(%d): %02X\n", i, bControls); 00349 } 00350 } 00351 ENDIF 00352 IF_EQ_THEN_PRINTF(VC_OUTPUT_TERMINAL, subtype) 00353 VERBOSE("TerminalID: %d\n", buf[3]); 00354 VERBOSE("TerminalType: %04X\n", LE16(buf+4)); 00355 VERBOSE("AssocTerminal: %d\n", buf[6]); 00356 VERBOSE("SourceID: %d\n", buf[7]); 00357 VERBOSE("Terminal: %d\n", buf[8]); 00358 ENDIF 00359 IF_EQ_THEN_PRINTF(VC_SELECTOR_UNIT, subtype) 00360 VERBOSE("UnitID: %d\n", buf[3]); 00361 ENDIF 00362 IF_EQ_THEN_PRINTF(VC_PROCESSING_UNIT, subtype) 00363 VERBOSE("UnitID: %d\n", buf[3]); 00364 VERBOSE("SourceID: %d\n", buf[4]); 00365 VERBOSE("MaxMultiplier: %d\n", LE16(buf+5)); 00366 VERBOSE("ControlSize: %d\n", buf[7]); 00367 int pos = 8; 00368 for (int n = 1; n <= buf[7]; n++) { 00369 VERBOSE("Controls(%d): %02X\n", n , buf[pos]); 00370 pos++; 00371 } 00372 VERBOSE("Processing: %d\n", buf[pos]); 00373 pos++; 00374 VERBOSE("VideoStanders: %02X\n", buf[pos]); 00375 ENDIF 00376 IF_EQ_THEN_PRINTF(VC_EXTENSION_UNIT, subtype) 00377 VERBOSE("UnitID: %d\n", buf[3]); 00378 GUID* guid = reinterpret_cast<GUID*>(buf+4); 00379 string s = guid->to_string(); 00380 VERBOSE("guidExtensionCode: %s\n", s.c_str()); 00381 VERBOSE("NumControls: %d\n", buf[20]); 00382 int p = buf[21]; 00383 VERBOSE("NrInPins: %d\n", p); 00384 int pos = 22; 00385 for (int n = 1; n <= p; n++) { 00386 VERBOSE("SourceID(%d): %d\n", n, buf[pos]); 00387 pos++; 00388 } 00389 int bControlSize = buf[pos]; 00390 pos++; 00391 VERBOSE("ControlSize: %d\n", bControlSize); 00392 pos++; 00393 for(int i = 0; i < bControlSize; i++) { 00394 VERBOSE("Control(%d): %02X\n", i, buf[pos]); 00395 pos++; 00396 } 00397 VERBOSE("iExtension: %d\n", buf[pos]); 00398 ENDIF 00399 } 00400 00401 #define VS_INPUT_HEADER 0x01 00402 #define VS_STILL_FRAME 0x03 00403 #define VS_FORMAT_UNCOMPRESSED 0x04 00404 #define VS_FRAME_UNCOMPRESSED 0x05 00405 #define VS_FORMAT_MJPEG 0x06 00406 #define VS_FRAME_MJPEG 0x07 00407 #define VS_COLOR_FORMAT 0x0d 00408 00409 void UvcCfg::_parserVideoStream(uint8_t* buf, int len) { 00410 int subtype = buf[2]; 00411 IF_EQ_THEN_PRINTF(VS_INPUT_HEADER, subtype) 00412 VERBOSE("NumFormats: %d\n", buf[3]); 00413 VERBOSE("TotalLength: %d\n", LE16(buf+4)); 00414 VERBOSE("EndpointAddress: %02X\n", buf[6]); 00415 VERBOSE("Info: %02X\n", buf[7]); 00416 VERBOSE("TerminalLink: %d\n", buf[8]); 00417 VERBOSE("StillCaptureMethod: %d\n", buf[9]); 00418 VERBOSE("TriggerSupport: %d\n", buf[10]); 00419 VERBOSE("TriggerUsage: %d\n", buf[11]); 00420 VERBOSE("ControlSize: %d\n", buf[12]); 00421 int pos = 13; 00422 for (int n = 1; n <= buf[12]; n++) { 00423 VERBOSE("Controls(%d): %02X\n", n, buf[pos]); 00424 pos++; 00425 } 00426 bEndpointAddress = buf[6]; 00427 ENDIF 00428 IF_EQ_THEN_PRINTF(VS_STILL_FRAME, subtype) 00429 VERBOSE("EndpointAdress: %02X\n", buf[3]); 00430 VERBOSE("NumImageSizePatterns: %d\n", buf[4]); 00431 int ptn = buf[4]; 00432 int pos = 5; 00433 for (int n = 1; n <= ptn; n++) { 00434 VERBOSE("Width(%d): %d\n", n, LE16(buf+pos)); 00435 VERBOSE("Height(%d): %d\n", n, LE16(buf+pos+2)); 00436 pos += 4; 00437 } 00438 VERBOSE("NumCompressPtn: %d\n", buf[pos]); 00439 ptn = buf[pos++]; 00440 for (int n = 1; n <= ptn; n++) { 00441 VERBOSE("Compress(%d): %d\n", n, buf[pos]); 00442 pos++; 00443 } 00444 ENDIF 00445 IF_EQ_THEN_PRINTF(VS_FORMAT_UNCOMPRESSED, subtype) 00446 VERBOSE("FormatIndex: %d\n", buf[3]); 00447 VERBOSE("NumFrameDescriptors: %d\n", buf[4]); 00448 GUID* guid = reinterpret_cast<GUID*>(buf+5); 00449 string s = guid->to_string(); 00450 if (guid->isFormat("YUY2")) { 00451 VERBOSE("GUID: %s YUY2\n", s.c_str()); 00452 } else if (guid->isFormat("NV12")) { 00453 VERBOSE("GUID: %s NV12\n", s.c_str()); 00454 } else { 00455 VERBOSE("GUID: %s\n", s.c_str()); 00456 } 00457 VERBOSE("DefaultFrameIndex: %d\n", buf[22]); 00458 if (_payload == UVC_YUY2) { 00459 FormatIndex = buf[3]; 00460 } 00461 ENDIF 00462 IF_EQ_THEN_PRINTF(VS_FRAME_UNCOMPRESSED, subtype) 00463 VERBOSE("FrameIndex: %d\n", buf[3]); 00464 VERBOSE("Capabilites: %d\n", buf[4]); 00465 VERBOSE("Width: %d\n", LE16(buf+5)); 00466 VERBOSE("Height: %d\n", LE16(buf+7)); 00467 VERBOSE("MinBitRate: %d\n", LE32(buf+9)); 00468 VERBOSE("MaxBitRate: %d\n", LE32(buf+13)); 00469 VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17)); 00470 VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21)); 00471 VERBOSE("FrameIntervalType: %d\n", buf[25]); 00472 int it = buf[25]; 00473 uint32_t max_fi = 333333; // 30.0fps 00474 if (it == 0) { 00475 VERBOSE("FrameMinInterval: %d\n", buf[26]); 00476 VERBOSE("FrameMaxInterval: %d\n", buf[30]); 00477 VERBOSE("FrameIntervalStep: %d\n", buf[34]); 00478 } else { 00479 int pos = 26; 00480 for (int n = 1; n <= it; n++) { 00481 uint32_t fi = LE32(buf+pos); 00482 if (fi >= max_fi) { 00483 max_fi = fi; 00484 } 00485 float fps = 1e+7 / fi; 00486 VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps); 00487 pos += 4; 00488 } 00489 } 00490 if (_payload == UVC_YUY2) { 00491 if (_width == LE16(buf+5) && _height == LE16(buf+7)) { 00492 FrameIndex = buf[3]; 00493 } 00494 if (dwFrameInterval == 0) { 00495 dwFrameInterval = max_fi; 00496 } 00497 } 00498 ENDIF 00499 IF_EQ_THEN_PRINTF(VS_FORMAT_MJPEG, subtype) 00500 VERBOSE("FormatIndex: %d\n", buf[3]); 00501 VERBOSE("NumFrameDescriptors: %d\n", buf[4]); 00502 VERBOSE("Flags: %d\n", buf[5]); 00503 VERBOSE("DefaultFrameIndex: %d\n", buf[6]); 00504 if (_payload == UVC_MJPEG) { 00505 FormatIndex = buf[3]; 00506 } 00507 ENDIF 00508 IF_EQ_THEN_PRINTF(VS_FRAME_MJPEG, subtype) 00509 VERBOSE("FrameIndex: %d\n", buf[3]); 00510 VERBOSE("Capabilites: %d\n", buf[4]); 00511 VERBOSE("Width: %d\n", LE16(buf+5)); 00512 VERBOSE("Height: %d\n", LE16(buf+7)); 00513 VERBOSE("MinBitRate: %d\n", LE32(buf+9)); 00514 VERBOSE("MaxBitRate: %d\n", LE32(buf+13)); 00515 VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17)); 00516 VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21)); 00517 VERBOSE("FrameIntervalType: %d\n", buf[25]); 00518 int it = buf[25]; 00519 uint32_t max_fi = 333333; // 30.0fps 00520 if (it == 0) { 00521 VERBOSE("FrameMinInterval: %d\n", buf[26]); 00522 VERBOSE("FrameMaxInterval: %d\n", buf[30]); 00523 VERBOSE("FrameIntervalStep: %d\n", buf[34]); 00524 } else { 00525 int pos = 26; 00526 for (int n = 1; n <= it; n++) { 00527 uint32_t fi = LE32(buf+pos); 00528 if (fi >= max_fi) { 00529 max_fi = fi; 00530 } 00531 float fps = 1e+7 / fi; 00532 VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps); 00533 pos += 4; 00534 } 00535 } 00536 if (_payload == UVC_MJPEG) { 00537 if (_width == LE16(buf+5) && _height == LE16(buf+7)) { 00538 FrameIndex = buf[3]; 00539 } 00540 if (dwFrameInterval == 0) { 00541 dwFrameInterval = max_fi; 00542 } 00543 } 00544 ENDIF 00545 IF_EQ_THEN_PRINTF(VS_COLOR_FORMAT, subtype) 00546 ENDIF 00547 } 00548 00549 void UvcCfg::_parserConfigurationDescriptor(uint8_t* buf, int len) { 00550 int pos = 0; 00551 _IfClass = 0; 00552 _IfSubClass = 0; 00553 while (pos < len) { 00554 int type = buf[pos+1]; 00555 //DBG_BYTES(TYPE_Str(type), buf+pos, buf[pos]); 00556 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CONFIGURATION, type) 00557 VERBOSE("NumInterfaces: %d\n", buf[pos+4]); 00558 ENDIF 00559 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, type) 00560 VERBOSE("FirstInterface: %d\n", buf[pos+2]); 00561 VERBOSE("InterfaceCount: %d\n", buf[pos+3]); 00562 VERBOSE("FunctionClass: %02X\n", buf[pos+4]); 00563 VERBOSE("FunctionSubClass: %02X\n", buf[pos+5]); 00564 VERBOSE("FunctionProtocol: %02X\n", buf[pos+6]); 00565 VERBOSE("Function: %d\n", buf[pos+7]); 00566 ENDIF 00567 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE,type) 00568 VERBOSE("InterfaceNumber: %d\n", buf[pos+2]); 00569 VERBOSE("AlternateSetting: %d\n", buf[pos+3]); 00570 VERBOSE("NumEndpoint: %d\n", buf[pos+4]); 00571 VERBOSE("InterfaceClass: %02X\n", buf[pos+5]); 00572 VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]); 00573 VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]); 00574 VERBOSE("Interface: %d\n", buf[pos+8]); 00575 _If = buf[pos+2]; 00576 _Ifalt = buf[pos+3]; 00577 _IfClass = buf[pos+5]; 00578 _IfSubClass = buf[pos+6]; 00579 ENDIF 00580 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_ENDPOINT, type) 00581 VERBOSE("EndpointAddress: %02X\n", buf[pos+2]); 00582 VERBOSE("Attributes: %02X\n", buf[pos+3]); 00583 VERBOSE("MaxPacketSize: %d\n", LE16(buf+pos+4)); 00584 VERBOSE("Interval: %d\n", buf[pos+6]); 00585 if (_IfClass == CC_VIDEO && _IfSubClass == SC_VIDEOSTREAMING) { 00586 if (bEndpointAddress == buf[pos+2]) { 00587 if (wMaxPacketSize == 0) { 00588 wMaxPacketSize = LE16(buf+pos+4); 00589 } 00590 if (wMaxPacketSize == LE16(buf+pos+4)) { 00591 bInterface = _If; 00592 bAlternate = _Ifalt; 00593 } 00594 } 00595 } 00596 ENDIF 00597 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CS_INTERFACE, type) 00598 IF_EQ_THEN_PRINTF(CC_VIDEO, _IfClass) 00599 IF_EQ_THEN_PRINTF(SC_VIDEOCONTROL, _IfSubClass) 00600 _parserVideoControl(buf+pos, buf[pos]); 00601 ENDIF 00602 IF_EQ_THEN_PRINTF(SC_VIDEOSTREAMING, _IfSubClass) 00603 _parserVideoStream(buf+pos, buf[pos]); 00604 ENDIF 00605 ENDIF 00606 IF_EQ_THEN_PRINTF(CC_AUDIO, _IfClass) 00607 IF_EQ_THEN_PRINTF(SC_AUDIOCONTROL, _IfSubClass) 00608 _parserAudioControl(buf+pos, buf[pos]); 00609 ENDIF 00610 IF_EQ_THEN_PRINTF(SC_AUDIOSTREAMING, _IfSubClass) 00611 _parserAudioStream(buf+pos, buf[pos]); 00612 ENDIF 00613 ENDIF 00614 ENDIF 00615 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_HUB, type) 00616 ENDIF 00617 pos += buf[pos]; 00618 } 00619 } 00620
Generated on Wed Jul 13 2022 06:43:34 by 1.7.2