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

📄 mfc_test.c

📁 三星 s3c6400测试代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	INTC_SetVectAddr(NUM_MFC,Isr_Mfc);
	INTC_Enable(NUM_MFC);


	// 6. Read the golden stream to compare
	//--------------------------------------

	FAT_GetFileIndex(pGoldenStreamFileName, &selGoldenStream, &oSdhc);

	FAT_GetFileSize(selGoldenStream, &nGoldenStreamFileSize, &oSdhc);
	Disp("golden stream size = %d bytes\n", nGoldenStreamFileSize);
	 
	uGoldenStreamStAddr = uFreeMemBuf;
	uFreeMemBuf += nGoldenStreamFileSize;

	nReadSize = (nGoldenStreamFileSize < STREAM_BUF_SIZE/2) ? nGoldenStreamFileSize : STREAM_BUF_SIZE/2;
	nGoldenStreamOffset = 0;	

	if (!FAT_ReadFile4(selGoldenStream, nGoldenStreamOffset, (nReadSize+uBlkSz-1)/uBlkSz, uGoldenStreamStAddr, &oSdhc))
		Assert(0);	
	nGoldenStreamOffset += nReadSize;

	uSrcFileOffset=0;	
	uFrameCount=0;
	uEncStreamOffset = 0;
		
	bResult = true;
	bIsNoMoreStream = (nReadSize == nGoldenStreamFileSize) ? true : false;
	
	while (GetKey() == 0)
	{	
		// 7. Read one Yuv source frame from SD/MMC card
		//-----------------------------------------------

		if (!FAT_ReadFile6(selSrcYuv, uSrcFileOffset, uSrcYuvFrameSizeInBytes, uSrcYuvBufAddr, &uTrueStAddrOfData, &oSdhc))
			break;
		uSrcFileOffset += uSrcYuvFrameSizeInBytes;

		// 8. Encode one frame
		//---------------------

		bMfcDone = false;
		MFC_SetEncRunOption(false, false);
		MFC_SetEncRotEn(false);
		MFC_StartEncodingOneFrame(uProcessIdx, uTrueStAddrOfData);
		while(bMfcDone != true);		
		
		// 9. Compare the encoded stream with the golden one, Load the golden stream if necessary
		//----------------------------------------------------------------------------------------

		uFrameCount++;
		Disp("%d ",uFrameCount);

		if (!MFC_IsMoreStreamNeeded(uProcessIdx, nReadSize) && !bIsNoMoreStream)
		{
			Disp(" more ");
			if (!Compare128(uEncBufAddr+(uEncStreamOffset%STREAM_BUF_SIZE), 
					uGoldenStreamStAddr+(uEncStreamOffset%STREAM_BUF_SIZE), nReadSize/16))
			{
				bResult = false;
				break;
			}
			uEncStreamOffset += nReadSize;
			
			nReadSize = (nGoldenStreamFileSize-nGoldenStreamOffset < STREAM_BUF_SIZE/2) ? 
				nGoldenStreamFileSize-nGoldenStreamOffset : STREAM_BUF_SIZE/2;
			bIsNoMoreStream = (nReadSize == nGoldenStreamFileSize-nGoldenStreamOffset) ? true : false;
			if (!FAT_ReadFile4(selGoldenStream, nGoldenStreamOffset/uBlkSz, 
				(nReadSize+uBlkSz-1)/uBlkSz, uGoldenStreamStAddr+(nGoldenStreamOffset%STREAM_BUF_SIZE), &oSdhc))
				Assert(0);
			nGoldenStreamOffset += nReadSize;

			MFC_SetRdPtr(uProcessIdx, uEncBufAddr+((nGoldenStreamOffset+STREAM_BUF_SIZE/2)%STREAM_BUF_SIZE));			
		}
			
		if (uFrameCount >= uNumOfFrames)		// end of YUV frame
		{
			Disp("Encoding ended with %d frames\n", uNumOfFrames);
			if (!Compare128(uEncBufAddr+uEncStreamOffset%STREAM_BUF_SIZE, 
					uGoldenStreamStAddr+uEncStreamOffset%STREAM_BUF_SIZE, nReadSize/16))
			{
				bResult = false;
			}			
			Disp("Rate control: %.2fkbps\n", 
				(float)nGoldenStreamFileSize*8/uNumOfFrames*uFrameRate/1000);	
			break;
		}			
	}	

	// 10. Report the result of comparison
	//-------------------------------------

	Disp("\n%s\n\n", bResult ? "Match" : "Mismatch");

	FAT_UnloadFileSystem(&oSdhc);
	SDHC_CloseMedia(&oSdhc);
	
	MFC_IssueSeqEndCmd(uProcessIdx);	
	MFC_StopBitProcessor();
}
#endif

//////////
// Function Name : SetEncMode
// Function Description : This function sets encoder mode
// Input : sSel, file number to select
// Output : NONE
// Version : 
const char *pEncFile[]=
{
	"foreman_qcif_300.yuv",
	"mobile_qcif_300.yuv",
	"foreman_cif_300.yuv",
	"mobile_cif_300.yuv",
	"city_vga_300.yuv",
	"football_sd601_260.yuv",
	"mobile_sd601_260.yuv",
	0
};
static void SetEncMode(s32 *sSel)
{
	int sEncMode=-1;
#if (USE_SD_STORAGE)
	s32 sTmpValue=0;
#else
	int sEncFile=-1;
	u8 i=0;
#endif	

#if USE_SD_STORAGE
	Disp("Select the Encoder File : ");
	sTmpValue = GetIntNum();
	FAT_GetFileName(sTmpValue, pSrcYUVFileName, &oSdhc);
	*sSel = sTmpValue;
	
	Disp("Enter the Encoder Width : ");
	sTmpValue = GetIntNum();
	if(sTmpValue != -1)
	{
		uEncWidth = sTmpValue;
	}
	
	Disp("Enter the Encoder Height : ");
	sTmpValue = GetIntNum();
	if(sTmpValue != -1)
	{
		uEncHeight = sTmpValue;
	}
	
	Disp("Enter the Encoder Total Frame Number : ");
	sTmpValue = GetIntNum();
	if(sTmpValue != -1)
	{
		uEncTotalFrameNum = sTmpValue;
	}
#else
	do
	{
		Disp("Select Encoder File: \n");

		for(i=0;pEncFile[i]!=0;i++)
		{
			Disp("[%d] %s\n",i,pEncFile[i]);
		}
		
		sEncFile = GetIntNum();	
	} while(sEncFile == -1);

	switch(sEncFile)
	{
		default:
		case 0:
			strncpy(pSrcYUVFileName, pEncFile[0], 256);
			uEncWidth = 176;
			uEncHeight = 144;
			uEncTotalFrameNum = 300;
			break;
			
		case 1:
			strncpy(pSrcYUVFileName, pEncFile[1], 256);
			uEncWidth = 176;
			uEncHeight = 144;
			uEncTotalFrameNum = 300;
			break;
			
		case 2:
			strncpy(pSrcYUVFileName, pEncFile[2], 256);
			uEncWidth = 352;
			uEncHeight = 288;
			uEncTotalFrameNum = 300;
			break;
			
		case 3:
			strncpy(pSrcYUVFileName, pEncFile[3], 256);
			uEncWidth = 352;
			uEncHeight = 288;
			uEncTotalFrameNum = 300;
			break;
			
		case 4:
			strncpy(pSrcYUVFileName, pEncFile[4], 256);
			uEncWidth = 640;
			uEncHeight = 480;
			uEncTotalFrameNum = 300;
			break;
			
		case 5:
			strncpy(pSrcYUVFileName, pEncFile[5], 256);
			uEncWidth = 720;
			uEncHeight = 480;
			uEncTotalFrameNum = 260;
			break;
			
		case 6:
			strncpy(pSrcYUVFileName, pEncFile[6], 256);
			uEncWidth = 720;
			uEncHeight = 480;
			uEncTotalFrameNum = 260;
			break;
			
	}
#endif	
	
	do
	{
		Disp("Select Encoder mode: \n");
		Disp("[0] MPEG4\n");
		Disp("[1] H.263\n");
		Disp("[2] H.264\n");
		sEncMode = GetIntNum();		
	} while (sEncMode == -1);

	eEncMode = (sEncMode == 2) ? AVC_ENC : MP4_ENC;
	bIsH263 = (sEncMode == 1) ? true : false;

}

//////////
// Function Name : TestEncoding
// Function Description : This function encodes an YUV file and displays the recon image
// Input : NONE
// Output : NONE
// Version : 
static void TestEncoding(void)
{
	u32 uFreeMemBuf = MFC_MEMORY_BASE;
	u32 uProcessIdx;
	u32 uYuvFrameSize;
	const char* pEncModeName;
	u32 uYuvBufAddr;
	s32 sel;
#if (!USE_SD_STORAGE)
	u32 uYuvFileAddr, uYuvFileSize;	
#endif	
	u32 uTransferSize;
	const int nWriteUnit = STREAM_BUF_SIZE/2;
	u32 uStreamOffset = 0;
	u32 uSaveBufAddr;
	u32 uStreamBufStAddr;
	u32 uLcdFbAddr;
	CSPACE eLcdBpp;
	u32 uLcdWidth, uLcdHeight;
	u32 uDecWidth, uDecHeight;
	u32 uRecFrmAddrY;
	u32 uDispFrameNum;
	u32 uFrameCount=0;
	u32 uSrcYuvFileOffset = 0;
	u32 uWrPtr;
	u32 uTrueStAddrOfData;
	u32 uRecFrameIdx;
	float fEncTime=0;
	double fTotEncTime;
	
#if USE_SD_STORAGE
	// 0. Select the YUV file in the SD card.
	//-------------------------------------------
	while(!SDHC_OpenMedia(SDHC_HCLK, &oSdhc));
	if (!FAT_LoadFileSystem(&oSdhc))
		Assert(0);
		
	SetEncMode(&sel);
	
	if(sel == -1)
	{
		Disp("There is the matched file in the SD card\n");
		return;
	}
#else
	// 0. Download the YUV file thru USB.
	//-------------------------------------------
	SetEncMode(&sel);
	
	uYuvFileAddr = uFreeMemBuf;
	Disp(" Before testing, download \"%s\" file through USB \n", pSrcYUVFileName);
	uYuvFileSize = DownloadImageThruUsbOtg((u8 *)uYuvFileAddr);
	if (uYuvFileSize == 0)
		return;
	uFreeMemBuf += uYuvFileSize;
	uFreeMemBuf = (uFreeMemBuf+STREAM_WR_SIZE-1)/STREAM_WR_SIZE*STREAM_WR_SIZE;
#endif

	// 1. Move firmware and init base settings.
	//-------------------------------------------
	
	MFC_MoveFirmwareToCodeBuf(uFreeMemBuf);
	MFC_GetCodeBufEndAddr(&uFreeMemBuf);	
	MFC_StartBitProcessor();
	
	MFC_InitBaseForProcesses(uFreeMemBuf);
	MFC_GetBaseBufEndAddr(&uFreeMemBuf);
	MFC_SetNoFlushingStreamBufModeInEncoding();

	// 2. Set encoding parameters.
	//-----------------------------

	uProcessIdx = 0;

	MFC_SetEncYuvFileCfg(uProcessIdx, pSrcYUVFileName, uEncTotalFrameNum, uEncWidth, uEncHeight, 30);
	MFC_SetEncSliceCfg(uProcessIdx, 1, 0, 4000);
	MFC_SetEncErrResilienceCfg(uProcessIdx, 0);

	if (eEncMode == MP4_ENC)
	{
		if (bIsH263)
			MFC_SetEnc263Cfg(uProcessIdx, 0, 1, 0, 0, 10, 15);
		else
			MFC_SetEncMpeg4Cfg(uProcessIdx, 0, 0, 0, 10, 15);
	}
	else if (eEncMode == AVC_ENC)
	{
		MFC_SetEnc264Cfg(uProcessIdx, 0, 0, 0, 0, 0, 15, 15);
	}
	MFC_SetEncRateCtrlCfg(uProcessIdx, 1, 128, 0, 0);

	uYuvFrameSize = uEncWidth * uEncHeight * 3/2;	

	pEncModeName =
		(eEncMode == MP4_ENC && bIsH263) ? "H.263" :
		(eEncMode == MP4_ENC && !bIsH263) ? "MPEG4" : "H.264";
	Disp("Source file Name: %s, enc mode: %s, w:%d, h:%d, uEncTotalFrameNum:%d\n",
		pSrcYUVFileName, pEncModeName, uEncWidth,uEncHeight,uEncTotalFrameNum);

	// 3. Keep one frame sized memory and index of the selected YUV file
	//-----------------------------------------------------------------

	uYuvBufAddr = uFreeMemBuf;
	uFreeMemBuf += (uYuvFrameSize/512 + 2) * 512;

	// 4. Init a process of MFC
	//--------------------------
	uFreeMemBuf = (uFreeMemBuf+STREAM_WR_SIZE-1)/STREAM_WR_SIZE*STREAM_WR_SIZE;
	uStreamBufStAddr = uFreeMemBuf;
	MFC_InitProcessForEncoding(
		uProcessIdx, eEncMode, uStreamBufStAddr, STREAM_BUF_SIZE, uEncWidth, uEncHeight, false);
	MFC_GetProcessBufEndAddr(uProcessIdx, &uFreeMemBuf);
	INTC_SetVectAddr(NUM_MFC,Isr_Mfc);
	INTC_Enable(NUM_MFC);	

	// 5. Init LCDC
	//---------------

	uLcdFbAddr = uFreeMemBuf;
	eLcdBpp = RGB24;
	LCD_InitDISPC(eLcdBpp, uLcdFbAddr, WIN0, false);
	LCD_GetFbEndAddr(&uFreeMemBuf, WIN0);

	LCD_GetFrmSz(&uLcdWidth, &uLcdHeight, WIN0);
	uDecWidth = uLcdWidth;
	uDecHeight = uLcdHeight*9/10;

	GLIB_InitInstance(uLcdFbAddr, uLcdWidth, uLcdHeight, eLcdBpp);
	GLIB_ClearFrame(C_BLUE);
	GLIB_SetFontColor(C_WHITE, C_BLUE, false);
	GLIB_Printf(2, uDecHeight+6, "S3C6400 MFC Encoder(%s)",
		(eEncMode == MP4_ENC && bIsH263) ? "H.263" : (eEncMode == MP4_ENC && !bIsH263) ? "MPEG4" : "H.264");

	// 6. Init POST
	//---------------
		
	MFC_GetAddrOfYFrame(uProcessIdx, 0, &uRecFrmAddrY); // Start addr of MFC's output frame buffers
	MFC_GetDispFrameNum(uProcessIdx, &uDispFrameNum);
	
	POST_InitIp1(
		uEncWidth, uEncHeight, 0, 0, uEncWidth, uEncHeight, uRecFrmAddrY, YC420,
		uLcdWidth, uLcdHeight, 0, 0, uDecWidth, uDecHeight, uLcdFbAddr, eLcdBpp,
		uDispFrameNum, false, ONE_SHOT, POST_DMA, POST_DMA, &oPost);
	INTC_SetVectAddr(NUM_POST0, Isr_Post);
	INTC_Enable(NUM_POST0);
	POST_EnableInterrupt(POST_LEVEL_INT, &oPost);

	fTotEncTime=0;
	uFrameCount=0;
	uSrcYuvFileOffset = 0;
	uSaveBufAddr = uFreeMemBuf;
	uFreeMemBuf += STREAM_BUF_SIZE*4;
	
	LCD_Start();
		
	while (GetKey() == 0)
	{
		// 7. Read one frame of YUV image from SD card
		//---------------------------------------------
#if USE_SD_STORAGE
		if (!FAT_ReadFile6(sel, uSrcYuvFileOffset, uYuvFrameSize, uYuvBufAddr, &uTrueStAddrOfData, &oSdhc))
			break;
#else
		if((uSrcYuvFileOffset+uYuvFrameSize)<=uYuvFileSize)
		{
			memcpy((void *)uYuvBufAddr, (void *)(uYuvFileAddr+uSrcYuvFileOffset), uYuvFrameSize);
			uTrueStAddrOfData = uYuvBufAddr;
		}
		else
			break;
#endif
		uSrcYuvFileOffset += uYuvFrameSize;	

		// 8. Encode one frame
		//---------------------

		StartTimer(0);
		
		bMfcDone = false;
		MFC_SetEncRunOption(false, false);
		MFC_StartEncodingOneFrame(uProcessIdx, uTrueStAddrOfData);
		while(bMfcDone != true);

		MFC_DoPostProcessingOfEncoding(uProcessIdx, &uRecFrameIdx);
		
		fEncTime = StopTimer(0);	
		fTotEncTime += fEncTime;

		// 9. Save the encoded stream of the size of the write unit
		//----------------------------------------------------------
		uFrameCount++;
		MFC_GetWrPtr(uProcessIdx, &uWrPtr);

		if (uWrPtr > uStreamBufStAddr+((uStreamOffset+nWriteUnit)%STREAM_BUF_SIZE)+STREAM_WR_SIZE)
		{
			//Copy32(uStreamBufStAddr+(uStreamOffset%STREAM_BUF_SIZE), uSaveBufAddr+uStreamOffset, nWriteUnit/4); 
			memcpy((void *)(uSaveBufAddr+uStreamOffset), (void *)(uStreamBufStAddr+(uStreamOffset%STREAM_BUF_SIZE)), nWriteUnit);

			uStreamOffset += nWriteUnit;			
			MFC_SetRdPtr(uProcessIdx, uWrPtr-STREAM_WR_SIZE); // to avoid the full status
		}

		// 10. Convert the frame for display for verifying
		//-------------------------------------------------
		
		bPostDone = false;
		POST_StartProcessing1(uRecFrameIdx, 0, &oPost);
		while(bPostDone == false);

		LCD_Trigger();

		if (uFrameCount == uEncTotalFrameNum)
		{
			Disp("Encoding is ended with %d frames\n", uFrameCount);
			break;
		}
	}

	MFC_IssueSeqEndCmd(uProcessIdx);

	// As we called MFC_SetNoFlushingStreamBufModeInEncoding(),
	// we need copy operation once more after calling MFC_IssueSeqEndCmd().
	MFC_GetWrPtr(uProcessIdx, &uWrPtr);
	uTransferSize = uWrPtr - (uStreamBufStAddr+(uStreamOffset%STREAM_BUF_SIZE));
	//Copy32(uStreamBufStAddr+

⌨️ 快捷键说明

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