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