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

📄 mobile_demo.c

📁 三星s3c2460开发板完整功能测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	//DctqEngine(&currImage, &refImage[prevImageNum], &dctqCoeff[frameNum], pQInfo, DCTQ_WITH_VLC_COEFF_WRITE);

    	DctqEngine(&currImage2[frameNum],&refImage[frameNum],&dctqCoeff[frameNum],pQInfo,DCTQ_WITH_VLC_COEFF_NOTWRITE);
}

void FdStartMe(unsigned int frameNum,unsigned int prevFrameNum)
{
    MeEngine(&currImage2[frameNum],&refImage[prevFrameNum],meVector2[frameNum],0);
}

void FdStartMc(unsigned int frameNum,unsigned int prevFrameNum)
{
    McEngine(&refImage[prevFrameNum],&refImage[frameNum],meVector2[frameNum],0);
}

#if CAM_ENABLE
void Fim20DemoMem(void)
{
	unsigned int i;
	unsigned int freeBufStartAddr = (_NONCACHE_STARTADDRESS+0);
 
	// current image start address setting
	printf(" w = %d, h=%d\n", FimvImageWidth, FimvImageHeight);
	
    	freeBufStartAddr = AllocImage420(&currImage2[0], freeBufStartAddr, FimvImageWidth,FimvImageHeight,
		  IMAGE420_NO_PADDED);
	
    	freeBufStartAddr = AllocImage420(&currImage2[1], freeBufStartAddr, FimvImageWidth,FimvImageHeight,
		  IMAGE420_NO_PADDED);
	
	freeBufStartAddr = AllocImage420(&currImage2[2], freeBufStartAddr, FimvImageWidth,FimvImageHeight,
		  IMAGE420_NO_PADDED);
	
	freeBufStartAddr = AllocImage420(&currImage2[3], freeBufStartAddr, FimvImageWidth,FimvImageHeight,
		  IMAGE420_NO_PADDED);

	// reference image start address setting
    	for(i=0;i<4;i++)
    	{
    		//printf("reference image #%d addr: %x\n",i,freeBufStartAddr);
			printf(" ref addr [%d]= %08x\n",i,freeBufStartAddr);
    		freeBufStartAddr=
				
    	    		AllocImage420(&refImage[i],freeBufStartAddr,FimvImageWidth,FimvImageHeight,
    			  		IMAGE420_PADDED|IMAGE420_CLEAR);    
    	}
	// dctq coeff image address setting
    	for(i=0;i<4;i++)
    	{
		//printf("dctqCoeff image #%d addr: %x\n",i,freeBufStartAddr);
		freeBufStartAddr=
	    		AllocImage420(&dctqCoeff[i],freeBufStartAddr,FimvImageWidth,FimvImageHeight,
			   		IMAGE420_DCTQ_COEFF|IMAGE420_CLEAR);    
    	}
    	printf("MV addr: [%x,",freeBufStartAddr);    

	meVector2[0] = freeBufStartAddr;
	meVector2[1] = freeBufStartAddr + ((FimvImageWidth/16)*(FimvImageHeight/16) *20)*1;
	meVector2[2] = freeBufStartAddr + ((FimvImageWidth/16)*(FimvImageHeight/16) *20)*2;
	meVector2[3] = freeBufStartAddr + ((FimvImageWidth/16)*(FimvImageHeight/16) *20)*3;	
	
	freeBufStartAddr = freeBufStartAddr + ((FimvImageWidth/16)*(FimvImageHeight/16) *20)*4;
		

	// Q-info initialize
	InitQInfo(&pQInfo,&freeBufStartAddr,FimvImageWidth,FimvImageHeight,QINFO_INTER_MODE);

	// Camera setting
//	CamInit(FimvImageWidth, FimvImageHeight, 352, 288, 100, 0,  0x11000000, LCDFRAMEBUFFERFG2);

	// Post setting
	mpegframebuffer = (_NONCACHE_STARTADDRESS+0x00d00000);
	PostSetFimv16B(FimvImageWidth,FimvImageHeight,240,320, refImage[0].frameStartAddr,mpegframebuffer);

 	VlcConfig4Dctq(FimvImageWidth,(_NONCACHE_STARTADDRESS+0x00a00000),(FimvImageWidth/16)*(FimvImageHeight/16),0);
	freeBufStartAddr = freeBufStartAddr + (1152/16)*(864/16)*4;
	if(freeBufStartAddr >= (_NONCACHE_STARTADDRESS+0x00a00000)) printf("Memory allocaton Over : %08x\n",freeBufStartAddr);
	else printf("Ok,memory allocation : %08x\n",freeBufStartAddr);
}
#endif

void Fim20DemoIsrUnmask(void)
{
	ClearPending(BIT_ALLMSK);
	rSUBSRCPND2 = BIT_SUB_POST;
		
    	pISR_DCTQ=(unsigned int)Cam_Demo_DctqIsr;
    	rINTMSK&=~BIT_DCTQ;

    	pISR_ME=(unsigned int)Cam_Demo_MeIsr;
    	rINTMSK&=~BIT_ME;

    	pISR_MC=(unsigned int)Cam_Demo_McIsr;
    	rINTMSK&=~BIT_MC;

       pISR_VLX=(unsigned int)Cam_Demo_VlxIsr;
    	rINTMSK&=~BIT_VLX;

	pISR_CAMIF_BLOCK_POST =(unsigned int)Cam_Demo_Cam_CodecIsr;
	rINTSUBMSK2 &= ~((BIT_SUB_POST)|(BIT_SUB_CAMIF_C)); // SUB-INT POST Enable
	rINTMSK &=~BIT_CAMIF_BLOCK_POST;

    	rMODE |= (1<<7);//Post Interrupt Enable

}


void Fim20DemoIsrMask(void)
{
	ClearPending(BIT_ALLMSK);
	//rSUBSRCPND |= (BIT_SUB_VLX | BIT_SUB_POST);

    	rINTMSK|=BIT_DCTQ;
    	rINTMSK|=BIT_ME;
    	rINTMSK|=BIT_MC;
    	rINTMSK |= BIT_VLX;	
   	rINTMSK |=BIT_CAMIF_BLOCK_POST;
	rINTSUBMSK2 |= ((BIT_SUB_POST)|(BIT_SUB_CAMIF_C)); // SUB-INT POST Enable
    	rMODE &= (0<<7);//Post Interrupt Enable

    	rINTSUBMSK  |= (BIT_SUB_WDT | BIT_SUB_TIMER4|BIT_SUB_TIMER3);           
    	rINTMSK  |= (BIT_TIMER34_WDT); //Watch dog Interrupt service is available
    	ClearPending(BIT_TIMER34_WDT);
	frameNum = 0;
	//Lcd_Port_Init(); // LCD gpio setting
}


/*/////////////////////////////////////////////////////////////////////////////
1. download the mobile image "mob20_3.CIF" using the usb download
2. allocate the address 4-pingpong memory which consist of curr/prev/q_info/mv/dctqcoeff
3. start the DCTQ based on the download pointer mob20_3.cif.
4. after DCTQ Isr , POST start & ME operate
5. after ME Isr, MC operate
6. after MC Isr, DCTQ operate & adopt the VLX optionally
7. repeat the 4~6
/////////////////////////////////////////////////////////////////////////////*/
volatile unsigned int iter;
extern unsigned int downloadAddress; 
extern void DownloadData(void);
void Mobile_Image_Demo(void)
{
    
	char is_char;
	
	unsigned int currImageSize = (FIMV_IMAGE_WIDTH*FIMV_IMAGE_HEIGHT)*1.5;
	unsigned int baseCurrImage= (_NONCACHE_STARTADDRESS+0x00d00000);  // under stack : 0x11ff8000, max limit 0x11fe7000
	unsigned int qinfoBaseAddr;
	
	unsigned int qinfoMode;

	unsigned int imageWidth=FIMV_IMAGE_WIDTH;  
	unsigned int imageHeight=FIMV_IMAGE_HEIGHT; 


	unsigned int freeBufStartAddr =_NONCACHE_STARTADDRESS;	

	unsigned int *pVlcData;
	unsigned int mode;
	unsigned int mcedimage;
	unsigned int fps;
	unsigned int *pt;

	unsigned int qpStepTable[((FIMV_IMAGE_WIDTH/16)*(FIMV_IMAGE_HEIGHT/16)+3)/4];  //for deblock test

	unsigned int i;
	

//	rPRIORITY1 &= ~(0x7);
//	rPRIORITY0 |= (1<<1);  // fixed priority I-BUS
//	rPRIORITY1 |= (1<<1);  // fixed priority I-BUS
	
	
	prevImageNum = 0; frameNum = 0;

	printf("/***         Mobile raw data image test Program    ***/\n");
	printf("/*** Download the mobile image ../bmp/mobile_20_3.CIF ( size 0x2e7000 ***/\n");
       printf("/*** Download address : 0x%08x(Noncahe_address   ***/\n",(_NONCACHE_STARTADDRESS+0x00d00000));
	printf("\n");

	//   
	printf(" Download OK? [Y]es, [N]o -->"); 
	printf("\n\n");
	
	is_char = getchar();

	if((is_char == 'n')||(is_char == 'N')){		
		downloadAddress=(_NONCACHE_STARTADDRESS+0x00d00000);
		printf("\n\nNOTE!! You should download ""mobile_20_3.CIF"" at 0x%x before executing test program\n",downloadAddress);
		return;
	}
	else printf(" Start Mpeg4 engine ? press any key!\n");

	
	//getchar();

	freeBufStartAddr = Alloc_FIMV_Addr_Init(freeBufStartAddr);

	qinfoBaseAddr = freeBufStartAddr; // inter / intra mode change

	InitQInfo(&pQInfo, &qinfoBaseAddr, FIMV_IMAGE_WIDTH, FIMV_IMAGE_HEIGHT, QINFO_INTRA_MODE);

    	pVlcData=(unsigned int *)(_NONCACHE_STARTADDRESS+0x00a00000);
    	//freeBufStartAddr+=FIMV_MBLK_NUM*0x200;
    	for(pt=pVlcData;pt<(pVlcData+FIMV_MBLK_NUM*0x200/4);pt++)
		*pt=0xffffffff;
    	printf("pVlcData=[%x,%x)\n",pVlcData,(pVlcData+FIMV_MBLK_NUM*0x200/4));

	// qpstep setting for deblock
	for(i=0;i<((FIMV_IMAGE_WIDTH/16)*(FIMV_IMAGE_HEIGHT/16)/4);i++)
//		qpStepTable[i]=0x1e1e1e1e; // 30	
//		qpStepTable[i]=0x0c0c0c0c; // 12
		qpStepTable[i]=0x03030303; // 3

/*
		mode=POST_IN_YCBYCR420|POST_OUT_RGB16B;
	mpegframebuffer = 0x13600000;
	PostInit(384, 320, 352, 288, 16, 16, 
			240, 320, 240, 320, 0, 0, 
			refImage[0].frameStartAddr, mpegframebuffer, mode);    


	LcdBGInit(MODE_PAR_16BIT565_240320|MODE_POST_DISPLAY_16B);

*/
	mpegframebuffer = (_NONCACHE_STARTADDRESS+0x00c00000);
	PostSetFimv16B(FIMV_IMAGE_WIDTH,FIMV_IMAGE_HEIGHT,240,320, refImage[0].frameStartAddr,mpegframebuffer);

	printf("Selec output LCD\n 0:Serial LCD 240x320, 1:Parallel LCD 240x320 ->\n");
	i = GetIntNum();
	if (i == 1) 
		LcdBGInit(MODE_PAR_16BIT565_240320|MODE_MPEG_DISPLAY_16B);
	else 
	{
		Init_240X320_AMLCD();
		LcdBGInit(MODE_SER_16BIT565_240320|MODE_MPEG_DISPLAY_16B);
	}

	FimvImageWidth = 352;
	FimvImageHeight = 288;

	LcdEnvidOnOff(1);

	Init_FIMV20_Isr();

	//Timer_Start(2);

	printf(" Data about test \n");

	printf(" Data about pass VLC\n");
	
	//DctqEngine(&currImage,&prevImage,&dctqCoeff,pQInfo,DCTQ_WITH_VLC_COEFF_WRITE);
    VlcConfig4Dctq(imageWidth,(_NONCACHE_STARTADDRESS+0x00a00000),(imageWidth/16)*(imageHeight/16),0);

	//DctqEngine(&currImage, &refImage[prevImageNum], &dctqCoeff[frameNum], pQInfo, DCTQ_FRAME_START_MODE);
	DctqEngine(&currImage, &refImage[prevImageNum], &dctqCoeff[frameNum], pQInfo, DCTQ_WITH_VLC_COEFF_NOTWRITE);

	//VlcEngine(&dctqCoeff,pQInfo,(unsigned int)pVlcData,0);

	// start scheduler
	while(!Uart_GetKey()){
	//while(1){

		//printf("prev = %d, frame = %d\n", prevImageNum,frameNum);

		if(d_dctqDone == TRUE){
			d_dctqDone = 0;
#if 1
			DeblockEngine(&refImage[prevImageNum],qpStepTable,DB_QPSRC_EXTERNAL);
		}
		if(deblockDone == TRUE){
			deblockDone = 0;
#endif
			//PostStartFIMV20( refImage[0].frameStartAddr);
			//PostStartProcessing(0,0);
			PostStartFIMV20(refImage[prevImageNum].frameStartAddr);
			//printf("framestart addr = %08x\n",refImage[prevImageNum].frameStartAddr);

			frameNum++;
			if(frameNum ==16) {
				//fps = Timer_Stop();
				//printf("iter = %d\n",iter++);
				//printf("fps = %d\n",1000000*16/(fps*64));
				frameNum=0 ;baseCurrImage = (_NONCACHE_STARTADDRESS+0x00d00000);}

			((frameNum %4 )== 0)? (qinfoMode=QINFO_INTRA_MODE):(qinfoMode=QINFO_INTER_MODE);
			InitQInfo(&pQInfo, &qinfoBaseAddr, FIMV_IMAGE_WIDTH, FIMV_IMAGE_HEIGHT, qinfoMode);

			// check point - ows
			AllocImage420(&currImage, baseCurrImage+=currImageSize, 
				                   FIMV_IMAGE_WIDTH, FIMV_IMAGE_HEIGHT, IMAGE420_NO_PADDED);

			if (qinfoMode == QINFO_INTRA_MODE) {
				//DctqEngine(&currImage, &refImage[mcedimage], &dctqCoeff[frameNum%4], pQInfo, 
				 //            DCTQ_FRAME_START_MODE);
				DctqEngine(&currImage, &refImage[mcedimage], &dctqCoeff[frameNum%4], pQInfo, 
				             DCTQ_WITH_VLC_COEFF_WRITE);
			}
			else if(qinfoMode == QINFO_INTER_MODE){
				MeEngine(&currImage, &refImage[prevImageNum], meVector2[frameNum%4], 0);	
			}
			//InitQInfo(&pQInfo, &qinfoBaseAddr, FIMV_IMAGE_WIDTH, FIMV_IMAGE_HEIGHT, QINFO_INTER_MODE);
			
		}
		if(d_meDone == TRUE){
			d_meDone = 0;
			mcedimage = prevImageNum+1;
			if(mcedimage== 4) mcedimage = 0;
			McEngine(&refImage[prevImageNum], &refImage[mcedimage ], meVector2[frameNum%4], 0);
			
		}
		if(d_mcDone == TRUE){
			d_mcDone = 0;
#if 0
			DeblockEngine(&refImage[mcedimage],qpStepTable,DB_QPSRC_EXTERNAL);
		}
		if(deblockDone == TRUE){
			deblockDone = 0;
#endif
			//DctqEngine(&currImage, &refImage[mcedimage], &dctqCoeff[frameNum%4], pQInfo, 
			//	             DCTQ_FRAME_START_MODE);
			DctqEngine(&currImage, &refImage[mcedimage], &dctqCoeff[frameNum%4], pQInfo, 
				             DCTQ_WITH_VLC_COEFF_NOTWRITE);

			//printf("1 %08x\n",rVLX_OUT1);
			
			prevImageNum++;
			if(prevImageNum == 4) prevImageNum=0;
		}

	}

	printf(" ME : currimag = %08x, prev= %08x, mv=%08x\n", rME_CFSA, rME_PFSA, rME_MVSA);
	printf(" MC : previmag = %08x, mced= %08x,mv= %08x\n", rMC_PFYSA_ENC, rMC_CFYSA_ENC, rMC_MVSA_ENC);
	printf(" ME : currimag = %08x, mced= %08x, coeff=%08x, Q=%08x\n", rSAYCF, rSAYRF, rSAYDQF, rSACRDQF);
	Fim20DemoIsrMask();

}

void PostStartFIMV20(unsigned int InFrameBuffer)
{
	unsigned int OffsetY, OffsetC,src420,inmultiplier, OrgSrcWidth,OrgSrcHeight,SrcWidth,SrcHeight;
	unsigned int SrcStartX,SrcStartY;


	OrgSrcWidth = FimvImageWidth+32;
	OrgSrcHeight = FimvImageHeight+32;
	SrcWidth = FimvImageWidth;
	SrcHeight = FimvImageHeight;
	inmultiplier = 1;
	src420 = 1;
	SrcStartX=SrcStartY = 16;
	OffsetY=(OrgSrcWidth-SrcWidth)*inmultiplier;
	
	rADDRStart_Y=InFrameBuffer+(OrgSrcWidth*SrcStartY+SrcStartX)*inmultiplier;
	rADDREnd_Y=rADDRStart_Y+SrcWidth*SrcHeight*inmultiplier+OffsetY*(SrcHeight-1);

	//rOffset_Y=OffsetY;
    
	if(src420) { //if .srcFormat420==1, .srcFormatInterleave should be 0.
		OffsetC=((OrgSrcWidth-SrcWidth)/2)*1;
		rADDRStart_Cb=InFrameBuffer+OrgSrcWidth*OrgSrcHeight*1+(OrgSrcWidth/2*SrcStartY/2+SrcStartX/2)*1;

		rADDREnd_Cb=rADDRStart_Cb+(SrcWidth/2*SrcHeight/2)*1+OffsetC*(SrcHeight/2-1);
		rADDRStart_Cr=InFrameBuffer+OrgSrcWidth*OrgSrcHeight*1+(OrgSrcWidth/2*OrgSrcHeight/2)*1+(OrgSrcWidth/2*SrcStartY/2+SrcStartX/2)*1;

		rADDREnd_Cr=rADDRStart_Cr+(SrcWidth/2*SrcHeight/2)*1+OffsetC*(SrcHeight/2-1);
		//rOffset_Cb=OffsetC;
		//rOffset_Cr=OffsetC;
	}

	rMODE|=(1<<5);
	
}




/////////////// Function Description //////////////////////////
// initialzie the allocation of FIMV addr which curr / ref / dctq
///////////////////////////////////////////////////////////
unsigned int Alloc_FIMV_Addr_Init ( unsigned int freeBufStartAddr)
{
	int i;

	// completed interrupt flag initialzation
	d_dctqDone=d_mcDone=d_meDone=d_vlxDone = FALSE;
	prevImageNum = frameNum = FALSE;

	// currImage [0] update only because image already loaded the memory
	//. When we wann use the camera you must be mapping the camera codec 4pingpong memory
	printf(" curr image start Addr = 0x%08x\n",(_NONCACHE_STARTADDRESS+0x00d00000));
	//freeBufStartAddr = AllocImage420(&currImage, freeBufStartAddr, FIMV_IMAGE_WIDTH, FIMV_IMAGE_HEIGHT, 
	//                                                       IMAGE420_NO_PADDED);
	AllocImage420(&currImage, (_NONCACHE_STARTADDRESS+0x00d00000), FIMV_IMAGE_WIDTH, FIMV_IMAGE_HEIGHT, IMAGE420_NO_PADDED);


	// intialize the reference image address
	for(i=0;i<4;i++){
		printf(" ref. image start addr = 0x%08x\n",freeBufStartAddr);
		freeBufStartAddr = AllocImage420(&refImage[i], freeBufStartAddr, FIMV_IMAGE_WIDTH, FIMV_IMAGE_HEIGHT, 
			                         IMAGE420_PADDED|IMAGE420_CLEAR);
	}
	for(i=0;i<4;i++){
		printf(" DCTQ coeff. image start addr = 0x%08x\n",freeBufStartAddr);
		freeBufStartAddr = AllocImage420(&dctqCoeff[i], freeBufStartAddr, FIMV_IMAGE_WIDTH, FIMV_IMAGE_HEIGHT, 
			                         IMAGE420_DCTQ_COEFF|IMAGE420_CLEAR);
	}
    	printf("MV addr: [%x,",freeBufStartAddr);    

	meVector2[0] = freeBufStartAddr;
	meVector2[1] = freeBufStartAddr + ((FIMV_IMAGE_WIDTH/16)*(FIMV_IMAGE_HEIGHT/16) *20)*1;
	meVector2[2] = freeBufStartAddr + ((FIMV_IMAGE_WIDTH/16)*(FIMV_IMAGE_HEIGHT/16) *20)*2;
	meVector2[3] = freeBufStartAddr + ((FIMV_IMAGE_WIDTH/16)*(FIMV_IMAGE_HEIGHT/16) *20)*3;	
	
	freeBufStartAddr = freeBufStartAddr + ((FIMV_IMAGE_WIDTH/16)*(FIMV_IMAGE_HEIGHT/16) *20)*4;
	if(freeBufStartAddr >= (_NONCACHE_STARTADDRESS+0x00d00000)) printf("Memory allocaton Over : %08x\n",freeBufStartAddr);
	else printf("Ok,memory allocation : %08x\n",freeBufStartAddr);

	return (freeBufStartAddr);
	

}

void	Init_FIMV20_Isr(void)
{

    	pISR_DCTQ=(unsigned int)demo_DctqIsr;
    
    	rINTMSK&=~BIT_DCTQ;

    	pISR_ME=(unsigned int)demo_MeIsr;
    
    	rINTMSK&=~BIT_ME;

    	pISR_MC=(unsigned int)demo_McIsr;
    
    	rINTMSK&=~BIT_MC;

       pISR_VLX=(unsigned int)demo_VlxIsr;

    	rINTMSK&=~BIT_VLX;

	pISR_CAMIF_BLOCK_POST=(unsigned int)demo_PostDeblockIsr;

	rINTSUBMSK2 &= ~(BIT_SUB_POST|BIT_SUB_DEBLOCK); // SUB-INT POST Enable
	rINTMSK &= ~(BIT_CAMIF_BLOCK_POST); // INT_POST_LCD Enable
    	rMODE |= (1<<7);//Post Interrupt Enable
    	rDB_MODE |= (1<<3);//Post Interrupt Enable

}
////////////////////////////////////////////////////////////////////
/// Mobile image FIMV10 Demo ISR
void __irq demo_DctqIsr(void)
{
    	ClearPending(BIT_DCTQ);	
    	d_dctqDone=TRUE;
    	printf("{d}");
}
void __irq demo_MeIsr(void)
{
    	ClearPending(BIT_ME);	
    	d_meDone=TRUE;
    	printf("{e}");
}
void __irq demo_McIsr(void)
{
    	ClearPending(BIT_MC);	
    	d_mcDone=TRUE;
    	printf("{c}");
}
void __irq demo_VlxIsr(void)
{
	//printf("2 %08x\n",rVLX_OUT1);
	//rSUBSRCPND |= BIT_VLX;
    	ClearPending(BIT_VLX);	
	//printf("3 %08x\n",rVLX_OUT1);
    	d_vlxDone=TRUE;
    	printf("{v}");
}
void __irq demo_PostDeblockIsr(void)
{

	rINTSUBMSK2=BIT_SUB_CAMIF_P|BIT_SUB_CAMIF_C|BIT_SUB_DEBLOCK|BIT_SUB_POST;

	ClearPending(BIT_CAMIF_BLOCK_POST);//Clear Source Pending, Interrupt Pending	   

	if (rSUBSRCPND2&BIT_SUB_POST)	   
	{
		rMODE &= ~(1<<6);//Clear Source in POST Processor
		rSUBSRCPND2=BIT_SUB_POST; //Clear SUB Interrupt Source Pending.

	    	printf("{P}\n");
    		//postProcessingDone=1;
	}
	if (rSUBSRCPND2&BIT_SUB_DEBLOCK)
	{
		rDB_MODE &= ~(DB_DEBLKINT); //deblock interrupt pending self-register
		rSUBSRCPND2 = BIT_SUB_DEBLOCK;

		printf("{b}");
		deblockDone=TRUE;
	}

	rINTSUBMSK2&= ~(BIT_SUB_POST|BIT_SUB_DEBLOCK|BIT_SUB_CAMIF_P|BIT_SUB_CAMIF_C);

}




////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -