BaseJpegDeocde exampe program

Dependencies:   BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos

Fork of BaseJpegDecode by Norimasa Okamoto

Committer:
va009039
Date:
Sun Jan 27 11:15:26 2013 +0000
Revision:
7:3ad9c948bc06
change library uvchost to BaseUsbHost, delete SimpleJpegDecode

Who changed what in which revision?

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