📄 mfc_test.c
字号:
//----------------------------------
StartTimer(0);
bPostDone = false;
POST_StartProcessing1(uFrameIdx, 0, &oPost);
while(bPostDone == false);
LCD_Trigger();
fPostTime = StopTimer(0);
fTotTime += fPostTime;
// 8. Load stream if necessary
//------------------------------
// ##### Check all frames are decoded : start #####
//=============================================================================================
if ((uReadAmountByteSize >= uStreamFileSize)||( frameCount == MAX_FRAME_NUM-2)||( frameCount == uNumOfFrames -1))
{
Disp("Decode Complete! \n" );
MFC_NotifyNoMoreStream(uProcessIdx);
break;
}
// 9. Display frame rate on the LCD
//----------------------------------
if((frameCount%10)==0)
{
Disp("Current Frame number= %d \n", frameCount);
GLIB_Printf(2, uDecHeight+6, "S3C6400 MFC Decoder(FPS=%.2f @%dx%d)",1000000*frameCount/fTotTime,picX,picY);
}
}
Disp("\ntotal decoding time=%.fus, pure FPS=%.2f\n",fTotDecTime,1000000*frameCount/fTotDecTime);
Disp("total decoding+post_processing time=%.fus\n",fTotTime);
Disp("FPS=%.2f, average elapsed time= %.2f(ms), total %d frames\n",
1000000*frameCount/fTotTime, fTotTime/frameCount/1000, frameCount);
MFC_IssueSeqEndCmd(uProcessIdx);
MFC_StopBitProcessor();
FAT_UnloadFileSystem(&oSdhc);
SDHC_CloseMedia(&oSdhc);
}
#endif
//////////
// Function Name : TestDmbDecoding
// Function Description : This function decodes an DMB stream file and displays the generated YUV
// Input : NONE
// Output : NONE
// Version :
static void TestDmbDecoding(void)
{
u32 uFreeMemBuf = MFC_MEMORY_BASE;
#if (USE_SD_STORAGE)
char pFileName[256];
u32 uTotalNumOfFiles;
char fileExt[50];
int sel, i;
const int uBlkSz = 512;
MFC_CODEC_MODE eDecMode;
bool bFat_FileLoad=false;
#else
u32 uStreamFileAddr;
#endif
const int nReadUnit = DMB_STREAM_BUF_SIZE/2;
u32 uStreamFileSize;
u32 uStreamBufStAddr;
int nReadSize;
u32 uStreamOffset;
u32 uFrameBufStAddr;
u32 uProcessIdx;
u32 uLcdFbAddr;
CSPACE eLcdBpp;
u32 uPicHsz, uPicVsz;
u32 uDispFrameNum;
u32 uRotWidth;
u32 uRotHeight;
u32 uLcdWidth, uLcdHeight;
u32 uFrameIdx;
u32 frameCount;
#if (!USE_SD_STORAGE)
// 0. Download the stream file thru USB.
//-------------------------------------------
uStreamFileAddr = uFreeMemBuf;
Disp(" Before testing, download a stream file through USB\n");
Disp(" If you want to test with previous stream file, press 'x' key\n");
if(Getc()!='x')
uStreamFileSize = DownloadImageThruUsbOtg((u8 *)uStreamFileAddr);
if (uStreamFileSize == 0)
return;
uFreeMemBuf += uStreamFileSize;
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_InitBaseForProcesses1(uFreeMemBuf, DECODING_DMB);
MFC_GetBaseBufEndAddr(&uFreeMemBuf);
// 2. Reserve the stream buffer, & load the first part of a stream
//-----------------------------------------------------------------
#if USE_SD_STORAGE
while(!SDHC_OpenMedia(SDHC_HCLK, &oSdhc));
bFat_FileLoad=FAT_LoadFileSystem(&oSdhc);
if (!bFat_FileLoad)
Assert(0);
if(bFat_FileLoad==false) //to avoid duplicate display
{
FAT_GetTotalNumOfFiles(&uTotalNumOfFiles, &oSdhc);
for (i=0; i<uTotalNumOfFiles; i++)
{
FAT_GetFileName(i, pFileName, &oSdhc);
Disp("%02d -- %s\n", i, pFileName);
}
}
Disp(" Which file to read ? ");
sel = GetIntNum();
Assert(nReadUnit%uBlkSz == 0);
FAT_GetFileSize(sel, (s32 *)&uStreamFileSize, &oSdhc);
uStreamBufStAddr = uFreeMemBuf;
uFreeMemBuf += DMB_STREAM_BUF_SIZE; // Reserved for stream buf.
Assert(uStreamBufStAddr%STREAM_WR_SIZE == 0);
nReadSize = (uStreamFileSize < nReadUnit) ? uStreamFileSize : nReadUnit;
uStreamOffset = nReadSize;
if (!FAT_ReadFile4(sel, 0, (nReadSize+uBlkSz-1)/uBlkSz, uStreamBufStAddr, &oSdhc))
Assert(0);
#else
uStreamBufStAddr = uFreeMemBuf;
uFreeMemBuf += DMB_STREAM_BUF_SIZE; // Reserved for stream buf.
Assert(uStreamBufStAddr%STREAM_WR_SIZE == 0);
nReadSize = (uStreamFileSize < nReadUnit) ? uStreamFileSize : nReadUnit;
uStreamOffset = nReadSize;
memcpy((void *)uStreamBufStAddr, (void *)uStreamFileAddr, nReadSize);
#endif
// 3. Init a process of MFC
//--------------------------
#if USE_SD_STORAGE
FAT_GetFileExt(sel, fileExt, &oSdhc);
MFC_GetCodecModeByName(fileExt, true, &eDecMode);
Assert(eDecMode == AVC_DEC);
#endif
uProcessIdx=0;
uFrameBufStAddr = uFreeMemBuf;
MFC_InitProcessForDmbDecoding(uProcessIdx, uStreamBufStAddr, DMB_STREAM_BUF_SIZE,
uFrameBufStAddr, bDecRotModeEn);
MFC_GetProcessBufEndAddr(uProcessIdx, &uFreeMemBuf);
MFC_SetWrPtr(uProcessIdx, uStreamBufStAddr+nReadSize);
INTC_SetVectAddr(NUM_MFC,Isr_Mfc);
INTC_Enable(NUM_MFC);
// 4. Init LCDC
//---------------
uLcdFbAddr = uFreeMemBuf;
eLcdBpp = RGB24;
LCD_InitDISPC(eLcdBpp, uLcdFbAddr, WIN0, false);
LCD_GetFbEndAddr(&uFreeMemBuf, WIN0); // Get the free mem buffer addr
// 5. Init POST
//---------------
MFC_GetSrcPicSize(uProcessIdx, &uPicHsz, &uPicVsz);
MFC_GetDispFrameNum(uProcessIdx, &uDispFrameNum);
uRotWidth = (uDecRotDeg%180 == 0) ? uPicHsz : uPicVsz;
uRotHeight = (uDecRotDeg%180 == 0) ? uPicVsz : uPicHsz;
LCD_GetFrmSz(&uLcdWidth, &uLcdHeight, WIN0);
POST_InitIp(uRotWidth, uRotHeight, uFrameBufStAddr, YC420,
uLcdWidth, uLcdHeight,uLcdFbAddr, eLcdBpp, uDispFrameNum, false, ONE_SHOT, &oPost);
INTC_SetVectAddr(NUM_POST0, Isr_Post);
INTC_Enable(NUM_POST0);
POST_EnableInterrupt(POST_LEVEL_INT, &oPost);
frameCount=0;
LCD_Start();
while (GetKey() == 0) // loop until any key is pressed.
{
// 6. Decode one frame
//---------------------
bStreamBufEmpty = false;
bMfcDone = false;
MFC_SetDecRotEn(bDecRotModeEn);
if (bDecRotModeEn)
MFC_SetDecRotationMode(bDecMirHor, bDecMirVer, uDecRotDeg);
MFC_StartDecodingOneFrame(uProcessIdx);
while(bMfcDone != true);
if (MFC_DoPostProcessingOfDecoding(uProcessIdx, bStreamBufEmpty, &uFrameIdx) == false)
break;
frameCount++;
// 7. Convert the frame for display
//----------------------------------
bPostDone = false;
POST_StartProcessing1(uFrameIdx, 0, &oPost);
while(bPostDone == false);
LCD_Trigger();
// 8. Load stream if necessary
//------------------------------
if (uStreamFileSize == uStreamOffset)
{
MFC_NotifyNoMoreStream(uProcessIdx);
}
else if (MFC_IsMoreStreamNeeded(uProcessIdx, nReadUnit))
{
if ((uStreamFileSize-uStreamOffset) < nReadUnit)
nReadSize = (uStreamFileSize-uStreamOffset);
else
nReadSize = nReadUnit;
#if USE_SD_STORAGE
if (!FAT_ReadFile4(sel, uStreamOffset/uBlkSz, (nReadSize+uBlkSz-1)/uBlkSz, uStreamBufStAddr+uStreamOffset%DMB_STREAM_BUF_SIZE, &oSdhc))
Assert(0);
#else
memcpy((void *)(uStreamBufStAddr+uStreamOffset%DMB_STREAM_BUF_SIZE), (void *)(uStreamFileAddr+uStreamOffset), nReadSize);
#endif
uStreamOffset += nReadSize;
MFC_SetWrPtr(uProcessIdx, uStreamBufStAddr+uStreamOffset%DMB_STREAM_BUF_SIZE);
}
}
#if USE_SD_STORAGE
FAT_UnloadFileSystem(&oSdhc);
SDHC_CloseMedia(&oSdhc);
#endif
MFC_IssueSeqEndCmd(uProcessIdx);
MFC_StopBitProcessor();
}
//////////
// Function Name : Compare128
// Function Description : This function compares 2 quad words
// Input : a0, a1, qwords
// Output : ok or err
// Version :
bool Compare128(u32 a0, u32 a1, u32 qwords)
{
u32 i;
for(i=0;i<(qwords*4);)
{
if(*(u8 *)(a0+i)!=*(u8 *)(a1+i))
return 0;
i+=1;
}
return 1;
}
//////////
// Function Name : FindFrameBufferDiff
// Function Description : This function compares 2 YUV images
// Input :
// Output : NONE
// Version :
bool FindFrameBufferDiff(u32 a0, u32 a1, u32 bytes, u32 uWidth, u32 uHeight, u32* uPeakDiff, u32* uAvgDiff)
{
u8* pD0 = (u8 *)a0;
u8* pD1 = (u8 *)a1;
bool ret = true;
u32 uErrCnt = 0;
u32 uMaxDiff = 0;
u32 uSumDiff = 0;
u32 temp2, i;
u32 uYEndAddr = uWidth*uHeight;
u32 uCbEndAddr = uWidth*uHeight*5/4;
u32 uCrEndAddr = uWidth*uHeight*3/2;
u32 uStride = (uWidth%16 ==0) ? uWidth : (uWidth+15)/16*16;
u32 uNewHeight = (uHeight%16 ==0) ? uHeight : (uHeight+15)/16*16;
for (i=0; i<bytes; i++)
{
if (*pD0 != *pD1)
{
ret = false;
temp2 = (*pD0 > *pD1) ? *pD0-*pD1 : *pD1-*pD0;
if (uMaxDiff < temp2)
uMaxDiff = temp2;
uErrCnt++;
//Disp("%d:0x%x~0x%x: %d-%d ",i,(u32)pD0, (u32)pD1, *pD0,*pD1);
//Disp("%d: %d-%d ",i, *pD0, *pD1);
}
pD0++;
if ((i%uWidth == uWidth-1) && i<uYEndAddr)
{
pD1 = pD1 + (uStride-uWidth) + 1;
if (i==uYEndAddr-1)
{
pD1 = pD1 + uStride*(uNewHeight-uHeight);
}
}
else if (i>=uYEndAddr && i<uCrEndAddr && ((i-uYEndAddr)%(uWidth/2) == (uWidth/2-1)))
{
pD1 = pD1 + (uStride-uWidth)/2 + 1;
if (i==uCbEndAddr-1)
{
pD1 = pD1 + uStride*(uNewHeight-uHeight)/4;
}
}
else
{
pD1++;
}
}
if (ret == false)
{
Assert(uErrCnt>0);
//Disp("\nError Count=%d, Max diff=%d, Avg diff=%d\n", uErrCnt, uMaxDiff, uSumDiff/uErrCnt);
*uPeakDiff = uMaxDiff;
*uAvgDiff = uSumDiff/uErrCnt;
}
else
{
*uPeakDiff = 0;
*uAvgDiff = 0;
}
return ret;
}
//////////
// Function Name : CompareFrameBuffers
// Function Description : This function compares 2 YUV images
// Input :
// Output : NONE
// Version :
bool CompareFrameBuffers(
u32 a0, u32 width, u32 height,
u32 a1, u32 dispWidth, u32 dispHeight,
u32* uMaxAbsDiff, u32* uAvgDiff)
{
u32 uAbsDiff;
bool resultComp=true;
bool resultCompY;
u32 j;
bool resultCompCb;
u32 uCompStAddr;
u32 uFrameStAddr;
bool resultCompCr;
for (j=0; j<height; j++)
{
resultCompY = Compare128(a0+j*width, a1+j*dispWidth, width/16);
if (!resultCompY)
{
FindFrameBufferDiff(a0+j*width, a1+j*dispWidth, width, width, height, &uAbsDiff, uAvgDiff);
if (*uMaxAbsDiff < uAbsDiff)
{
*uMaxAbsDiff = uAbsDiff;
}
resultComp = false;
}
}
uCompStAddr = a0+width*height;
uFrameStAddr = a1+dispWidth*dispHeight;
for (j=0; j<height/2; j++)
{
resultCompCb = Compare128(uCompStAddr+j*width/2, uFrameStAddr+j*dispWidth/2, width/2/16);
if (!resultCompCb)
{
FindFrameBufferDiff(uCompStAddr+j*width/2, uFrameStAddr+j*dispWidth/2, width/2, width, height, &uAbsDiff, uAvgDiff);
if (*uMaxAbsDiff < uAbsDiff)
{
*uMaxAbsDiff = uAbsDiff;
}
resultComp = false;
}
}
uCompStAddr = a0+width*height*5/4;
uFrameStAddr = a1+dispWidth*dispHeight*5/4;
for (j=0; j<height/2; j++)
{
resultCompCr = Compare128(uCompStAddr+j*width/2, uFrameStAddr+j*dispWidth/2, width/2/16);
if (!resultCompCr)
{
FindFrameBufferDiff(uCompStAddr+j*width/2, uFrameStAddr+j*dispWidth/2, width/2, width, height, &uAbsDiff, uAvgDiff);
if (*uMaxAbsDiff < uAbsDiff)
{
*uMaxAbsDiff = uAbsDiff;
}
resultComp = false;
}
}
return resultComp;
}
//////////
// Function Name : TestDecConformanceEach
// Function Description : This function decodes a stream file and then
// compares the decoded YUV image with pre-made YUV image
// Input : NONE
// Output : NONE
// Version :
#if (USE_SD_STORAGE)
static void TestDecConformanceEach(void)
{
u32 uFreeMemBuf = CODEC_MEM_ST;
char pFileName[256];
u32 uTotalNumOfFiles, i;
int sel;
s32 nDecFileSize;
const int nBlkSz = 512;
const int nReadUnit = STREAM_BUF_SIZE/2;
int nReadSize;
u32 uStreamPtr;
u32 uStreamBufStAddr;
u32 selYuv;
u32 uProcessIdx;
u32 uFrameBufStAddr;
u32 picX, picY;
u32 uWidth, uHeight;
char fileExt[50];
u32 uYuvBufAddr;
u32 uYuvFrameSize;
u32 uFileOffset;
u32 uReturnAddr;
u32 uFrameAddrY;
u32 uAbsDiff;
u32 uMaxAbsDiff=0;
u32 uFrameIdx;
u32 uFrameCount = 0;
u32 uFrmNum;
u32 uErrMbNum;
MFC_CODEC_MODE eDecMode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -