Simple USBHost WebCam test program

Dependencies:   F401RE-USBHost mbed

Fork of KL46Z-USBHostC270_example by Norimasa Okamoto

WebカメラからJPEG画像を読み取るテストプログラムです。
使い方はKL46Z-USBHostC270_exampleと同じです。
動作確認カメラ: Logitech C270, Logitech C210, Logitech Q200R(Qcam Orbit AF), LifeCam VX-500
/media/uploads/va009039/f401re-c270-1.jpg /media/uploads/va009039/k64f-c270.jpg

KL46Z_USBHostC270/USBHostCam.cpp

Committer:
va009039
Date:
2014-01-28
Revision:
1:22304b8f8395
Child:
2:2a40888db9fc

File content as of revision 1:22304b8f8395:

// USBHostCam.cpp
#include "USBHostCam.h"

//#define CAM_DEBUG 1
#ifdef CAM_DEBUG
#define CAM_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define CAM_DBG(...)  while(0);
#endif
#define CAM_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0);

CamInfo* getCamInfoList(); // CamInfo.cpp

USBHostCam::USBHostCam(uint8_t size, uint8_t option, CamInfo* user_caminfo)
{
    CAM_DBG("size: %d, option: %d", size, option);
    _caminfo_size = size;
    _caminfo_option = option;
    if (user_caminfo) {
        CamInfoList = user_caminfo;
    } else {
        CamInfoList = getCamInfoList();
    }
    clearOnResult();
    host = USBHost::getHostInst();
    setup();
}

void USBHostCam::setup() {
    caminfo = CamInfoList;
    bool found = false;
    while(caminfo->vid != 0) {
        if (caminfo->vid == host->dev.vid && caminfo->pid == host->dev.pid && 
            caminfo->size == _caminfo_size && caminfo->option == _caminfo_option) {
            found = true;
            break;
        }
        caminfo++;
    }
    if (!found) {
        CAM_INFO("caminfo not found.\n");
        exit(1);
    }
    CAM_INFO("Found: %s\n", caminfo->name);

    ep_iso_in.setAddress(caminfo->en);
    ep_iso_in.setSize(caminfo->mps);
    uint8_t buf[26];
    memset(buf, 0, sizeof(buf));
    buf[2] = caminfo->formatIndex;
    buf[3] = caminfo->frameIndex;
    *reinterpret_cast<uint32_t*>(buf+4) = caminfo->interval;
    USB_TYPE res = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, sizeof(buf));
    if (res != USB_TYPE_OK) {
         CAM_DBG("SET_CUR VS_COMMIT_CONTROL FAILED");
    }
    res = setInterfaceAlternate(1, caminfo->if_alt);
    if (res != USB_TYPE_OK) {
         CAM_DBG("SET_INTERFACE FAILED");
    }
}

#define SEQ_READ_IDOL 0
#define SEQ_READ_EXEC 1
#define SEQ_READ_DONE 2

int USBHostCam::readJPEG(uint8_t* buf, int size, int timeout_ms) {
    _buf = buf;
    _pos = 0;
    _size = size;
    _seq = SEQ_READ_IDOL;
    setOnResult(this, &USBHostCam::callback_motion_jpeg);
    Timer timeout_t;
    timeout_t.reset();
    timeout_t.start();
    while(timeout_t.read_ms() < timeout_ms && _seq != SEQ_READ_DONE) {
        poll();
    } 
    return _pos;
}

/* virtual */ void USBHostCam::outputJPEG(uint8_t c, int status) { // from decodeMJPEG
    if (_seq == SEQ_READ_IDOL) {
        if (status == JPEG_START) {
            _pos = 0;
            _seq = SEQ_READ_EXEC;
        }
    }
    if (_seq == SEQ_READ_EXEC) {
        if (_pos < _size) {
            _buf[_pos++] = c;  
        }  
        if (status == JPEG_END) {
            _seq = SEQ_READ_DONE;
        }
    }
}

void USBHostCam::callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) {
        inputPacket(buf, len);
}