📄 usbvideo_state.c
字号:
{
//p_incall_param = g_USBVideo.mmi_param->usbvideo_get_incall_jpeg_info(&incall_size_num);
p_default_jpeg = g_USBVideo.default_jpeg_info;
savedMask = SaveAndSetIRQMask();
g_USBVideo.video_control.incall_jpeg_addr = p_default_jpeg[g_USBVideo.commit_video_index - 1].start_addr;
g_USBVideo.video_control.incall_jpeg_size = p_default_jpeg[g_USBVideo.commit_video_index - 1].size;
RestoreIRQMask(savedMask);
g_USBVideo.video_control.dma_type = USBVIDEO_DMA_INCALL_JPEG;
USBVideo_Send_Incall_JPEG();
}
}
/* GPT timeout function for incall setting*/
static void USBVideo_Incall_Timeout(void *parameter)
{
GPTI_StopItem(g_USBVideo.video_control.timer_handle);
USBVideo_Send_Msg(USBVIDEO_MSG_USB_INCALL_TIMEOUT, 0, 0);
}
/* Handler for incall JPEG DMA done from DMA HISR */
static void USBVideo_InCall_DMA_Done_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
kal_bool bBufferEmpty = KAL_FALSE;
kal_uint32 savedMask;
usbvideo_default_JPEG_Info*p_default_jpeg;
kal_uint32 total_size;
kal_bool bEPEmpty;
kal_uint32 count;
if(g_USBVideo.state==USBVIDEO_STATE_STILL)
EXT_ASSERT(0, (kal_uint32)g_USBVideo.state, 0, 0);
if(g_USBVideo.state == USBVIDEO_STATE_STOP)
return;
if(g_USBVideo.video_control.dma_done_type == USBVIDEO_DMA_DONE_COMPLETE)
{
/* send NULL packet only when dma done type is complete */
p_default_jpeg = g_USBVideo.default_jpeg_info;
total_size = p_default_jpeg[g_USBVideo.commit_video_index - 1].size;
count = total_size/(USBVIDEO_MAX_PAYLOAD_LENGTH -USBVIDEO_PAYLOAD_HEADER_LENGTH);
if(total_size%(USBVIDEO_MAX_PAYLOAD_LENGTH -USBVIDEO_PAYLOAD_HEADER_LENGTH)!=0)
count++;
if(((total_size+count*USBVIDEO_PAYLOAD_HEADER_LENGTH)%USB_EP_BULK_MAXP) == 0)
{
/* multiple of 64 bytes */
/* make sure previous packets are already sent out
maybe last DMA data has triggered DMA done but data are still in FIFO*/
bEPEmpty = USB_Is_EP_Bulk_In_Empty(g_USBVideo.txpipe->byEP);
/* If cable plug out at this time, add timeout to avoid looping here */
while((bEPEmpty == KAL_FALSE)&&(count<100))
{
count++;
kal_sleep_task(1);
bEPEmpty = USB_Is_EP_Bulk_In_Empty(g_USBVideo.txpipe->byEP);
}
/* send out a NULL packet */
USB_EPFIFOWrite(g_USBVideo.txpipe->byEP, 0, NULL);
USB_EP_Bulk_In_Ready(g_USBVideo.txpipe->byEP);
/* mak sure previous NULL pkt has been sent out
avoid next DMA data in FIFO sent out instead of previos NULL pkt.*/
bEPEmpty = USB_Is_EP_Bulk_In_Empty(g_USBVideo.txpipe->byEP);
/* If cable plug out at this time, add timeout to avoid looping here */
count = 0;
while((bEPEmpty == KAL_FALSE)&&(count<100))
{
count++;
kal_sleep_task(1);
bEPEmpty = USB_Is_EP_Bulk_In_Empty(g_USBVideo.txpipe->byEP);
}
}
}
/* Note that if pause and then resume, without open PC application, and then pause again, pre_pause state may happen */
if(g_USBVideo.state == USBVIDEO_STATE_PRE_PAUSE)
{
/* stop pre-pause timer */
GPTI_StopItem(g_USBVideo.video_control.timer_handle);
g_USBVideo.state = USBVIDEO_STATE_PAUSE;
USBVideo_Send_Msg(USBVIDEO_MSG_MED_PAUSE_CNF, (kal_uint32)KAL_TRUE, 0);
//p_default_jpeg = g_USBVideo.mmi_param->usbvideo_get_incall_jpeg_info(&incall_size_num);
p_default_jpeg = g_USBVideo.default_jpeg_info;
savedMask = SaveAndSetIRQMask();
g_USBVideo.video_control.still_count = 0;
g_USBVideo.video_control.sent_video_size = 0;
g_USBVideo.video_control.incall_jpeg_addr = p_default_jpeg[g_USBVideo.commit_video_index - 1].start_addr;
g_USBVideo.video_control.incall_jpeg_size = p_default_jpeg[g_USBVideo.commit_video_index - 1].size;
RestoreIRQMask(savedMask);
g_USBVideo.video_control.dma_type = USBVIDEO_DMA_INCALL_JPEG;
USBVideo_Send_Incall_JPEG();
}
else if(g_USBVideo.state==USBVIDEO_STATE_PAUSE)
{
savedMask = SaveAndSetIRQMask();
g_USBVideo.video_control.sent_video_size = 0;
RestoreIRQMask(savedMask);
/* start a timer to periodicaly send this image to PC */
if(g_USBVideo.video_control.b_stop_timer == KAL_FALSE)
GPTI_StartItem(g_USBVideo.video_control.timer_handle, USBVIDEO_INCALL_JPEG_TIMEOUT, USBVideo_Incall_Timeout, NULL);
}
else if((g_USBVideo.state==USBVIDEO_STATE_SEND) ||(g_USBVideo.state==USBVIDEO_STATE_DROP))
{
savedMask = SaveAndSetIRQMask();
g_USBVideo.video_control.sent_video_size = 0;
/* receive resume msg and back to send state */
if(g_USBVideo.video_control.video_buffer_read_index==g_USBVideo.video_control.video_buffer_write_index)
{
/* buffer empty */
bBufferEmpty = KAL_TRUE;
g_USBVideo.video_control.send_video_msg = KAL_TRUE;
}
RestoreIRQMask(savedMask);
if(bBufferEmpty==KAL_FALSE)
{
g_USBVideo.video_control.dma_type = USBVIDEO_DMA_VIDEO;
USBVideo_Send_Video();
}
}
}
static void USBVideo_InCall_Change_Size_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
kal_uint32 savedMask;
kal_bool b_sendmsg = KAL_FALSE;
if(g_USBVideo.state != USBVIDEO_STATE_PAUSE)
return;
savedMask = SaveAndSetIRQMask();
/* If DMA is running, there will be done message trigger next image */
if(USB_DMA_Get_Run_Status(g_USBVideo.txpipe->byEP)==KAL_FALSE)
{
g_USBVideo.video_control.b_stop_timer = KAL_FALSE;
GPTI_StopItem(g_USBVideo.video_control.timer_handle);
b_sendmsg = KAL_TRUE;
}
RestoreIRQMask(savedMask);
if(b_sendmsg==KAL_TRUE)
USBVideo_Send_Msg(USBVIDEO_MSG_USB_INCALL_TIMEOUT, 0, 0);
}
/* Handler for resume request from media task */
static void USBVideo_Resume_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
usbvideo_video_req_struct *video_req;
kal_uint32 savedMask;
const USBVideo_Video_Size_Info *p_video_size_param;
const USBVideo_Still_Size_Info *p_still_size_param;
kal_uint8 video_size_num;
kal_uint8 still_size_num;
kal_uint32 index;
if((g_USBVideo.state==USBVIDEO_STATE_SEND) || (g_USBVideo.state==USBVIDEO_STATE_STILL)
|| (g_USBVideo.state==USBVIDEO_STATE_DROP) || (g_USBVideo.state==USBVIDEO_STATE_PRE_PAUSE))
EXT_ASSERT(0, (kal_uint32)g_USBVideo.state, 0, 0);
if(g_USBVideo.state == USBVIDEO_STATE_STOP)
{
USBVideo_Send_Msg(USBVIDEO_MSG_MED_RESUME_FAIL_CNF, 0, 0);
return;
}
/* The resume requset must wait for pause request confirm no matter success or not */
//if((g_USBVideo.state==USBVIDEO_STATE_PAUSE) || (g_USBVideo.state==USBVIDEO_STATE_PRE_PAUSE) )
if(g_USBVideo.state==USBVIDEO_STATE_PAUSE)
{
GPTI_StopItem(g_USBVideo.video_control.timer_handle);
g_USBVideo.state = USBVIDEO_STATE_SEND;
savedMask = SaveAndSetIRQMask();
if(USB_DMA_Get_Run_Status(g_USBVideo.txpipe->byEP)==KAL_FALSE)
g_USBVideo.video_control.send_video_msg = KAL_TRUE;
else
g_USBVideo.video_control.send_video_msg = KAL_FALSE; /* let incall dma done to start video */
video_req=(usbvideo_video_req_struct *)p_recv_ilm->local_para_ptr;
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.sent_video_size = 0;
//g_USBVideo.video_control.video_frame_id = 0;
/* 4-bytes align, the jpeg need 4-bytes alignment buffer */
g_USBVideo.video_control.video_buffer_addr[0] = (kal_uint8*)(((kal_uint32)video_req->buffer_addr + (4-1))&(~(4-1)));
g_USBVideo.video_control.video_buffer_size = (video_req->buffer_size - ((4-1)*USBVIDEO_VIDEO_BUFFER_NUMBER))/USBVIDEO_VIDEO_BUFFER_NUMBER;
/* 4-bytes align, the jpeg need 4-bytes alignment buffer */
g_USBVideo.video_control.video_buffer_size = (g_USBVideo.video_control.video_buffer_size + (4-1))& (~(4-1));
for(index = 1; index < USBVIDEO_VIDEO_BUFFER_NUMBER; index++)
{
g_USBVideo.video_control.video_buffer_addr[index] = g_USBVideo.video_control.video_buffer_addr[index - 1] + g_USBVideo.video_control.video_buffer_size;
}
RestoreIRQMask(savedMask);
/* chek the video buffer size larger than all custom camera video buffer, and still size also */
p_video_size_param = g_USBVideo.camera_param->usbvideo_get_video_size_info(&video_size_num);
p_still_size_param = g_USBVideo.camera_param->usbvideo_get_still_size_info(&still_size_num);
for(index = 0; index < video_size_num; index++)
{
if(g_USBVideo.video_control.video_buffer_size < (p_video_size_param[index].max_frame_size+USBVIDEO_PAYLOAD_HEADER_LENGTH))
{
EXT_ASSERT(0, g_USBVideo.video_control.video_buffer_size, index, p_video_size_param[index].max_frame_size);
}
}
for(index = 0; index < still_size_num; index++)
{
if(video_req->buffer_size < (p_still_size_param[index].max_frame_size+USBVIDEO_PAYLOAD_HEADER_LENGTH))
{
EXT_ASSERT(0, video_req->buffer_size, index, p_still_size_param[index].max_frame_size);
}
}
USBVideo_Send_Msg(USBVIDEO_MSG_MED_RESUME_SUCCESS_CNF, g_USBVideo.commit_video_index, g_USBVideo.video_compression_index);
}
}
/* Handler for stop request from media task */
static void USBVideo_Stop_Req_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
g_USBVideo.state = USBVIDEO_STATE_STOP;
USBVideo_Send_Msg(USBVIDEO_MSG_MED_STOP_CNF, (kal_uint32)KAL_TRUE, 0);
}
/* Handler for reset/abort indication from USB HISR, reset if not stop state, msut abort to update state */
static void USBVideo_Abort_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
g_USBVideo.state = USBVIDEO_STATE_STOP;
USBVideo_Send_Msg(USBVIDEO_MSG_MED_ABORT_IND, 0, 0);
}
/* Handler for USB cable plug out indication from EINT HISR */
void USBVideo_Plug_Out_Hdlr(void)
{
if(g_USBVideo.video_start_state == USBVIDEO_START_RECV_MED_REQ)
{
/* media task is waiting for this fail confirm*/
USBVideo_Send_Msg(USBVIDEO_MSG_MED_START_FAIL_CNF, 0, 0);
g_USBVideo.video_start_state = USBVIDEO_START_NONE;
}
if(g_USBVideo.state==USBVIDEO_STATE_PRE_PAUSE)
{
GPTI_StopItem(g_USBVideo.video_control.timer_handle);
USBVideo_Send_Msg(USBVIDEO_MSG_MED_PAUSE_CNF, (kal_uint32)KAL_FALSE, 0);
}
g_USBVideo.state = USBVIDEO_STATE_STOP;
USBVideo_Send_Msg(USBVIDEO_MSG_MED_STOP_IND, 0, 0);
}
/* Parse all messages from USB HISR, DMA HISR, camera HISR, and media task */
void USBVideo_Parse_Med_Msg(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
switch(p_recv_ilm->msg_id)
{
case MSG_ID_USB_MED_SET_CAMERA_ATTR_CNF:
USBVideo_Attr_Cnf_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_ENUM_DONE:
USBVideo_Enum_Done_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_MED_USB_START_VIDEO_REQ:
USBVideo_Start_Video_Req_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_CHANGE_SIZE:
USBVideo_Change_Video_Size_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_COMPLETE:
USBVideo_Video_Complete_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_DMA_DONE:
USBVideo_Video_DMA_Done_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_STILL_DMA_DONE:
USBVideo_Still_DMA_Done_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_STILL_DMA_PARTIAL:
USBVideo_Still_DMA_Partial_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_STILL_CAPTURE:
USBVideo_Still_Capture_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_STILL_COMPLETE:
USBVideo_Still_Complete_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_MED_USB_DEVICE_STILL_REQ:
USBVideo_Dev_Still_Req_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_MED_USB_PAUSE_REQ:
USBVideo_Pause_Req_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_INCALL_TIMEOUT:
USBVideo_InCall_Timeout_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_INCALL_DMA_DONE:
USBVideo_InCall_DMA_Done_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_INCALL_CHANGE_SIZE:
USBVideo_InCall_Change_Size_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_MED_USB_RESUME_VIDEO_REQ:
USBVideo_Resume_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_MED_USB_STOP_REQ:
USBVideo_Stop_Req_Hdlr(p_recv_ilm, device_type);
break;
case MSG_ID_USB_VIDEO_ABORT:
USBVideo_Abort_Hdlr(p_recv_ilm, device_type);
break;
default:
EXT_ASSERT(0, p_recv_ilm->msg_id, (kal_uint32)g_USBVideo.state, 0);
break;
}
}
#endif /* WEBCAM_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -