📄 usbvideo_drv.c
字号:
g_USBVideo.video_control.send_video_msg = KAL_TRUE;
g_USBVideo.video_control.sent_video_size = 0;
g_USBVideo.video_control.video_frame_id = 0;
g_USBVideo.video_control.incall_jpeg_buff = get_ctrl_buffer(USBVIDEO_MAX_PAYLOAD_LENGTH);
g_USBVideo.video_control.b_processing_dma = KAL_FALSE;
/* Start GPT timer 3 for PTS */
GPT_Start(3);
if(g_USBVideo.video_control.timer_handle==0)
GPTI_GetHandle(&g_USBVideo.video_control.timer_handle);
#ifdef WEBCAM_TEST_DMA_DELAY
if(g_USBVideo.test_timer_handle==0)
GPTI_GetHandle(&g_USBVideo.test_timer_handle);
g_USBVideo.test_enable = KAL_FALSE;
#endif
}
/* release global variable g_USBVideo */
void USB_Release_Video_Status(void)
{
kal_prompt_trace(MOD_USB, "Release video\n");
/* release g_USBVideo resource */
g_USBVideo.txpipe = NULL;
g_USBVideo.intrpipe = NULL;
g_USBVideo.vs_interface_id = 0;
g_USBVideo.vc_ct_support = 0;
g_USBVideo.vc_ct_set = 0;
g_USBVideo.vc_pu_support = 0;
g_USBVideo.vc_pu_set = 0;
g_USBVideo.state = USBVIDEO_STATE_STOP;
g_USBVideo.commit_video_index = 0;
g_USBVideo.probe_state = USBVIDEO_PROBE_NONE;
g_USBVideo.commit_still_index = 0;
g_USBVideo.still_probe_state = USBVIDEO_PROBE_NONE;
g_USBVideo.video_start_state = USBVIDEO_START_NONE;
g_USBVideo.video_control.video_buffer_addr[0] = NULL;
g_USBVideo.video_control.video_buffer_read_index = 0;
g_USBVideo.video_control.video_buffer_write_index = 0;
g_USBVideo.video_control.video_buffer_full = KAL_FALSE;
g_USBVideo.video_control.send_video_msg = KAL_TRUE;
g_USBVideo.video_control.sent_video_size = 0;
g_USBVideo.video_control.video_frame_id = 0;
if(g_USBVideo.video_control.incall_jpeg_buff!=NULL)
free_ctrl_buffer(g_USBVideo.video_control.incall_jpeg_buff);
g_USBVideo.video_control.incall_jpeg_buff = NULL;
g_USBVideo.video_control.b_processing_dma = KAL_FALSE;
/* Stop GPT timer */
GPT_Stop(3);
GPTI_StopItem(g_USBVideo.video_control.timer_handle);
#ifdef WEBCAM_TEST_DMA_DELAY
GPTI_StopItem(g_USBVideo.test_timer_handle);
#endif
}
/************************************************************
EP0 command parse functions
*************************************************************/
/* Rx handler for set attribute control */
static void USBVideo_Set_Attr(void *data)
{
kal_uint32 nCount;
kal_uint8 recv[8];
usbvideo_attr_msg_struct *attr_req;
kal_uint32 index, index2;
kal_uint32 subtype_num;
kal_uint32 process_num;
ilm_struct *send_ilm;
const USBVideo_Attr_Map *attr_map;
kal_uint8 *subtype_cnf;
kal_uint8 attr_index;
module_type dest_mod;
#if ( (defined(__WEBCAM_CAMERA_TEST__)) || (defined(__WEBCAM_USB_TEST__)) )
dest_mod = MOD_CUSTOM1;
#else
dest_mod = MOD_MED;
#endif
nCount = USB_EP0_Pkt_Len();
if(nCount > 0)
{
USB_EPFIFORead(0, nCount, recv);
if((g_USBVideo.set_attr_value.type&0x80)==0)
{
/* camera terminal attribute */
attr_map = g_USBVideo_CT_Attr_Map;
subtype_cnf = g_USBVideo.vc_ct_subtype_cnf;
attr_index = g_USBVideo.set_attr_value.type - 1;
}
else
{
/* processing unit attribute*/
attr_map = g_USBVideo_PU_Attr_Map;
subtype_cnf = g_USBVideo.vc_pu_subtype_cnf;
attr_index = (g_USBVideo.set_attr_value.type&(~0x80)) - 1;
}
process_num = 0;
subtype_cnf[attr_index] = 0;
if(attr_map[attr_index].subtype_table!=NULL)
{
/* has subtype for the current attribute type */
subtype_num = sizeof(attr_map[attr_index].subtype_table)/sizeof(USBVideo_Attr_Sub_Map);
for(index = 0; index < subtype_num; index++)/* how many subtype */
{
g_USBVideo.set_attr_value.value = 0;
g_USBVideo.set_attr_value.subtype = attr_map[attr_index].subtype_table[index].subtype;
for(index2 = 0; index2 < attr_map[attr_index].subtype_table[index].length; index2++)/*each subtype's length*/
{
/* For value larger than one byte */
g_USBVideo.set_attr_value.value += (recv[index2+process_num]<<(index2*8));
}
attr_req = (usbvideo_attr_msg_struct*)construct_local_para(
sizeof(usbvideo_attr_msg_struct), TD_CTRL);
kal_mem_cpy(&attr_req->attr_value, &g_USBVideo.set_attr_value, sizeof(USBVideo_Attr_Value));
DRV_BuildPrimitive(send_ilm, /* one subtype, one message */
MOD_DRV_HISR,
dest_mod,
MSG_ID_USB_MED_SET_CAMERA_ATTR_REQ,
attr_req);
msg_send_ext_queue(send_ilm);
process_num+=index2;
subtype_cnf[attr_index] |= (1<<index);
}
}
else
{
/* Do not have subtype for the current attribute type */
g_USBVideo.set_attr_value.value = 0;
g_USBVideo.set_attr_value.subtype = 0;
for(index = 0; index < attr_map[attr_index].length; index++)
{
/* For value larger than one byte */
g_USBVideo.set_attr_value.value += (recv[index]<<(index*8));
}
attr_req = (usbvideo_attr_msg_struct*)construct_local_para(
sizeof(usbvideo_attr_msg_struct), TD_CTRL);
kal_mem_cpy(&attr_req->attr_value, &g_USBVideo.set_attr_value, sizeof(USBVideo_Attr_Value));
DRV_BuildPrimitive(send_ilm,
MOD_DRV_HISR,
dest_mod,
MSG_ID_USB_MED_SET_CAMERA_ATTR_REQ,
attr_req);
msg_send_ext_queue(send_ilm);
}
gUsbDevice.ep0_state = USB_EP0_RX_STATUS;
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_FALSE, KAL_TRUE);
USB_Register_EP0_RxHdlr(NULL);
}
}
/* Rx handler for video probe and commit control */
static void USBVideo_Set_ProbControl(void *data)
{
kal_uint32 nCount;
static kal_uint32 nTotal = 0;
static kal_uint8 recv[8];
const USBVideo_Video_Size_Info *p_video_size_param;
kal_uint8 video_size_num;
kal_uint32 max_frame_size;
kal_uint32 savedMask;
kal_bool b_change_size = KAL_FALSE;
kal_bool b_sendmsg = KAL_FALSE;
USBVIDEO_DMA_TYPE dma_type;
p_video_size_param = g_USBVideo.video_control.p_video_size_info; /* be set at USBVideo_VS_If_Create() */
video_size_num = g_USBVideo.video_control.video_size_num;
/* read setting and set video setting*/
nCount = USB_EP0_Pkt_Len(); /* because ep0 get 8 bytes at a time */
if(nCount > 0)
{
USB_EPFIFORead(0, nCount, recv);
/* check illegal probe length */
if((nTotal+nCount) > 26)
//if((nTotal+nCount) > 34)
{
#ifndef __PRODUCTION_RELEASE__
EXT_ASSERT(0, nTotal, nCount, 0);
#endif
/* illegal probe length */
gUsbDevice.ep0_state = USB_EP0_RX_STATUS;
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_TRUE);
USB_Register_EP0_RxHdlr(NULL);
nTotal = 0;
return;
}
kal_mem_cpy(&((kal_uint8*)&g_USBVideo.vs_recv_probe_control)[nTotal], recv, nCount);
nTotal+=nCount;
if(nTotal == 26) /* All probe control are received */
//if( (nTotal == 34) ||(nTotal == 26) )
{
if(g_USBVideo.vs_recv_probe_control.bFrameIndex!=g_USBVideo.vs_probe_control.bFrameIndex)
{
/* update current frame index if PC request for a new one */
if(g_USBVideo.vs_recv_probe_control.bFrameIndex > video_size_num)
EXT_ASSERT(0, g_USBVideo.vs_recv_probe_control.bFrameIndex, video_size_num, 0);
g_USBVideo.vs_probe_control.bFrameIndex = g_USBVideo.vs_recv_probe_control.bFrameIndex;
g_USBVideo.vs_probe_control.dwFrameInterval[0] = p_video_size_param[g_USBVideo.vs_probe_control.bFrameIndex-1].default_frame_interval&0xff;
g_USBVideo.vs_probe_control.dwFrameInterval[1] = (p_video_size_param[g_USBVideo.vs_probe_control.bFrameIndex-1].default_frame_interval>>8)&0xff;
g_USBVideo.vs_probe_control.dwFrameInterval[2] = (p_video_size_param[g_USBVideo.vs_probe_control.bFrameIndex-1].default_frame_interval>>16)&0xff;
g_USBVideo.vs_probe_control.dwFrameInterval[3] = (p_video_size_param[g_USBVideo.vs_probe_control.bFrameIndex-1].default_frame_interval>>24)&0xff;
max_frame_size = USBVideo_Get_Max(p_video_size_param[g_USBVideo.vs_probe_control.bFrameIndex-1].max_frame_size,
g_USBVideo.video_control.default_jpeg_max_size[g_USBVideo.vs_probe_control.bFrameIndex-1]);
g_USBVideo.vs_probe_control.dwMaxVideoFrameSize[0] = max_frame_size&0xff;
g_USBVideo.vs_probe_control.dwMaxVideoFrameSize[1] = (max_frame_size>>8)&0xff;
g_USBVideo.vs_probe_control.dwMaxVideoFrameSize[2] = (max_frame_size>>16)&0xff;
g_USBVideo.vs_probe_control.dwMaxVideoFrameSize[3] = (max_frame_size>>24)&0xff;
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
}
if(g_USBVideo.probe_state == USBVIDEO_PROBE_IN)
g_USBVideo.probe_state = USBVIDEO_PROBE_DONE;
else if(g_USBVideo.probe_state == USBVIDEO_COMMIT_IN)
{
if(g_USBVideo.commit_video_index != g_USBVideo.vs_probe_control.bFrameIndex) /* 0 by default*/
{
g_USBVideo.commit_video_index = g_USBVideo.vs_probe_control.bFrameIndex;
b_change_size = KAL_TRUE;
}
else
b_change_size = KAL_FALSE;
g_USBVideo.probe_state = USBVIDEO_COMMIT_DONE;
g_USBVideo.video_compression_index = g_USBVideo.camera_param->usbvideo_get_default_compression_index();
/* In case another un-support still image application is opened,
so reset the still probe state when recv new probe commit */
if(g_USBVideo.still_probe_state == USBVIDEO_COMMIT_DONE)
{
kal_prompt_trace(MOD_DRV_HISR, "probe v still commit 0\n");
g_USBVideo.still_probe_state = USBVIDEO_PROBE_NONE;
g_USBVideo.commit_still_index = 0;
}
if(g_USBVideo.state == USBVIDEO_STATE_STOP)
{
USBVideo_Send_Msg(USBVIDEO_MSG_USB_ENUM_DONE, 0, 0);
}
else if ((g_USBVideo.state == USBVIDEO_STATE_SEND) || (g_USBVideo.state == USBVIDEO_STATE_DROP))
{
if(b_change_size==KAL_TRUE)
{
USBVideo_Send_Msg(USBVIDEO_MSG_USB_CHANGE_SIZE, 0, 0);
/* 1103 add, in case win2000 MSN send commit twice*/
/* Avoid race condition with DMA HISR */
savedMask = SaveAndSetIRQMask();
g_USBVideo.state = USBVIDEO_STATE_DROP;
/* stop DMA if it is on */
if(USB_DMA_Get_Run_Status(g_USBVideo.txpipe->byEP)==KAL_TRUE)
{
USB_Stop_DMA_Channel(g_USBVideo.txpipe->byEP);
/* clear FIFO, if not clear it, the next packet may be false */
USB_Clear_IN_EP_FIFO(g_USBVideo.txpipe->byEP);
/* clear dma running state here*/
USB_DMA_Set_Run_Status(g_USBVideo.txpipe->byEP, KAL_FALSE);
g_USBVideo.video_control.sent_video_size = 0;
g_USBVideo.video_control.video_buffer_write_index = 0;
g_USBVideo.video_control.video_buffer_read_index = 0;
g_USBVideo.video_control.video_buffer_full = KAL_FALSE;
g_USBVideo.video_control.send_video_msg = KAL_TRUE;
}
RestoreIRQMask(savedMask);
}
else
{
b_sendmsg = KAL_FALSE;
savedMask = SaveAndSetIRQMask();
/* stop DMA if it is on */
if(USB_DMA_Get_Run_Status(g_USBVideo.txpipe->byEP)==KAL_TRUE)
{
USB_Stop_DMA_Channel(g_USBVideo.txpipe->byEP);
/* clear FIFO, if not clear it, the next packet may be false */
USB_Clear_IN_EP_FIFO(g_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -