\r
MULTI_DEBUG_CHANNEL(tizen, camera_linux);\r
\r
-#define MARUCAM_SKIPFRAMES 2\r
-\r
enum {\r
_MC_THREAD_PAUSED,\r
_MC_THREAD_STREAMON,\r
static int __v4l2_grab(MaruCamState *state)\r
{\r
fd_set fds;\r
- static uint32_t index = 0;\r
struct timeval tv;\r
void *buf;\r
int ret;\r
if (!is_streamon(state))\r
return -1;\r
\r
- buf = state->vaddr + (state->buf_size * index);\r
+ qemu_mutex_lock(&state->thread_mutex);\r
+ if (ready_count < MARUCAM_SKIPFRAMES) {\r
+ ++ready_count; /* skip a frame cause first some frame are distorted */\r
+ qemu_mutex_unlock(&state->thread_mutex);\r
+ return 0;\r
+ }\r
+ if (state->req_frame == 0) {\r
+ qemu_mutex_unlock(&state->thread_mutex);\r
+ return 0;\r
+ }\r
+ buf = state->vaddr + state->buf_size * (state->req_frame -1);\r
+ qemu_mutex_unlock(&state->thread_mutex);\r
+\r
ret = v4l2_read(v4l2_fd, buf, state->buf_size);\r
if ( ret < 0) {\r
switch (errno) {\r
}\r
}\r
\r
- index = !index;\r
-\r
qemu_mutex_lock(&state->thread_mutex);\r
if (state->streamon == _MC_THREAD_STREAMON) {\r
- if (ready_count >= MARUCAM_SKIPFRAMES) {\r
- if (state->req_frame) {\r
- state->req_frame = 0; // clear request\r
- state->isr |= 0x01; // set a flag of rasing a interrupt.\r
- qemu_bh_schedule(state->tx_bh);\r
- }\r
- ret = 1;\r
- } else {\r
- ++ready_count; // skip a frame cause first some frame are distorted.\r
- ret = 0;\r
- }\r
+ state->req_frame = 0; /* clear request */\r
+ state->isr |= 0x01; /* set a flag of rasing a interrupt */\r
+ qemu_bh_schedule(state->tx_bh);\r
+ ret = 1;\r
} else {\r
ret = -1;\r
}\r
- qemu_mutex_unlock(&state->thread_mutex);\r
\r
+ qemu_mutex_unlock(&state->thread_mutex);\r
return ret;\r
}\r
\r
\r
MULTI_DEBUG_CHANNEL(tizen, camera_win32);\r
\r
+extern int hax_enabled(void);\r
+\r
/*\r
* COM Interface implementations\r
*\r
\r
IGrabCallback *g_pCallback;\r
\r
-DWORD g_dwFourcc;\r
-LONG g_dwWidth;\r
-LONG g_dwHeight;\r
-\r
// V4L2 defines copy from videodev2.h\r
#define V4L2_CTRL_FLAG_SLIDER 0x0020\r
\r
*/\r
static STDMETHODIMP marucam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)\r
{\r
- static uint32_t index = 0;\r
+ void *tmp_buf;\r
uint32_t width, height;\r
+\r
+ qemu_mutex_lock(&g_state->thread_mutex);\r
+ if (ready_count < MARUCAM_SKIPFRAMES) {\r
+ ++ready_count; /* skip a frame cause first some frame are distorted */\r
+ qemu_mutex_unlock(&g_state->thread_mutex);\r
+ return S_OK;\r
+ }\r
+ if (g_state->req_frame == 0) {\r
+ qemu_mutex_unlock(&g_state->thread_mutex);\r
+ return S_OK;\r
+ }\r
+ tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1);\r
+ qemu_mutex_unlock(&g_state->thread_mutex);\r
+\r
width = supported_dst_frames[cur_frame_idx].width;\r
height = supported_dst_frames[cur_frame_idx].height;\r
- void *buf = g_state->vaddr + (g_state->buf_size * index);\r
\r
switch (supported_dst_pixfmts[cur_fmt_idx].fmt) {\r
case V4L2_PIX_FMT_YUV420:\r
- v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 0);\r
+ v4lconvert_yuyv_to_yuv420(pBuffer, tmp_buf, width, height, 0);\r
break;\r
case V4L2_PIX_FMT_YVU420:\r
- v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 1);\r
+ v4lconvert_yuyv_to_yuv420(pBuffer, tmp_buf, width, height, 1);\r
break;\r
case V4L2_PIX_FMT_YUYV:\r
- memcpy(buf, (void*)pBuffer, dwSize);\r
+ memcpy(tmp_buf, (void*)pBuffer, (size_t)dwSize);\r
break;\r
}\r
- index = !index;\r
\r
qemu_mutex_lock(&g_state->thread_mutex);\r
- if (ready_count >= 4) {\r
- if (g_state->req_frame) {\r
- g_state->req_frame = 0; // clear request\r
- g_state->isr |= 0x01; // set a flag raising a interrupt.\r
- qemu_bh_schedule(g_state->tx_bh);\r
- }\r
- } else {\r
- ++ready_count; // skip a frame cause first some frame are distorted.\r
- }\r
+ g_state->req_frame = 0; /* clear request */\r
+ g_state->isr |= 0x01; /* set a flag raising a interrupt. */\r
+ qemu_bh_schedule(g_state->tx_bh);\r
qemu_mutex_unlock(&g_state->thread_mutex);\r
return S_OK;\r
}\r
return hr;\r
}\r
\r
-static STDMETHODIMP SetDefaultValues(void)\r
+/* default fps is 15 */\r
+#define MARUCAM_DEFAULT_FRAMEINTERVAL 666666\r
+\r
+static STDMETHODIMP SetFormat(uint32_t dwWidth, uint32_t dwHeight,\r
+ uint32_t dwFourcc)\r
{\r
HRESULT hr;\r
IAMStreamConfig *pSConfig;\r
int iCount = 0, iSize = 0;\r
\r
- hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0, g_pSrcFilter, &IID_IAMStreamConfig, (void**)&pSConfig);\r
+ if (dwFourcc == 0) {\r
+ dwFourcc = MAKEFOURCC('Y','U','Y','2');\r
+ }\r
+\r
+ hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0,\r
+ g_pSrcFilter, &IID_IAMStreamConfig,\r
+ (void**)&pSConfig);\r
if (FAILED(hr)) {\r
ERR("failed to FindInterface method\n");\r
return hr;\r
VIDEO_STREAM_CONFIG_CAPS scc;\r
AM_MEDIA_TYPE *pmtConfig;\r
\r
- hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig, (BYTE*)&scc);\r
+ hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig,\r
+ (BYTE*)&scc);\r
if (hr == S_OK)\r
{\r
if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo))\r
{\r
- VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;\r
- if ((pvi->bmiHeader.biWidth == g_dwWidth) &&\r
- (pvi->bmiHeader.biHeight == g_dwHeight) &&\r
- (pvi->bmiHeader.biCompression == g_dwFourcc))\r
+ VIDEOINFOHEADER *pvi =\r
+ (VIDEOINFOHEADER *)pmtConfig->pbFormat;\r
+ if ((pvi->bmiHeader.biWidth == (LONG)dwWidth) &&\r
+ (pvi->bmiHeader.biHeight == (LONG)dwHeight) &&\r
+ (pvi->bmiHeader.biCompression == (DWORD)dwFourcc))\r
{\r
+ /* use minimum FPS(maximum frameinterval)\r
+ with non-VT system */\r
+ if (!hax_enabled()) {\r
+ pvi->AvgTimePerFrame =\r
+ (REFERENCE_TIME)scc.MaxFrameInterval;\r
+ } else {\r
+ pvi->AvgTimePerFrame =\r
+ (REFERENCE_TIME)MARUCAM_DEFAULT_FRAMEINTERVAL;\r
+ }\r
hr = pSConfig->lpVtbl->SetFormat(pSConfig, pmtConfig);\r
DeleteMediaType(pmtConfig);\r
- INFO("Setting default values.\n");\r
break;\r
}\r
}\r
}\r
}\r
if (iFormat >= iCount) {\r
- ERR("Maybe connected webcam does not support %ld x %ld resolution.\n", g_dwWidth, g_dwHeight);\r
+ ERR("Failed to Set format. "\r
+ "Maybe connected webcam does not support "\r
+ "(%ldx%ld) resolution or YUY2 image format.\n",\r
+ dwWidth, dwHeight);\r
hr = E_FAIL;\r
}\r
}\r
return hr;\r
}\r
\r
-static STDMETHODIMP SetResolution(LONG width, LONG height)\r
-{\r
- HRESULT hr;\r
- IAMStreamConfig* vsc = NULL;\r
- AM_MEDIA_TYPE* pmt = NULL;\r
-\r
- hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, g_pSrcFilter, &IID_IAMStreamConfig, (void**)&vsc);\r
- if (FAILED(hr))\r
- return hr;\r
-\r
- hr = vsc->lpVtbl->GetFormat(vsc, &pmt);\r
- if (FAILED(hr))\r
- {\r
- vsc->lpVtbl->Release(vsc);\r
- return hr;\r
- }\r
-\r
- if (pmt != NULL)\r
- {\r
- if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))\r
- {\r
- VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
- pvi->bmiHeader.biWidth = width;\r
- pvi->bmiHeader.biHeight = height;\r
- pvi->bmiHeader.biSizeImage = ((width * pvi->bmiHeader.biBitCount) >> 3 ) * height;\r
- hr = vsc->lpVtbl->SetFormat(vsc, pmt);\r
- if (hr != S_OK) {\r
- ERR("failed to set the resolution.(w:%ld, h:%ld), Maybe connected webcam does not support the resolution.\n", width, height);\r
- }\r
- }\r
- DeleteMediaType(pmt);\r
- }\r
- vsc->lpVtbl->Release(vsc);\r
- return hr;\r
-}\r
-\r
static STDMETHODIMP QueryVideoProcAmp(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault)\r
{\r
HRESULT hr;\r
void marucam_device_open(MaruCamState* state)\r
{\r
HRESULT hr;\r
+ uint32_t dwHeight, dwWidth;\r
MaruCamParam *param = state->param;\r
param->top = 0;\r
\r
goto error_failed;\r
}\r
\r
- g_dwFourcc = MAKEFOURCC('Y','U','Y','2');\r
- g_dwHeight = 480;\r
- g_dwWidth = 640;\r
- hr = SetDefaultValues();\r
+ cur_frame_idx = 0;\r
+ cur_fmt_idx = 0;\r
+\r
+ dwHeight = supported_dst_frames[cur_frame_idx].height;\r
+ dwWidth = supported_dst_frames[cur_frame_idx].width;\r
+ hr = SetFormat(dwWidth, dwHeight, 0);\r
if (hr != S_OK) {\r
- ERR("SetDefaultValues\n");\r
+ ERR("failed to Set default values\n");\r
goto error_failed;\r
}\r
- cur_frame_idx = 0;\r
- cur_fmt_idx = 0;\r
\r
INFO("Open successfully!!!\n");\r
return;\r
\r
if ((supported_dst_frames[cur_frame_idx].width != width) &&\r
(supported_dst_frames[cur_frame_idx].height != height)) {\r
- HRESULT hr = SetResolution((LONG)width, (LONG)height);\r
+ HRESULT hr = SetFormat(width, height, 0);\r
if (FAILED(hr)) {\r
param->errCode = EINVAL;\r
return;\r
}\r
- g_dwWidth = (LONG)width;\r
- g_dwHeight = (LONG)height;\r
}\r
\r
param->stack[0] = width;\r