video streaming using websocket. but,streaming is very slower than 0.1fps.

Dependencies:   BaseUsbHost EthernetInterface WebSocketClient mbed-rtos mbed

Fork of BaseUsbHost_example by Norimasa Okamoto

viewer

Committer:
va009039
Date:
Tue Feb 19 15:50:06 2013 +0000
Revision:
7:5dc595bbff58
video streaming using websocket

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 7:5dc595bbff58 1 // UvcCam.cpp 2013/2/11
va009039 7:5dc595bbff58 2 #include "mbed.h"
va009039 7:5dc595bbff58 3 #include "rtos.h"
va009039 7:5dc595bbff58 4 #include "BaseUsbHost.h"
va009039 7:5dc595bbff58 5 //#define DEBUG
va009039 7:5dc595bbff58 6 #include "BaseUsbHostDebug.h"
va009039 7:5dc595bbff58 7 #define TEST
va009039 7:5dc595bbff58 8 #include "BaseUsbHostTest.h"
va009039 7:5dc595bbff58 9 #include "UvcCam.h"
va009039 7:5dc595bbff58 10 #include <string>
va009039 7:5dc595bbff58 11
va009039 7:5dc595bbff58 12 UvcCam::UvcCam(int formatIndex, int frameIndex, uint32_t interval, ControlEp* ctlEp)
va009039 7:5dc595bbff58 13 {
va009039 7:5dc595bbff58 14 uint8_t buf[34];
va009039 7:5dc595bbff58 15 int rc;
va009039 7:5dc595bbff58 16 int alt;
va009039 7:5dc595bbff58 17 int cfg2;
va009039 7:5dc595bbff58 18
va009039 7:5dc595bbff58 19 if (ctlEp == NULL) { // root hub
va009039 7:5dc595bbff58 20 DBG_OHCI(LPC_USB->HcRhPortStatus1);
va009039 7:5dc595bbff58 21 TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
va009039 7:5dc595bbff58 22 ctlEp = new ControlEp();
va009039 7:5dc595bbff58 23 TEST_ASSERT_TRUE(ctlEp);
va009039 7:5dc595bbff58 24 }
va009039 7:5dc595bbff58 25 bool r = check(ctlEp);
va009039 7:5dc595bbff58 26 TEST_ASSERT(r);
va009039 7:5dc595bbff58 27 m_ctlEp = ctlEp;
va009039 7:5dc595bbff58 28
va009039 7:5dc595bbff58 29 rc = ctlEp->GetDescriptor(1, 0, buf, sizeof(StandardDeviceDescriptor));
va009039 7:5dc595bbff58 30 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 31 StandardDeviceDescriptor* sd = reinterpret_cast<StandardDeviceDescriptor*>(buf);
va009039 7:5dc595bbff58 32 VERBOSE("vid: %04x\n", sd->idVendor);
va009039 7:5dc595bbff58 33 VERBOSE("pid: %04x\n", sd->idProduct);
va009039 7:5dc595bbff58 34 string s = ctlEp->GetStringDescriptor(sd->iManufacturer);
va009039 7:5dc595bbff58 35 VERBOSE("iManufacturer: %s\n", s.c_str());
va009039 7:5dc595bbff58 36 s = ctlEp->GetStringDescriptor(sd->iProduct);
va009039 7:5dc595bbff58 37 VERBOSE("iProduct: %s\n", s.c_str());
va009039 7:5dc595bbff58 38 vid = sd->idVendor;
va009039 7:5dc595bbff58 39 pid = sd->idProduct;
va009039 7:5dc595bbff58 40
va009039 7:5dc595bbff58 41 UvcCfg* cfg = new UvcCfg(formatIndex, frameIndex, ctlEp);
va009039 7:5dc595bbff58 42 TEST_ASSERT(cfg);
va009039 7:5dc595bbff58 43
va009039 7:5dc595bbff58 44 int param_len = 34;
va009039 7:5dc595bbff58 45 TEST_ASSERT(cfg->bcdUVC >= 0x0100);
va009039 7:5dc595bbff58 46 if (cfg->bcdUVC == 0x0100) { // UVC ver. 1.0
va009039 7:5dc595bbff58 47 param_len = 26;
va009039 7:5dc595bbff58 48 }
va009039 7:5dc595bbff58 49
va009039 7:5dc595bbff58 50 int addr = m_ctlEp->GetAddr();
va009039 7:5dc595bbff58 51 m_isoEp = new IsochronousEp(addr, cfg->bEndpointAddress, cfg->wMaxPacketSize);
va009039 7:5dc595bbff58 52 TEST_ASSERT_TRUE(m_isoEp);
va009039 7:5dc595bbff58 53
va009039 7:5dc595bbff58 54 //#define USE_PROBE
va009039 7:5dc595bbff58 55
va009039 7:5dc595bbff58 56 #ifdef USE_PROBE
va009039 7:5dc595bbff58 57 rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1);
va009039 7:5dc595bbff58 58 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 59 DBG_BYTES("GET_INFO Prob", buf, 1);
va009039 7:5dc595bbff58 60
va009039 7:5dc595bbff58 61 rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, param_len);
va009039 7:5dc595bbff58 62 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 63 DBG_BYTES("GET_DEF Probe", buf, param_len);
va009039 7:5dc595bbff58 64
va009039 7:5dc595bbff58 65 rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, param_len);
va009039 7:5dc595bbff58 66 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 67 DBG_BYTES("GET_MIN Probe", buf, param_len);
va009039 7:5dc595bbff58 68
va009039 7:5dc595bbff58 69 rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, param_len);
va009039 7:5dc595bbff58 70 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 71 DBG_BYTES("GET_MAX Probe", buf, param_len);
va009039 7:5dc595bbff58 72
va009039 7:5dc595bbff58 73 rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, param_len);
va009039 7:5dc595bbff58 74 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 75 DBG_BYTES("GET_CUR Probe", buf, param_len);
va009039 7:5dc595bbff58 76 #endif // USE_PROBE
va009039 7:5dc595bbff58 77
va009039 7:5dc595bbff58 78 rc = Control(GET_INFO, VS_COMMIT_CONTROL, 1, buf, 1);
va009039 7:5dc595bbff58 79 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 80 DBG_BYTES("GET_INFO Commit", buf, 1);
va009039 7:5dc595bbff58 81
va009039 7:5dc595bbff58 82 memset(buf, 0, param_len);
va009039 7:5dc595bbff58 83 buf[2] = cfg->FormatIndex;
va009039 7:5dc595bbff58 84 buf[3] = cfg->FrameIndex;
va009039 7:5dc595bbff58 85 *reinterpret_cast<uint32_t*>(buf+4) = interval;
va009039 7:5dc595bbff58 86
va009039 7:5dc595bbff58 87 DBG_BYTES("SET_CUR Commit", buf, param_len);
va009039 7:5dc595bbff58 88 rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len);
va009039 7:5dc595bbff58 89 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 90
va009039 7:5dc595bbff58 91 rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len);
va009039 7:5dc595bbff58 92 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 93 TEST_ASSERT_EQUAL(buf[2], cfg->FormatIndex);
va009039 7:5dc595bbff58 94 TEST_ASSERT_EQUAL(buf[3], cfg->FrameIndex);
va009039 7:5dc595bbff58 95 TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval);
va009039 7:5dc595bbff58 96 DBG_BYTES("GET_CUR Commit", buf, param_len);
va009039 7:5dc595bbff58 97
va009039 7:5dc595bbff58 98 rc = m_ctlEp->GetConfiguration(&cfg2);
va009039 7:5dc595bbff58 99 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 7:5dc595bbff58 100 DBG("config: %d\n", cfg2);
va009039 7:5dc595bbff58 101
va009039 7:5dc595bbff58 102 rc = m_ctlEp->SetConfiguration(1);
va009039 7:5dc595bbff58 103 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 7:5dc595bbff58 104
va009039 7:5dc595bbff58 105 rc = m_ctlEp->GetConfiguration(&cfg2);
va009039 7:5dc595bbff58 106 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 7:5dc595bbff58 107 DBG("config: %d\n", cfg2);
va009039 7:5dc595bbff58 108 TEST_ASSERT_EQUAL(cfg2, 1);
va009039 7:5dc595bbff58 109
va009039 7:5dc595bbff58 110 rc = m_ctlEp->GetInterface(cfg->bInterface, &alt);
va009039 7:5dc595bbff58 111 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 7:5dc595bbff58 112 DBG("alt: %d\n", alt);
va009039 7:5dc595bbff58 113
va009039 7:5dc595bbff58 114 rc = m_ctlEp->SetInterfaceAlternate(cfg->bInterface, cfg->bAlternate);
va009039 7:5dc595bbff58 115 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 7:5dc595bbff58 116
va009039 7:5dc595bbff58 117 rc = m_ctlEp->GetInterface(cfg->bInterface, &alt);
va009039 7:5dc595bbff58 118 TEST_ASSERT_EQUAL(rc, USB_OK);
va009039 7:5dc595bbff58 119 DBG("alt: %d\n", alt);
va009039 7:5dc595bbff58 120 TEST_ASSERT_EQUAL(alt, cfg->bAlternate);
va009039 7:5dc595bbff58 121 delete cfg;
va009039 7:5dc595bbff58 122
va009039 7:5dc595bbff58 123 for(int i = 0; i < 16; i++) {
va009039 7:5dc595bbff58 124 report_cc_count[i] = 0;
va009039 7:5dc595bbff58 125 report_ps_cc_count[i] = 0;
va009039 7:5dc595bbff58 126 }
va009039 7:5dc595bbff58 127
va009039 7:5dc595bbff58 128 LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable
va009039 7:5dc595bbff58 129 LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable
va009039 7:5dc595bbff58 130 }
va009039 7:5dc595bbff58 131
va009039 7:5dc595bbff58 132 bool UvcCam::check(ControlEp* ctlEp)
va009039 7:5dc595bbff58 133 {
va009039 7:5dc595bbff58 134 if (ctlEp == NULL) {
va009039 7:5dc595bbff58 135 return false;
va009039 7:5dc595bbff58 136 }
va009039 7:5dc595bbff58 137 uint8_t buf[18];
va009039 7:5dc595bbff58 138 int r = ctlEp->GetDescriptor(1, 0, buf, 8);
va009039 7:5dc595bbff58 139 if (r != USB_OK) {
va009039 7:5dc595bbff58 140 return false;
va009039 7:5dc595bbff58 141 }
va009039 7:5dc595bbff58 142 DBG_HEX(buf, 8);
va009039 7:5dc595bbff58 143 const uint8_t desc[] = {0x12,0x01,0x00,0x02,0xef,0x02,0x01};
va009039 7:5dc595bbff58 144 if (memcmp(buf, desc, sizeof(desc)) != 0) {
va009039 7:5dc595bbff58 145 return false;
va009039 7:5dc595bbff58 146 }
va009039 7:5dc595bbff58 147 r = ctlEp->GetDescriptor(1, 0, buf, sizeof(buf));
va009039 7:5dc595bbff58 148 if (r != USB_OK) {
va009039 7:5dc595bbff58 149 return false;
va009039 7:5dc595bbff58 150 }
va009039 7:5dc595bbff58 151 DBG_HEX(buf, 18);
va009039 7:5dc595bbff58 152 return true;
va009039 7:5dc595bbff58 153 }
va009039 7:5dc595bbff58 154
va009039 7:5dc595bbff58 155 #define DESCRIPTOR_TYPE_DEVICE 1
va009039 7:5dc595bbff58 156 #define DESCRIPTOR_TYPE_CONFIGURATION 2
va009039 7:5dc595bbff58 157 #define DESCRIPTOR_TYPE_STRING 3
va009039 7:5dc595bbff58 158 #define DESCRIPTOR_TYPE_INTERFACE 4
va009039 7:5dc595bbff58 159 #define DESCRIPTOR_TYPE_ENDPOINT 5
va009039 7:5dc595bbff58 160
va009039 7:5dc595bbff58 161 #define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0b
va009039 7:5dc595bbff58 162
va009039 7:5dc595bbff58 163 #define DESCRIPTOR_TYPE_HID 0x21
va009039 7:5dc595bbff58 164 #define DESCRIPTOR_TYPE_REPORT 0x22
va009039 7:5dc595bbff58 165 #define DESCRIPTOR_TYPE_PHYSICAL 0x23
va009039 7:5dc595bbff58 166 #define DESCRIPTOR_TYPE_CS_INTERFACE 0x24
va009039 7:5dc595bbff58 167 #define DESCRIPTOR_TYPE_CS_ENDPOINT 0x25
va009039 7:5dc595bbff58 168 #define DESCRIPTOR_TYPE_HUB 0x29
va009039 7:5dc595bbff58 169
va009039 7:5dc595bbff58 170 #define CLASS_AUDIO 0x02
va009039 7:5dc595bbff58 171 #define CLASS_HUB 0x09
va009039 7:5dc595bbff58 172
va009039 7:5dc595bbff58 173 #define IF_EQ_THEN_PRINTF(A,B) if (A == B) {VERBOSE("%s\n", #A);
va009039 7:5dc595bbff58 174 #define ENDIF }
va009039 7:5dc595bbff58 175
va009039 7:5dc595bbff58 176 #define CC_AUDIO 0x01
va009039 7:5dc595bbff58 177 #define SC_AUDIOCONTROL 0x01
va009039 7:5dc595bbff58 178 #define SC_AUDIOSTREAMING 0x02
va009039 7:5dc595bbff58 179
va009039 7:5dc595bbff58 180 #define AC_HEADER 0x01
va009039 7:5dc595bbff58 181 #define AC_INPUT_TERMINAL 0x02
va009039 7:5dc595bbff58 182 #define AC_OUTPUT_TERMINAL 0x03
va009039 7:5dc595bbff58 183 #define AC_FEATURE_UNIT 0x06
va009039 7:5dc595bbff58 184
va009039 7:5dc595bbff58 185 // Input Terminal Types
va009039 7:5dc595bbff58 186 #define ITT_CAMERA 0x0201
va009039 7:5dc595bbff58 187
va009039 7:5dc595bbff58 188 static int LE16(const uint8_t* d)
va009039 7:5dc595bbff58 189 {
va009039 7:5dc595bbff58 190 return d[0] | (d[1] << 8);
va009039 7:5dc595bbff58 191 }
va009039 7:5dc595bbff58 192
va009039 7:5dc595bbff58 193 static int LE24(const uint8_t* d) {
va009039 7:5dc595bbff58 194 return d[0] | (d[1]<<8) | (d[2] << 16);
va009039 7:5dc595bbff58 195 }
va009039 7:5dc595bbff58 196
va009039 7:5dc595bbff58 197 static int LE32(const uint8_t* d) {
va009039 7:5dc595bbff58 198 return d[0] |(d[1]<<8) | (d[2] << 16) |(d[3] << 24) ;
va009039 7:5dc595bbff58 199 }
va009039 7:5dc595bbff58 200
va009039 7:5dc595bbff58 201 struct GUID {
va009039 7:5dc595bbff58 202 uint8_t data[16];
va009039 7:5dc595bbff58 203 string to_string() {
va009039 7:5dc595bbff58 204 string s;
va009039 7:5dc595bbff58 205 for(int i = 0; i < 16; i++) {
va009039 7:5dc595bbff58 206 char buf[3];
va009039 7:5dc595bbff58 207 snprintf(buf, sizeof(buf), "%02x", data[i]);
va009039 7:5dc595bbff58 208 s += buf;
va009039 7:5dc595bbff58 209 if (i == 3 || i == 5 || i == 7 || i == 9) {
va009039 7:5dc595bbff58 210 s += "-";
va009039 7:5dc595bbff58 211 }
va009039 7:5dc595bbff58 212 }
va009039 7:5dc595bbff58 213 return s;
va009039 7:5dc595bbff58 214 }
va009039 7:5dc595bbff58 215 bool isFormat(const char* fmt) {
va009039 7:5dc595bbff58 216 int len = strlen(fmt);
va009039 7:5dc595bbff58 217 return memcmp(data, fmt, len) == 0;
va009039 7:5dc595bbff58 218 }
va009039 7:5dc595bbff58 219 };
va009039 7:5dc595bbff58 220
va009039 7:5dc595bbff58 221 UvcCfg::UvcCfg(int formatIndex, int frameIndex, ControlEp* ctlEp):wMaxPacketSize(0),_ctlEp(ctlEp)
va009039 7:5dc595bbff58 222 {
va009039 7:5dc595bbff58 223 TEST_ASSERT(ctlEp);
va009039 7:5dc595bbff58 224 switch(formatIndex) {
va009039 7:5dc595bbff58 225 case UVC_MJPEG: _payload = UVC_MJPEG; break;
va009039 7:5dc595bbff58 226 case UVC_YUY2: _payload = UVC_YUY2; break;
va009039 7:5dc595bbff58 227 default: _payload = UVC_MJPEG; break;
va009039 7:5dc595bbff58 228 }
va009039 7:5dc595bbff58 229
va009039 7:5dc595bbff58 230 switch(frameIndex) {
va009039 7:5dc595bbff58 231 case UVC_160x120: _width = 160; _height = 120; break;
va009039 7:5dc595bbff58 232 case UVC_176x144: _width = 176; _height = 144; break;
va009039 7:5dc595bbff58 233 case UVC_320x176: _width = 320; _height = 176; break;
va009039 7:5dc595bbff58 234 case UVC_320x240: _width = 320; _height = 240; break;
va009039 7:5dc595bbff58 235 case UVC_352x288: _width = 352; _height = 288; break;
va009039 7:5dc595bbff58 236 case UVC_432x240: _width = 432; _height = 240; break;
va009039 7:5dc595bbff58 237 case UVC_640x480: _width = 640; _height = 480; break;
va009039 7:5dc595bbff58 238 case UVC_544x288: _width = 544; _height = 288; break;
va009039 7:5dc595bbff58 239 case UVC_640x360: _width = 640; _height = 360; break;
va009039 7:5dc595bbff58 240 case UVC_752x416: _width = 752; _height = 416; break;
va009039 7:5dc595bbff58 241 case UVC_800x448: _width = 800; _height = 448; break;
va009039 7:5dc595bbff58 242 case UVC_800x600: _width = 800; _height = 600; break;
va009039 7:5dc595bbff58 243 default: _width = 160; _height = 120; break;
va009039 7:5dc595bbff58 244 }
va009039 7:5dc595bbff58 245 int index = 0;
va009039 7:5dc595bbff58 246 uint8_t temp[4];
va009039 7:5dc595bbff58 247 int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, temp, sizeof(temp));
va009039 7:5dc595bbff58 248 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 249 DBG_BYTES("Config Descriptor 4bytes", temp, sizeof(temp));
va009039 7:5dc595bbff58 250 TEST_ASSERT(temp[0] == 9);
va009039 7:5dc595bbff58 251 TEST_ASSERT(temp[1] == 0x02);
va009039 7:5dc595bbff58 252 int TotalLength = LE16(temp+2);
va009039 7:5dc595bbff58 253 DBG("TotalLength: %d\n", TotalLength);
va009039 7:5dc595bbff58 254
va009039 7:5dc595bbff58 255 uint8_t* buf = new uint8_t[TotalLength];
va009039 7:5dc595bbff58 256 TEST_ASSERT(buf);
va009039 7:5dc595bbff58 257 rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, TotalLength);
va009039 7:5dc595bbff58 258 TEST_ASSERT(rc == USB_OK);
va009039 7:5dc595bbff58 259 if (rc != USB_OK) {
va009039 7:5dc595bbff58 260 delete[] buf;
va009039 7:5dc595bbff58 261 return;
va009039 7:5dc595bbff58 262 }
va009039 7:5dc595bbff58 263 _parserConfigurationDescriptor(buf, TotalLength);
va009039 7:5dc595bbff58 264 delete[] buf;
va009039 7:5dc595bbff58 265 }
va009039 7:5dc595bbff58 266
va009039 7:5dc595bbff58 267 void UvcCfg::_parserAudioControl(uint8_t* buf, int len) {
va009039 7:5dc595bbff58 268 int subtype = buf[2];
va009039 7:5dc595bbff58 269 IF_EQ_THEN_PRINTF(AC_HEADER, subtype)
va009039 7:5dc595bbff58 270 VERBOSE("ADC: %04x\n", LE16(buf+3));
va009039 7:5dc595bbff58 271 VERBOSE("TotalLength: %d\n", LE16(buf+5));
va009039 7:5dc595bbff58 272 VERBOSE("InCollection: %d\n", buf[7]);
va009039 7:5dc595bbff58 273 for (int n = 1; n <= buf[7]; n++) {
va009039 7:5dc595bbff58 274 VERBOSE("aInterfaceNr(%d): %d\n", n, buf[8+n-1]);
va009039 7:5dc595bbff58 275 }
va009039 7:5dc595bbff58 276 ENDIF
va009039 7:5dc595bbff58 277 IF_EQ_THEN_PRINTF(AC_INPUT_TERMINAL, subtype)
va009039 7:5dc595bbff58 278 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 7:5dc595bbff58 279 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 7:5dc595bbff58 280 VERBOSE("AssocTermianl: %d\n", buf[6]);
va009039 7:5dc595bbff58 281 VERBOSE("NrChannels: %d\n", buf[7]);
va009039 7:5dc595bbff58 282 ENDIF
va009039 7:5dc595bbff58 283 IF_EQ_THEN_PRINTF(AC_OUTPUT_TERMINAL, subtype)
va009039 7:5dc595bbff58 284 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 7:5dc595bbff58 285 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 7:5dc595bbff58 286 VERBOSE("AssocTermianl: %d\n", buf[6]);
va009039 7:5dc595bbff58 287 ENDIF
va009039 7:5dc595bbff58 288 IF_EQ_THEN_PRINTF(AC_FEATURE_UNIT, subtype)
va009039 7:5dc595bbff58 289 VERBOSE("UnitID: %d\n", buf[3]);
va009039 7:5dc595bbff58 290 VERBOSE("SourceID: %d\n", buf[4]);
va009039 7:5dc595bbff58 291 VERBOSE("ControlSize: %d\n", buf[5]);
va009039 7:5dc595bbff58 292 ENDIF
va009039 7:5dc595bbff58 293 }
va009039 7:5dc595bbff58 294
va009039 7:5dc595bbff58 295 #define AS_GENERAL 0x01
va009039 7:5dc595bbff58 296 #define AS_FORMAT_TYPE 0x02
va009039 7:5dc595bbff58 297
va009039 7:5dc595bbff58 298 void UvcCfg::_parserAudioStream(uint8_t* buf, int len) {
va009039 7:5dc595bbff58 299 int subtype = buf[2];
va009039 7:5dc595bbff58 300 IF_EQ_THEN_PRINTF(AS_GENERAL, subtype)
va009039 7:5dc595bbff58 301 VERBOSE("TerminalLink: %d\n", buf[3]);
va009039 7:5dc595bbff58 302 VERBOSE("Delay: %d\n", buf[4]);
va009039 7:5dc595bbff58 303 VERBOSE("FormatTag: %04x\n", LE16(buf+5));
va009039 7:5dc595bbff58 304 ENDIF
va009039 7:5dc595bbff58 305 IF_EQ_THEN_PRINTF(AS_FORMAT_TYPE, subtype)
va009039 7:5dc595bbff58 306 VERBOSE("FormatType: %d\n", buf[3]);
va009039 7:5dc595bbff58 307 VERBOSE("NrChannels: %d\n", buf[4]);
va009039 7:5dc595bbff58 308 VERBOSE("SubFrameSize: %d\n", buf[5]);
va009039 7:5dc595bbff58 309 VERBOSE("BitResolution: %d\n", buf[6]);
va009039 7:5dc595bbff58 310 VERBOSE("SamFreqType: %d\n", buf[7]);
va009039 7:5dc595bbff58 311 VERBOSE("SamFreq(1): %d\n", LE24(buf+8));
va009039 7:5dc595bbff58 312 ENDIF
va009039 7:5dc595bbff58 313 }
va009039 7:5dc595bbff58 314
va009039 7:5dc595bbff58 315 #define CC_VIDEO 0x0e
va009039 7:5dc595bbff58 316
va009039 7:5dc595bbff58 317 #define SC_VIDEOCONTROL 0x01
va009039 7:5dc595bbff58 318 #define SC_VIDEOSTREAMING 0x02
va009039 7:5dc595bbff58 319
va009039 7:5dc595bbff58 320 #define VC_HEADER 0x01
va009039 7:5dc595bbff58 321 #define VC_INPUT_TERMINAL 0x02
va009039 7:5dc595bbff58 322 #define VC_OUTPUT_TERMINAL 0x03
va009039 7:5dc595bbff58 323 #define VC_SELECTOR_UNIT 0x04
va009039 7:5dc595bbff58 324 #define VC_PROCESSING_UNIT 0x05
va009039 7:5dc595bbff58 325 #define VC_EXTENSION_UNIT 0x06
va009039 7:5dc595bbff58 326
va009039 7:5dc595bbff58 327 void UvcCfg::_parserVideoControl(uint8_t* buf, int len) {
va009039 7:5dc595bbff58 328 int subtype = buf[2];
va009039 7:5dc595bbff58 329 IF_EQ_THEN_PRINTF(VC_HEADER, subtype)
va009039 7:5dc595bbff58 330 bcdUVC = LE16(buf+3);
va009039 7:5dc595bbff58 331 VERBOSE("UVC: %04x\n", bcdUVC);
va009039 7:5dc595bbff58 332 VERBOSE("TotalLength: %d\n", LE16(buf+5));
va009039 7:5dc595bbff58 333 VERBOSE("ClockFrequency: %d\n", LE32(buf+7));
va009039 7:5dc595bbff58 334 VERBOSE("InCollection: %d\n", buf[11]);
va009039 7:5dc595bbff58 335 VERBOSE("aInterfaceNr(1): %d\n", buf[12]);
va009039 7:5dc595bbff58 336 ENDIF
va009039 7:5dc595bbff58 337 IF_EQ_THEN_PRINTF(VC_INPUT_TERMINAL, subtype)
va009039 7:5dc595bbff58 338 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 7:5dc595bbff58 339 uint16_t tt = LE16(buf+4);
va009039 7:5dc595bbff58 340 VERBOSE("TerminalType: %04X\n", tt);
va009039 7:5dc595bbff58 341 VERBOSE("AssocTerminal: %d\n", buf[6]);
va009039 7:5dc595bbff58 342 VERBOSE("Terminal: %d\n", buf[7]);
va009039 7:5dc595bbff58 343 if (tt == ITT_CAMERA) { // camera
va009039 7:5dc595bbff58 344 int bControlSize = buf[14];
va009039 7:5dc595bbff58 345 VERBOSE("ControlSize: %d\n", bControlSize);
va009039 7:5dc595bbff58 346 for(int i = 0; i < bControlSize; i++) {
va009039 7:5dc595bbff58 347 uint8_t bControls = buf[15+i];
va009039 7:5dc595bbff58 348 VERBOSE("Controls(%d): %02X\n", i, bControls);
va009039 7:5dc595bbff58 349 }
va009039 7:5dc595bbff58 350 }
va009039 7:5dc595bbff58 351 ENDIF
va009039 7:5dc595bbff58 352 IF_EQ_THEN_PRINTF(VC_OUTPUT_TERMINAL, subtype)
va009039 7:5dc595bbff58 353 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 7:5dc595bbff58 354 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 7:5dc595bbff58 355 VERBOSE("AssocTerminal: %d\n", buf[6]);
va009039 7:5dc595bbff58 356 VERBOSE("SourceID: %d\n", buf[7]);
va009039 7:5dc595bbff58 357 VERBOSE("Terminal: %d\n", buf[8]);
va009039 7:5dc595bbff58 358 ENDIF
va009039 7:5dc595bbff58 359 IF_EQ_THEN_PRINTF(VC_SELECTOR_UNIT, subtype)
va009039 7:5dc595bbff58 360 VERBOSE("UnitID: %d\n", buf[3]);
va009039 7:5dc595bbff58 361 ENDIF
va009039 7:5dc595bbff58 362 IF_EQ_THEN_PRINTF(VC_PROCESSING_UNIT, subtype)
va009039 7:5dc595bbff58 363 VERBOSE("UnitID: %d\n", buf[3]);
va009039 7:5dc595bbff58 364 VERBOSE("SourceID: %d\n", buf[4]);
va009039 7:5dc595bbff58 365 VERBOSE("MaxMultiplier: %d\n", LE16(buf+5));
va009039 7:5dc595bbff58 366 VERBOSE("ControlSize: %d\n", buf[7]);
va009039 7:5dc595bbff58 367 int pos = 8;
va009039 7:5dc595bbff58 368 for (int n = 1; n <= buf[7]; n++) {
va009039 7:5dc595bbff58 369 VERBOSE("Controls(%d): %02X\n", n , buf[pos]);
va009039 7:5dc595bbff58 370 pos++;
va009039 7:5dc595bbff58 371 }
va009039 7:5dc595bbff58 372 VERBOSE("Processing: %d\n", buf[pos]);
va009039 7:5dc595bbff58 373 pos++;
va009039 7:5dc595bbff58 374 VERBOSE("VideoStanders: %02X\n", buf[pos]);
va009039 7:5dc595bbff58 375 ENDIF
va009039 7:5dc595bbff58 376 IF_EQ_THEN_PRINTF(VC_EXTENSION_UNIT, subtype)
va009039 7:5dc595bbff58 377 VERBOSE("UnitID: %d\n", buf[3]);
va009039 7:5dc595bbff58 378 GUID* guid = reinterpret_cast<GUID*>(buf+4);
va009039 7:5dc595bbff58 379 string s = guid->to_string();
va009039 7:5dc595bbff58 380 VERBOSE("guidExtensionCode: %s\n", s.c_str());
va009039 7:5dc595bbff58 381 VERBOSE("NumControls: %d\n", buf[20]);
va009039 7:5dc595bbff58 382 int p = buf[21];
va009039 7:5dc595bbff58 383 VERBOSE("NrInPins: %d\n", p);
va009039 7:5dc595bbff58 384 int pos = 22;
va009039 7:5dc595bbff58 385 for (int n = 1; n <= p; n++) {
va009039 7:5dc595bbff58 386 VERBOSE("SourceID(%d): %d\n", n, buf[pos]);
va009039 7:5dc595bbff58 387 pos++;
va009039 7:5dc595bbff58 388 }
va009039 7:5dc595bbff58 389 int bControlSize = buf[pos];
va009039 7:5dc595bbff58 390 pos++;
va009039 7:5dc595bbff58 391 VERBOSE("ControlSize: %d\n", bControlSize);
va009039 7:5dc595bbff58 392 pos++;
va009039 7:5dc595bbff58 393 for(int i = 0; i < bControlSize; i++) {
va009039 7:5dc595bbff58 394 VERBOSE("Control(%d): %02X\n", i, buf[pos]);
va009039 7:5dc595bbff58 395 pos++;
va009039 7:5dc595bbff58 396 }
va009039 7:5dc595bbff58 397 VERBOSE("iExtension: %d\n", buf[pos]);
va009039 7:5dc595bbff58 398 ENDIF
va009039 7:5dc595bbff58 399 }
va009039 7:5dc595bbff58 400
va009039 7:5dc595bbff58 401 #define VS_INPUT_HEADER 0x01
va009039 7:5dc595bbff58 402 #define VS_STILL_FRAME 0x03
va009039 7:5dc595bbff58 403 #define VS_FORMAT_UNCOMPRESSED 0x04
va009039 7:5dc595bbff58 404 #define VS_FRAME_UNCOMPRESSED 0x05
va009039 7:5dc595bbff58 405 #define VS_FORMAT_MJPEG 0x06
va009039 7:5dc595bbff58 406 #define VS_FRAME_MJPEG 0x07
va009039 7:5dc595bbff58 407 #define VS_COLOR_FORMAT 0x0d
va009039 7:5dc595bbff58 408
va009039 7:5dc595bbff58 409 void UvcCfg::_parserVideoStream(uint8_t* buf, int len) {
va009039 7:5dc595bbff58 410 int subtype = buf[2];
va009039 7:5dc595bbff58 411 IF_EQ_THEN_PRINTF(VS_INPUT_HEADER, subtype)
va009039 7:5dc595bbff58 412 VERBOSE("NumFormats: %d\n", buf[3]);
va009039 7:5dc595bbff58 413 VERBOSE("TotalLength: %d\n", LE16(buf+4));
va009039 7:5dc595bbff58 414 VERBOSE("EndpointAddress: %02X\n", buf[6]);
va009039 7:5dc595bbff58 415 VERBOSE("Info: %02X\n", buf[7]);
va009039 7:5dc595bbff58 416 VERBOSE("TerminalLink: %d\n", buf[8]);
va009039 7:5dc595bbff58 417 VERBOSE("StillCaptureMethod: %d\n", buf[9]);
va009039 7:5dc595bbff58 418 VERBOSE("TriggerSupport: %d\n", buf[10]);
va009039 7:5dc595bbff58 419 VERBOSE("TriggerUsage: %d\n", buf[11]);
va009039 7:5dc595bbff58 420 VERBOSE("ControlSize: %d\n", buf[12]);
va009039 7:5dc595bbff58 421 int pos = 13;
va009039 7:5dc595bbff58 422 for (int n = 1; n <= buf[12]; n++) {
va009039 7:5dc595bbff58 423 VERBOSE("Controls(%d): %02X\n", n, buf[pos]);
va009039 7:5dc595bbff58 424 pos++;
va009039 7:5dc595bbff58 425 }
va009039 7:5dc595bbff58 426 bEndpointAddress = buf[6];
va009039 7:5dc595bbff58 427 ENDIF
va009039 7:5dc595bbff58 428 IF_EQ_THEN_PRINTF(VS_STILL_FRAME, subtype)
va009039 7:5dc595bbff58 429 VERBOSE("EndpointAdress: %02X\n", buf[3]);
va009039 7:5dc595bbff58 430 VERBOSE("NumImageSizePatterns: %d\n", buf[4]);
va009039 7:5dc595bbff58 431 int ptn = buf[4];
va009039 7:5dc595bbff58 432 int pos = 5;
va009039 7:5dc595bbff58 433 for (int n = 1; n <= ptn; n++) {
va009039 7:5dc595bbff58 434 VERBOSE("Width(%d): %d\n", n, LE16(buf+pos));
va009039 7:5dc595bbff58 435 VERBOSE("Height(%d): %d\n", n, LE16(buf+pos+2));
va009039 7:5dc595bbff58 436 pos += 4;
va009039 7:5dc595bbff58 437 }
va009039 7:5dc595bbff58 438 VERBOSE("NumCompressPtn: %d\n", buf[pos]);
va009039 7:5dc595bbff58 439 ptn = buf[pos++];
va009039 7:5dc595bbff58 440 for (int n = 1; n <= ptn; n++) {
va009039 7:5dc595bbff58 441 VERBOSE("Compress(%d): %d\n", n, buf[pos]);
va009039 7:5dc595bbff58 442 pos++;
va009039 7:5dc595bbff58 443 }
va009039 7:5dc595bbff58 444 ENDIF
va009039 7:5dc595bbff58 445 IF_EQ_THEN_PRINTF(VS_FORMAT_UNCOMPRESSED, subtype)
va009039 7:5dc595bbff58 446 VERBOSE("FormatIndex: %d\n", buf[3]);
va009039 7:5dc595bbff58 447 VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
va009039 7:5dc595bbff58 448 GUID* guid = reinterpret_cast<GUID*>(buf+5);
va009039 7:5dc595bbff58 449 string s = guid->to_string();
va009039 7:5dc595bbff58 450 if (guid->isFormat("YUY2")) {
va009039 7:5dc595bbff58 451 VERBOSE("GUID: %s YUY2\n", s.c_str());
va009039 7:5dc595bbff58 452 } else if (guid->isFormat("NV12")) {
va009039 7:5dc595bbff58 453 VERBOSE("GUID: %s NV12\n", s.c_str());
va009039 7:5dc595bbff58 454 } else {
va009039 7:5dc595bbff58 455 VERBOSE("GUID: %s\n", s.c_str());
va009039 7:5dc595bbff58 456 }
va009039 7:5dc595bbff58 457 VERBOSE("DefaultFrameIndex: %d\n", buf[22]);
va009039 7:5dc595bbff58 458 if (_payload == UVC_YUY2) {
va009039 7:5dc595bbff58 459 FormatIndex = buf[3];
va009039 7:5dc595bbff58 460 }
va009039 7:5dc595bbff58 461 ENDIF
va009039 7:5dc595bbff58 462 IF_EQ_THEN_PRINTF(VS_FRAME_UNCOMPRESSED, subtype)
va009039 7:5dc595bbff58 463 VERBOSE("FrameIndex: %d\n", buf[3]);
va009039 7:5dc595bbff58 464 VERBOSE("Capabilites: %d\n", buf[4]);
va009039 7:5dc595bbff58 465 VERBOSE("Width: %d\n", LE16(buf+5));
va009039 7:5dc595bbff58 466 VERBOSE("Height: %d\n", LE16(buf+7));
va009039 7:5dc595bbff58 467 VERBOSE("MinBitRate: %d\n", LE32(buf+9));
va009039 7:5dc595bbff58 468 VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
va009039 7:5dc595bbff58 469 VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
va009039 7:5dc595bbff58 470 VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
va009039 7:5dc595bbff58 471 VERBOSE("FrameIntervalType: %d\n", buf[25]);
va009039 7:5dc595bbff58 472 int it = buf[25];
va009039 7:5dc595bbff58 473 uint32_t max_fi = 333333; // 30.0fps
va009039 7:5dc595bbff58 474 if (it == 0) {
va009039 7:5dc595bbff58 475 VERBOSE("FrameMinInterval: %d\n", buf[26]);
va009039 7:5dc595bbff58 476 VERBOSE("FrameMaxInterval: %d\n", buf[30]);
va009039 7:5dc595bbff58 477 VERBOSE("FrameIntervalStep: %d\n", buf[34]);
va009039 7:5dc595bbff58 478 } else {
va009039 7:5dc595bbff58 479 int pos = 26;
va009039 7:5dc595bbff58 480 for (int n = 1; n <= it; n++) {
va009039 7:5dc595bbff58 481 uint32_t fi = LE32(buf+pos);
va009039 7:5dc595bbff58 482 if (fi >= max_fi) {
va009039 7:5dc595bbff58 483 max_fi = fi;
va009039 7:5dc595bbff58 484 }
va009039 7:5dc595bbff58 485 float fps = 1e+7 / fi;
va009039 7:5dc595bbff58 486 VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
va009039 7:5dc595bbff58 487 pos += 4;
va009039 7:5dc595bbff58 488 }
va009039 7:5dc595bbff58 489 }
va009039 7:5dc595bbff58 490 if (_payload == UVC_YUY2) {
va009039 7:5dc595bbff58 491 if (_width == LE16(buf+5) && _height == LE16(buf+7)) {
va009039 7:5dc595bbff58 492 FrameIndex = buf[3];
va009039 7:5dc595bbff58 493 }
va009039 7:5dc595bbff58 494 if (dwFrameInterval == 0) {
va009039 7:5dc595bbff58 495 dwFrameInterval = max_fi;
va009039 7:5dc595bbff58 496 }
va009039 7:5dc595bbff58 497 }
va009039 7:5dc595bbff58 498 ENDIF
va009039 7:5dc595bbff58 499 IF_EQ_THEN_PRINTF(VS_FORMAT_MJPEG, subtype)
va009039 7:5dc595bbff58 500 VERBOSE("FormatIndex: %d\n", buf[3]);
va009039 7:5dc595bbff58 501 VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
va009039 7:5dc595bbff58 502 VERBOSE("Flags: %d\n", buf[5]);
va009039 7:5dc595bbff58 503 VERBOSE("DefaultFrameIndex: %d\n", buf[6]);
va009039 7:5dc595bbff58 504 if (_payload == UVC_MJPEG) {
va009039 7:5dc595bbff58 505 FormatIndex = buf[3];
va009039 7:5dc595bbff58 506 }
va009039 7:5dc595bbff58 507 ENDIF
va009039 7:5dc595bbff58 508 IF_EQ_THEN_PRINTF(VS_FRAME_MJPEG, subtype)
va009039 7:5dc595bbff58 509 VERBOSE("FrameIndex: %d\n", buf[3]);
va009039 7:5dc595bbff58 510 VERBOSE("Capabilites: %d\n", buf[4]);
va009039 7:5dc595bbff58 511 VERBOSE("Width: %d\n", LE16(buf+5));
va009039 7:5dc595bbff58 512 VERBOSE("Height: %d\n", LE16(buf+7));
va009039 7:5dc595bbff58 513 VERBOSE("MinBitRate: %d\n", LE32(buf+9));
va009039 7:5dc595bbff58 514 VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
va009039 7:5dc595bbff58 515 VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
va009039 7:5dc595bbff58 516 VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
va009039 7:5dc595bbff58 517 VERBOSE("FrameIntervalType: %d\n", buf[25]);
va009039 7:5dc595bbff58 518 int it = buf[25];
va009039 7:5dc595bbff58 519 uint32_t max_fi = 333333; // 30.0fps
va009039 7:5dc595bbff58 520 if (it == 0) {
va009039 7:5dc595bbff58 521 VERBOSE("FrameMinInterval: %d\n", buf[26]);
va009039 7:5dc595bbff58 522 VERBOSE("FrameMaxInterval: %d\n", buf[30]);
va009039 7:5dc595bbff58 523 VERBOSE("FrameIntervalStep: %d\n", buf[34]);
va009039 7:5dc595bbff58 524 } else {
va009039 7:5dc595bbff58 525 int pos = 26;
va009039 7:5dc595bbff58 526 for (int n = 1; n <= it; n++) {
va009039 7:5dc595bbff58 527 uint32_t fi = LE32(buf+pos);
va009039 7:5dc595bbff58 528 if (fi >= max_fi) {
va009039 7:5dc595bbff58 529 max_fi = fi;
va009039 7:5dc595bbff58 530 }
va009039 7:5dc595bbff58 531 float fps = 1e+7 / fi;
va009039 7:5dc595bbff58 532 VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
va009039 7:5dc595bbff58 533 pos += 4;
va009039 7:5dc595bbff58 534 }
va009039 7:5dc595bbff58 535 }
va009039 7:5dc595bbff58 536 if (_payload == UVC_MJPEG) {
va009039 7:5dc595bbff58 537 if (_width == LE16(buf+5) && _height == LE16(buf+7)) {
va009039 7:5dc595bbff58 538 FrameIndex = buf[3];
va009039 7:5dc595bbff58 539 }
va009039 7:5dc595bbff58 540 if (dwFrameInterval == 0) {
va009039 7:5dc595bbff58 541 dwFrameInterval = max_fi;
va009039 7:5dc595bbff58 542 }
va009039 7:5dc595bbff58 543 }
va009039 7:5dc595bbff58 544 ENDIF
va009039 7:5dc595bbff58 545 IF_EQ_THEN_PRINTF(VS_COLOR_FORMAT, subtype)
va009039 7:5dc595bbff58 546 ENDIF
va009039 7:5dc595bbff58 547 }
va009039 7:5dc595bbff58 548
va009039 7:5dc595bbff58 549 void UvcCfg::_parserConfigurationDescriptor(uint8_t* buf, int len) {
va009039 7:5dc595bbff58 550 int pos = 0;
va009039 7:5dc595bbff58 551 _IfClass = 0;
va009039 7:5dc595bbff58 552 _IfSubClass = 0;
va009039 7:5dc595bbff58 553 while (pos < len) {
va009039 7:5dc595bbff58 554 int type = buf[pos+1];
va009039 7:5dc595bbff58 555 //DBG_BYTES(TYPE_Str(type), buf+pos, buf[pos]);
va009039 7:5dc595bbff58 556 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CONFIGURATION, type)
va009039 7:5dc595bbff58 557 VERBOSE("NumInterfaces: %d\n", buf[pos+4]);
va009039 7:5dc595bbff58 558 ENDIF
va009039 7:5dc595bbff58 559 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, type)
va009039 7:5dc595bbff58 560 VERBOSE("FirstInterface: %d\n", buf[pos+2]);
va009039 7:5dc595bbff58 561 VERBOSE("InterfaceCount: %d\n", buf[pos+3]);
va009039 7:5dc595bbff58 562 VERBOSE("FunctionClass: %02X\n", buf[pos+4]);
va009039 7:5dc595bbff58 563 VERBOSE("FunctionSubClass: %02X\n", buf[pos+5]);
va009039 7:5dc595bbff58 564 VERBOSE("FunctionProtocol: %02X\n", buf[pos+6]);
va009039 7:5dc595bbff58 565 VERBOSE("Function: %d\n", buf[pos+7]);
va009039 7:5dc595bbff58 566 ENDIF
va009039 7:5dc595bbff58 567 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE,type)
va009039 7:5dc595bbff58 568 VERBOSE("InterfaceNumber: %d\n", buf[pos+2]);
va009039 7:5dc595bbff58 569 VERBOSE("AlternateSetting: %d\n", buf[pos+3]);
va009039 7:5dc595bbff58 570 VERBOSE("NumEndpoint: %d\n", buf[pos+4]);
va009039 7:5dc595bbff58 571 VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
va009039 7:5dc595bbff58 572 VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
va009039 7:5dc595bbff58 573 VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
va009039 7:5dc595bbff58 574 VERBOSE("Interface: %d\n", buf[pos+8]);
va009039 7:5dc595bbff58 575 _If = buf[pos+2];
va009039 7:5dc595bbff58 576 _Ifalt = buf[pos+3];
va009039 7:5dc595bbff58 577 _IfClass = buf[pos+5];
va009039 7:5dc595bbff58 578 _IfSubClass = buf[pos+6];
va009039 7:5dc595bbff58 579 ENDIF
va009039 7:5dc595bbff58 580 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_ENDPOINT, type)
va009039 7:5dc595bbff58 581 VERBOSE("EndpointAddress: %02X\n", buf[pos+2]);
va009039 7:5dc595bbff58 582 VERBOSE("Attributes: %02X\n", buf[pos+3]);
va009039 7:5dc595bbff58 583 VERBOSE("MaxPacketSize: %d\n", LE16(buf+pos+4));
va009039 7:5dc595bbff58 584 VERBOSE("Interval: %d\n", buf[pos+6]);
va009039 7:5dc595bbff58 585 if (_IfClass == CC_VIDEO && _IfSubClass == SC_VIDEOSTREAMING) {
va009039 7:5dc595bbff58 586 if (bEndpointAddress == buf[pos+2]) {
va009039 7:5dc595bbff58 587 if (wMaxPacketSize == 0) {
va009039 7:5dc595bbff58 588 wMaxPacketSize = LE16(buf+pos+4);
va009039 7:5dc595bbff58 589 }
va009039 7:5dc595bbff58 590 if (wMaxPacketSize == LE16(buf+pos+4)) {
va009039 7:5dc595bbff58 591 bInterface = _If;
va009039 7:5dc595bbff58 592 bAlternate = _Ifalt;
va009039 7:5dc595bbff58 593 }
va009039 7:5dc595bbff58 594 }
va009039 7:5dc595bbff58 595 }
va009039 7:5dc595bbff58 596 ENDIF
va009039 7:5dc595bbff58 597 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CS_INTERFACE, type)
va009039 7:5dc595bbff58 598 IF_EQ_THEN_PRINTF(CC_VIDEO, _IfClass)
va009039 7:5dc595bbff58 599 IF_EQ_THEN_PRINTF(SC_VIDEOCONTROL, _IfSubClass)
va009039 7:5dc595bbff58 600 _parserVideoControl(buf+pos, buf[pos]);
va009039 7:5dc595bbff58 601 ENDIF
va009039 7:5dc595bbff58 602 IF_EQ_THEN_PRINTF(SC_VIDEOSTREAMING, _IfSubClass)
va009039 7:5dc595bbff58 603 _parserVideoStream(buf+pos, buf[pos]);
va009039 7:5dc595bbff58 604 ENDIF
va009039 7:5dc595bbff58 605 ENDIF
va009039 7:5dc595bbff58 606 IF_EQ_THEN_PRINTF(CC_AUDIO, _IfClass)
va009039 7:5dc595bbff58 607 IF_EQ_THEN_PRINTF(SC_AUDIOCONTROL, _IfSubClass)
va009039 7:5dc595bbff58 608 _parserAudioControl(buf+pos, buf[pos]);
va009039 7:5dc595bbff58 609 ENDIF
va009039 7:5dc595bbff58 610 IF_EQ_THEN_PRINTF(SC_AUDIOSTREAMING, _IfSubClass)
va009039 7:5dc595bbff58 611 _parserAudioStream(buf+pos, buf[pos]);
va009039 7:5dc595bbff58 612 ENDIF
va009039 7:5dc595bbff58 613 ENDIF
va009039 7:5dc595bbff58 614 ENDIF
va009039 7:5dc595bbff58 615 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_HUB, type)
va009039 7:5dc595bbff58 616 ENDIF
va009039 7:5dc595bbff58 617 pos += buf[pos];
va009039 7:5dc595bbff58 618 }
va009039 7:5dc595bbff58 619 }
va009039 7:5dc595bbff58 620