⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbvideo_state.c

📁 MTK平台绝密核心代码之 USB驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	{
		//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 + -