データのサイズが4800で制限されているようだったので、 /uvchost/uvc/uvc.cpp内の int uvc::get_jpeg(const char* path) const int size = 9600; に変更。

Dependents:   WebCamera_SD

Fork of uvchost by Norimasa Okamoto

Committer:
Dromar
Date:
Sun Feb 10 15:20:36 2013 +0000
Revision:
4:97438d526ad3
Parent:
0:b0f04c137829
????????4800????????????????; /uvchost/uvc/uvc.cpp??; int uvc::get_jpeg(const char* path); const int size = 9600;; ????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Dromar 4:97438d526ad3 1 #include "mbed.h"
Dromar 4:97438d526ad3 2 #include "uvc.h"
Dromar 4:97438d526ad3 3
Dromar 4:97438d526ad3 4 //#define __DEBUG
Dromar 4:97438d526ad3 5 //#define __DEBUG3
Dromar 4:97438d526ad3 6 #include "mydbg.h"
Dromar 4:97438d526ad3 7 #include "usb_itd.h"
Dromar 4:97438d526ad3 8
Dromar 4:97438d526ad3 9 uvc::uvc(int cam)
Dromar 4:97438d526ad3 10 {
Dromar 4:97438d526ad3 11 DBG("cam=%d\n", cam);
Dromar 4:97438d526ad3 12 DBG_ASSERT(cam >= 0);
Dromar 4:97438d526ad3 13 m_cam = cam;
Dromar 4:97438d526ad3 14 m_init = false;
Dromar 4:97438d526ad3 15 m_connect = false;
Dromar 4:97438d526ad3 16 m_int_seq = 0;
Dromar 4:97438d526ad3 17 m_iso_seq = 0;
Dromar 4:97438d526ad3 18 m_width = 0;
Dromar 4:97438d526ad3 19 m_height = 0;
Dromar 4:97438d526ad3 20 m_payload = PAYLOAD_MJPEG;
Dromar 4:97438d526ad3 21 m_FormatIndex = 0;
Dromar 4:97438d526ad3 22 m_FrameIndex = 0;
Dromar 4:97438d526ad3 23 m_FrameInterval = 0;
Dromar 4:97438d526ad3 24 m_PacketSize = 0;
Dromar 4:97438d526ad3 25 m_stream = NULL;
Dromar 4:97438d526ad3 26 for(int i = 0; i <= 15; i++) {
Dromar 4:97438d526ad3 27 ReportConditionCode[i] = 0;
Dromar 4:97438d526ad3 28 }
Dromar 4:97438d526ad3 29 clearOnResult();
Dromar 4:97438d526ad3 30 }
Dromar 4:97438d526ad3 31
Dromar 4:97438d526ad3 32 uvc::~uvc()
Dromar 4:97438d526ad3 33 {
Dromar 4:97438d526ad3 34 clearOnResult();
Dromar 4:97438d526ad3 35 }
Dromar 4:97438d526ad3 36
Dromar 4:97438d526ad3 37 int uvc::setup()
Dromar 4:97438d526ad3 38 {
Dromar 4:97438d526ad3 39 if (!m_init) {
Dromar 4:97438d526ad3 40 return _init();
Dromar 4:97438d526ad3 41 }
Dromar 4:97438d526ad3 42 return 0;
Dromar 4:97438d526ad3 43 }
Dromar 4:97438d526ad3 44
Dromar 4:97438d526ad3 45 int uvc::get_jpeg(const char* path)
Dromar 4:97438d526ad3 46 {
Dromar 4:97438d526ad3 47 //const int size = 4800;
Dromar 4:97438d526ad3 48 const int size = 9600;
Dromar 4:97438d526ad3 49 const int timeout = 5000;
Dromar 4:97438d526ad3 50 uint8_t* buf = new uint8_t[size];
Dromar 4:97438d526ad3 51 DBG_ASSERT(buf);
Dromar 4:97438d526ad3 52 if (buf == NULL) {
Dromar 4:97438d526ad3 53 return -1;
Dromar 4:97438d526ad3 54 }
Dromar 4:97438d526ad3 55 usb_mjpeg mjpeg(buf, size);
Dromar 4:97438d526ad3 56 attach(&mjpeg);
Dromar 4:97438d526ad3 57 Timer t;
Dromar 4:97438d526ad3 58 t.reset();
Dromar 4:97438d526ad3 59 t.start();
Dromar 4:97438d526ad3 60 while(t.read_ms() < timeout) {
Dromar 4:97438d526ad3 61 int stat = isochronous();
Dromar 4:97438d526ad3 62 if (mjpeg.status() >= 0) {
Dromar 4:97438d526ad3 63 break;
Dromar 4:97438d526ad3 64 }
Dromar 4:97438d526ad3 65 }
Dromar 4:97438d526ad3 66 detach();
Dromar 4:97438d526ad3 67 int len = mjpeg.status();
Dromar 4:97438d526ad3 68 if (len >= 0) {
Dromar 4:97438d526ad3 69 if (path != NULL) {
Dromar 4:97438d526ad3 70 FILE *fp = fopen(path, "wb");
Dromar 4:97438d526ad3 71 if (fp != NULL) {
Dromar 4:97438d526ad3 72 for(int i = 0; i < len; i++) {
Dromar 4:97438d526ad3 73 fputc(buf[i], fp);
Dromar 4:97438d526ad3 74 }
Dromar 4:97438d526ad3 75 fclose(fp);
Dromar 4:97438d526ad3 76 }
Dromar 4:97438d526ad3 77 }
Dromar 4:97438d526ad3 78 }
Dromar 4:97438d526ad3 79 delete[] buf;
Dromar 4:97438d526ad3 80 return len;
Dromar 4:97438d526ad3 81 }
Dromar 4:97438d526ad3 82
Dromar 4:97438d526ad3 83 int uvc::get_jpeg(uint8_t* buf, int size)
Dromar 4:97438d526ad3 84 {
Dromar 4:97438d526ad3 85 //DBG("buf=%p size=%d\n", buf, size);
Dromar 4:97438d526ad3 86 const int timeout = 5000;
Dromar 4:97438d526ad3 87 usb_mjpeg mjpeg(buf, size);
Dromar 4:97438d526ad3 88 attach(&mjpeg);
Dromar 4:97438d526ad3 89 Timer t;
Dromar 4:97438d526ad3 90 t.reset();
Dromar 4:97438d526ad3 91 t.start();
Dromar 4:97438d526ad3 92 while(t.read_ms() < timeout) {
Dromar 4:97438d526ad3 93 int stat = isochronous();
Dromar 4:97438d526ad3 94 if (mjpeg.status() >= 0) {
Dromar 4:97438d526ad3 95 break;
Dromar 4:97438d526ad3 96 }
Dromar 4:97438d526ad3 97 }
Dromar 4:97438d526ad3 98 detach();
Dromar 4:97438d526ad3 99 int len = mjpeg.status();
Dromar 4:97438d526ad3 100 return len;
Dromar 4:97438d526ad3 101 }
Dromar 4:97438d526ad3 102
Dromar 4:97438d526ad3 103 bool uvc::interrupt()
Dromar 4:97438d526ad3 104 {
Dromar 4:97438d526ad3 105 if (!m_init) {
Dromar 4:97438d526ad3 106 _init();
Dromar 4:97438d526ad3 107 }
Dromar 4:97438d526ad3 108 if (m_int_seq == 0) {
Dromar 4:97438d526ad3 109 int rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf));
Dromar 4:97438d526ad3 110 if (rc != USBERR_PROCESSING) {
Dromar 4:97438d526ad3 111 return false;
Dromar 4:97438d526ad3 112 }
Dromar 4:97438d526ad3 113 m_int_seq++;
Dromar 4:97438d526ad3 114 }
Dromar 4:97438d526ad3 115 int len = m_pEpIntIn->status();
Dromar 4:97438d526ad3 116 if (len > 0) {
Dromar 4:97438d526ad3 117 m_int_seq = 0;
Dromar 4:97438d526ad3 118 DBG_BYTES("interrupt", m_int_buf, len);
Dromar 4:97438d526ad3 119 return true;
Dromar 4:97438d526ad3 120 }
Dromar 4:97438d526ad3 121 return false;
Dromar 4:97438d526ad3 122 }
Dromar 4:97438d526ad3 123
Dromar 4:97438d526ad3 124 #define CC_NOERROR 0x0
Dromar 4:97438d526ad3 125 #define CC_DATAOVERRUN 0x8
Dromar 4:97438d526ad3 126 #define CC_DATAUNDERRUN 0x9
Dromar 4:97438d526ad3 127
Dromar 4:97438d526ad3 128 inline void DI()
Dromar 4:97438d526ad3 129 {
Dromar 4:97438d526ad3 130 NVIC_DisableIRQ(USB_IRQn);
Dromar 4:97438d526ad3 131 }
Dromar 4:97438d526ad3 132
Dromar 4:97438d526ad3 133 inline void EI()
Dromar 4:97438d526ad3 134 {
Dromar 4:97438d526ad3 135 NVIC_EnableIRQ(USB_IRQn);
Dromar 4:97438d526ad3 136 }
Dromar 4:97438d526ad3 137
Dromar 4:97438d526ad3 138 int uvc::isochronous()
Dromar 4:97438d526ad3 139 {
Dromar 4:97438d526ad3 140 if (m_iso_seq == 0) {
Dromar 4:97438d526ad3 141 uint16_t frame = LPC_USB->HcFmNumber;
Dromar 4:97438d526ad3 142 m_iso_frame = frame + 10; // 10msec
Dromar 4:97438d526ad3 143 DBG_ASSERT(m_pEpIsoIn->m_itdActive == 0);
Dromar 4:97438d526ad3 144 m_iso_seq++;
Dromar 4:97438d526ad3 145 }
Dromar 4:97438d526ad3 146 if (m_iso_seq == 1) {
Dromar 4:97438d526ad3 147 DBG_ASSERT(m_itdCount > 0 && m_itdCount <= 8);
Dromar 4:97438d526ad3 148 while(m_pEpIsoIn->m_itdActive < m_itdCount) {
Dromar 4:97438d526ad3 149 int len = m_PacketSize * m_FrameCount;
Dromar 4:97438d526ad3 150 uint8_t* buf = (uint8_t*)usb_get_bp(len);
Dromar 4:97438d526ad3 151 if (buf == NULL) {
Dromar 4:97438d526ad3 152 DBG("len=%d\n", len);
Dromar 4:97438d526ad3 153 DBG("m_itdCount=%d\n", m_itdCount);
Dromar 4:97438d526ad3 154 }
Dromar 4:97438d526ad3 155 DBG_ASSERT(buf);
Dromar 4:97438d526ad3 156 int rc = m_pEpIsoIn->transfer(m_iso_frame, m_FrameCount, buf, len);
Dromar 4:97438d526ad3 157 m_iso_frame += m_FrameCount;
Dromar 4:97438d526ad3 158 DBG_ASSERT(rc == USBERR_PROCESSING);
Dromar 4:97438d526ad3 159 }
Dromar 4:97438d526ad3 160 m_iso_seq++;
Dromar 4:97438d526ad3 161 }
Dromar 4:97438d526ad3 162 if (m_iso_seq == 2) {
Dromar 4:97438d526ad3 163 //DBG("frame:%04X\n", LPC_USB->HcFmNumber);
Dromar 4:97438d526ad3 164 while(1) {
Dromar 4:97438d526ad3 165 DI();
Dromar 4:97438d526ad3 166 bool empty = m_pEpIsoIn->queue_done_itd.empty();
Dromar 4:97438d526ad3 167 EI();
Dromar 4:97438d526ad3 168
Dromar 4:97438d526ad3 169 if (empty) {
Dromar 4:97438d526ad3 170 break;
Dromar 4:97438d526ad3 171 }
Dromar 4:97438d526ad3 172
Dromar 4:97438d526ad3 173 DI();
Dromar 4:97438d526ad3 174 HCITD* itd = m_pEpIsoIn->queue_done_itd.front();
Dromar 4:97438d526ad3 175 m_pEpIsoIn->queue_done_itd.pop();
Dromar 4:97438d526ad3 176 EI();
Dromar 4:97438d526ad3 177
Dromar 4:97438d526ad3 178 m_pEpIsoIn->m_itdActive--;
Dromar 4:97438d526ad3 179 usb_itd iso_td(itd);
Dromar 4:97438d526ad3 180 //DBG("frame:%04X\n", LPC_USB->HcFmNumber);
Dromar 4:97438d526ad3 181 //DBG("itd->Control=%08X\n", itd->Control);
Dromar 4:97438d526ad3 182 int cc = iso_td.ConditionCode();
Dromar 4:97438d526ad3 183 DBG_ASSERT(cc >= 0 && cc <= 15);
Dromar 4:97438d526ad3 184 ReportConditionCode[cc]++;
Dromar 4:97438d526ad3 185 if (cc != CC_NOERROR) {
Dromar 4:97438d526ad3 186 DBG3("%04X ERR:%X\n", LPC_USB->HcFmNumber, cc);
Dromar 4:97438d526ad3 187 iso_td.free();
Dromar 4:97438d526ad3 188 m_iso_seq = 3;
Dromar 4:97438d526ad3 189 return -1;
Dromar 4:97438d526ad3 190 }
Dromar 4:97438d526ad3 191 uint16_t frame = iso_td.StartingFrame();
Dromar 4:97438d526ad3 192 int fc = iso_td.FrameCount();
Dromar 4:97438d526ad3 193 for(int i = 0; i < fc; i++) {
Dromar 4:97438d526ad3 194 int len = iso_td.Length(i);
Dromar 4:97438d526ad3 195 if (len > 0) {
Dromar 4:97438d526ad3 196 if (m_stream) {
Dromar 4:97438d526ad3 197 m_stream->input(frame+i, iso_td.BufferPage(i, m_PacketSize), len);
Dromar 4:97438d526ad3 198 }
Dromar 4:97438d526ad3 199 onResult(frame+i, iso_td.BufferPage(i, m_PacketSize), len);
Dromar 4:97438d526ad3 200 }
Dromar 4:97438d526ad3 201 }
Dromar 4:97438d526ad3 202 iso_td.free();
Dromar 4:97438d526ad3 203 }
Dromar 4:97438d526ad3 204 //DBG("frame:%04X\n", LPC_USB->HcFmNumber);
Dromar 4:97438d526ad3 205 m_iso_seq = 1;
Dromar 4:97438d526ad3 206 return m_pEpIsoIn->m_itdActive;
Dromar 4:97438d526ad3 207 }
Dromar 4:97438d526ad3 208 if (m_iso_seq == 3) { // cleanup
Dromar 4:97438d526ad3 209 DBG("m_pEpIsoIn->queue_done_itd.size() :%d\n", m_pEpIsoIn->queue_done_itd.size());
Dromar 4:97438d526ad3 210 while(1) {
Dromar 4:97438d526ad3 211 DI();
Dromar 4:97438d526ad3 212 bool empty = m_pEpIsoIn->queue_done_itd.empty();
Dromar 4:97438d526ad3 213 EI();
Dromar 4:97438d526ad3 214
Dromar 4:97438d526ad3 215 if (empty) {
Dromar 4:97438d526ad3 216 break;
Dromar 4:97438d526ad3 217 }
Dromar 4:97438d526ad3 218
Dromar 4:97438d526ad3 219 DI();
Dromar 4:97438d526ad3 220 HCITD* itd = m_pEpIsoIn->queue_done_itd.front();
Dromar 4:97438d526ad3 221 m_pEpIsoIn->queue_done_itd.pop();
Dromar 4:97438d526ad3 222 EI();
Dromar 4:97438d526ad3 223
Dromar 4:97438d526ad3 224 m_pEpIsoIn->m_itdActive--;
Dromar 4:97438d526ad3 225 usb_itd iso_td(itd);
Dromar 4:97438d526ad3 226 iso_td.free();
Dromar 4:97438d526ad3 227 }
Dromar 4:97438d526ad3 228 if (m_pEpIsoIn->m_itdActive == 0) {
Dromar 4:97438d526ad3 229 m_iso_seq = 0;
Dromar 4:97438d526ad3 230 }
Dromar 4:97438d526ad3 231 }
Dromar 4:97438d526ad3 232 return m_pEpIsoIn->m_itdActive;
Dromar 4:97438d526ad3 233 }
Dromar 4:97438d526ad3 234
Dromar 4:97438d526ad3 235 void uvc::attach(usb_stream* stream)
Dromar 4:97438d526ad3 236 {
Dromar 4:97438d526ad3 237 m_stream = stream;
Dromar 4:97438d526ad3 238 }
Dromar 4:97438d526ad3 239
Dromar 4:97438d526ad3 240 void uvc::detach()
Dromar 4:97438d526ad3 241 {
Dromar 4:97438d526ad3 242 m_stream = NULL;
Dromar 4:97438d526ad3 243 }
Dromar 4:97438d526ad3 244
Dromar 4:97438d526ad3 245 void uvc::onResult(uint16_t frame, uint8_t* buf, int len)
Dromar 4:97438d526ad3 246 {
Dromar 4:97438d526ad3 247 if(m_pCbItem && m_pCbMeth)
Dromar 4:97438d526ad3 248 (m_pCbItem->*m_pCbMeth)(frame, buf, len);
Dromar 4:97438d526ad3 249 else if(m_pCb)
Dromar 4:97438d526ad3 250 m_pCb(frame, buf, len);
Dromar 4:97438d526ad3 251 }
Dromar 4:97438d526ad3 252
Dromar 4:97438d526ad3 253 void uvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) )
Dromar 4:97438d526ad3 254 {
Dromar 4:97438d526ad3 255 m_pCb = pMethod;
Dromar 4:97438d526ad3 256 m_pCbItem = NULL;
Dromar 4:97438d526ad3 257 m_pCbMeth = NULL;
Dromar 4:97438d526ad3 258 }
Dromar 4:97438d526ad3 259
Dromar 4:97438d526ad3 260 void uvc::clearOnResult()
Dromar 4:97438d526ad3 261 {
Dromar 4:97438d526ad3 262 m_pCb = NULL;
Dromar 4:97438d526ad3 263 m_pCbItem = NULL;
Dromar 4:97438d526ad3 264 m_pCbMeth = NULL;
Dromar 4:97438d526ad3 265 }