Webcam Server.
Dependencies: uvchost FatFileSystem mbed HTTPServer NetServicesMin
Diff: uvc/uvc.cpp
- Revision:
- 1:7a4f2c038803
- Parent:
- 0:2b4ea8a138e5
--- a/uvc/uvc.cpp Wed Jun 06 11:47:06 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ -#include "mbed.h" -#include "uvc.h" - -//#define __DEBUG -//#define __DEBUG3 -#include "mydbg.h" -#include "usb_itd.h" - -uvc::uvc(int cam) -{ - DBG("cam=%d\n", cam); - DBG_ASSERT(cam >= 0); - m_cam = cam; - m_init = false; - m_connect = false; - m_int_seq = 0; - m_iso_seq = 0; - m_width = 0; - m_height = 0; - m_payload = PAYLOAD_MJPEG; - m_FormatIndex = 0; - m_FrameIndex = 0; - m_FrameInterval = 0; - m_PacketSize = 0; - m_stream = NULL; - for(int i = 0; i <= 15; i++) { - ReportConditionCode[i] = 0; - } - clearOnResult(); -} - -uvc::~uvc() -{ - clearOnResult(); -} - -int uvc::setup() -{ - if (!m_init) { - return _init(); - } - return 0; -} - -int uvc::get_jpeg(const char* path) -{ - const int size = 4800; - const int timeout = 5000; - uint8_t* buf = new uint8_t[size]; - DBG_ASSERT(buf); - if (buf == NULL) { - return -1; - } - usb_mjpeg mjpeg(buf, size); - attach(&mjpeg); - Timer t; - t.reset(); - t.start(); - while(t.read_ms() < timeout) { - int stat = isochronous(); - if (mjpeg.status() >= 0) { - break; - } - } - detach(); - int len = mjpeg.status(); - if (len >= 0) { - if (path != NULL) { - FILE *fp = fopen(path, "wb"); - if (fp != NULL) { - for(int i = 0; i < len; i++) { - fputc(buf[i], fp); - } - fclose(fp); - } - } - } - delete[] buf; - return len; -} - -int uvc::get_jpeg(uint8_t* buf, int size) -{ - //DBG("buf=%p size=%d\n", buf, size); - const int timeout = 5000; - usb_mjpeg mjpeg(buf, size); - attach(&mjpeg); - Timer t; - t.reset(); - t.start(); - while(t.read_ms() < timeout) { - int stat = isochronous(); - if (mjpeg.status() >= 0) { - break; - } - } - detach(); - int len = mjpeg.status(); - return len; -} - -bool uvc::interrupt() -{ - if (!m_init) { - _init(); - } - if (m_int_seq == 0) { - int rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf)); - if (rc != USBERR_PROCESSING) { - return false; - } - m_int_seq++; - } - int len = m_pEpIntIn->status(); - if (len > 0) { - m_int_seq = 0; - DBG_BYTES("interrupt", m_int_buf, len); - return true; - } - return false; -} - -#define CC_NOERROR 0x0 -#define CC_DATAOVERRUN 0x8 -#define CC_DATAUNDERRUN 0x9 - -inline void DI() -{ - NVIC_DisableIRQ(USB_IRQn); -} - -inline void EI() -{ - NVIC_EnableIRQ(USB_IRQn); -} - -int uvc::isochronous() -{ - if (m_iso_seq == 0) { - uint16_t frame = LPC_USB->HcFmNumber; - m_iso_frame = frame + 10; // 10msec - DBG_ASSERT(m_pEpIsoIn->m_itdActive == 0); - m_iso_seq++; - } - if (m_iso_seq == 1) { - DBG_ASSERT(m_itdCount > 0 && m_itdCount <= 8); - while(m_pEpIsoIn->m_itdActive < m_itdCount) { - int len = m_PacketSize * m_FrameCount; - uint8_t* buf = (uint8_t*)usb_get_bp(len); - if (buf == NULL) { - DBG("len=%d\n", len); - DBG("m_itdCount=%d\n", m_itdCount); - } - DBG_ASSERT(buf); - int rc = m_pEpIsoIn->transfer(m_iso_frame, m_FrameCount, buf, len); - m_iso_frame += m_FrameCount; - DBG_ASSERT(rc == USBERR_PROCESSING); - } - m_iso_seq++; - } - if (m_iso_seq == 2) { - //DBG("frame:%04X\n", LPC_USB->HcFmNumber); - while(1) { - DI(); - bool empty = m_pEpIsoIn->queue_done_itd.empty(); - EI(); - - if (empty) { - break; - } - - DI(); - HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); - m_pEpIsoIn->queue_done_itd.pop(); - EI(); - - m_pEpIsoIn->m_itdActive--; - usb_itd iso_td(itd); - //DBG("frame:%04X\n", LPC_USB->HcFmNumber); - //DBG("itd->Control=%08X\n", itd->Control); - int cc = iso_td.ConditionCode(); - DBG_ASSERT(cc >= 0 && cc <= 15); - ReportConditionCode[cc]++; - if (cc != CC_NOERROR) { - DBG3("%04X ERR:%X\n", LPC_USB->HcFmNumber, cc); - iso_td.free(); - m_iso_seq = 3; - return -1; - } - uint16_t frame = iso_td.StartingFrame(); - int fc = iso_td.FrameCount(); - for(int i = 0; i < fc; i++) { - int len = iso_td.Length(i); - if (len > 0) { - if (m_stream) { - m_stream->input(frame+i, iso_td.BufferPage(i, m_PacketSize), len); - } - onResult(frame+i, iso_td.BufferPage(i, m_PacketSize), len); - } - } - iso_td.free(); - } - //DBG("frame:%04X\n", LPC_USB->HcFmNumber); - m_iso_seq = 1; - return m_pEpIsoIn->m_itdActive; - } - if (m_iso_seq == 3) { // cleanup - DBG("m_pEpIsoIn->queue_done_itd.size() :%d\n", m_pEpIsoIn->queue_done_itd.size()); - while(1) { - DI(); - bool empty = m_pEpIsoIn->queue_done_itd.empty(); - EI(); - - if (empty) { - break; - } - - DI(); - HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); - m_pEpIsoIn->queue_done_itd.pop(); - EI(); - - m_pEpIsoIn->m_itdActive--; - usb_itd iso_td(itd); - iso_td.free(); - } - if (m_pEpIsoIn->m_itdActive == 0) { - m_iso_seq = 0; - } - } - return m_pEpIsoIn->m_itdActive; -} - -void uvc::attach(usb_stream* stream) -{ - m_stream = stream; -} - -void uvc::detach() -{ - m_stream = NULL; -} - -void uvc::onResult(uint16_t frame, uint8_t* buf, int len) -{ - if(m_pCbItem && m_pCbMeth) - (m_pCbItem->*m_pCbMeth)(frame, buf, len); - else if(m_pCb) - m_pCb(frame, buf, len); -} - -void uvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ) -{ - m_pCb = pMethod; - m_pCbItem = NULL; - m_pCbMeth = NULL; -} - -void uvc::clearOnResult() -{ - m_pCb = NULL; - m_pCbItem = NULL; - m_pCbMeth = NULL; -}