📄 mfc_test.c
字号:
uStreamOffset += nReadSize;
MFC_SetWrPtr(uProcessIdx, uStreamBufStAddr+uStreamOffset%STREAM_BUF_SIZE);
}
// 9. Display frame rate on the LCD
//----------------------------------
if((frameCount%10)==0)
{
GLIB_Printf(2, uDecHeight+6, "S3C6400 MFC Decoder(FPS=%.2f @%dx%d)",1000000*frameCount/fTotTime,picX,picY);
}
fOtherTime = StopTimer(0);
}
#if USE_SD_STORAGE
FAT_UnloadFileSystem(&oSdhc);
SDHC_CloseMedia(&oSdhc);
#endif
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();
}
//////////
// Function Name : TestDecodingOneFrameByOneFrame
// Function Description : This function decodes an stream file in line buffer mode
// Input : NONE
// Output : NONE
// Version :
#if (USE_SD_STORAGE)
#define MAX_FRAME_NUM 1500
static void TestDecodingOneFrameByOneFrame(void)
{
u32 uFreeMemBuf = CODEC_MEM_ST;
char pFileName[256];
u32 uTotalNumOfFiles;
int sel, i;
const int uBlkSz = 512;
const int nReadUnit = STREAM_BUF_SIZE/2;
s32 uStreamFileSize;
u32 uStreamBufStAddr;
char fileExt[50];
u32 uFrameBufStAddr;
u32 uProcessIdx =0;
u32 uLcdFbAddr;
CSPACE eLcdBpp;
u32 uPicHsz, uPicVsz;
u32 uDispFrameNum;
u32 uRotWidth;
u32 uRotHeight;
u32 uLcdWidth, uLcdHeight;
u32 uDecWidth, uDecHeight;
float fDecTime=0,fPostTime=0;
double fTotTime,fTotDecTime;
u32 picX, picY;
u32 uFrameIdx;
u32 frameCount;
MFC_CODEC_MODE eDecMode;
float frameRate;
u32 uStreamBufForSD = CODEC_MEM_ST + 0x02000000;
u32 uTemp32;
u32 uTemp32_1 = 0;
u32 uCopySize=1;
u8 *pucSrcMem;
u32 auFrameStartAddr[MAX_FRAME_NUM];
u32 j;
u32 uReadAmountByteSize=0; // Stream Buffer Read Amount.
bool bFilePlayEn;
bool bDynBufAllocEn;
bool bMp4DeblkEn;
u32 uMyFrameIndex;
bool bIsFirstFrame;
bool bIsCnMSeq=false;
u32 uNumOfH264IFrame;
u32 uBufferByteSize;
bool bIsHeader;
u32 uFrameStartAddr;
u32 uFrameSize;
u32 uNumOfFrames;
bool bIsMpeg4ShrotHeader;
bool bIsStreamCorrect = true;
bool bFat_FileLoad=false;
// 1. Move firmware and init base settings.
//--------------------------------------------------------------------------------
MFC_MoveFirmwareToCodeBuf(uFreeMemBuf);
MFC_GetCodeBufEndAddr(&uFreeMemBuf);
MFC_StartBitProcessor();
MFC_InitBaseForProcesses(uFreeMemBuf);
MFC_GetBaseBufEndAddr(&uFreeMemBuf);
// 2. Reserve the stream buffer, & load the first part of a stream
//--------------------------------------------------------------------------------
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, &uStreamFileSize, &oSdhc);
uStreamBufStAddr = uFreeMemBuf;
uFreeMemBuf += STREAM_BUF_SIZE; // Reserved for stream buf.
Assert(uStreamBufStAddr%STREAM_WR_SIZE == 0);
Disp("Stream Buffer Start Address: 0x%x \n", uStreamBufStAddr);
// 3. Loading Streams into uStreamBufForSD
//--------------------------------------------------------------------------------
if (!FAT_ReadFile4(sel, 0, (uStreamFileSize+uBlkSz-1)/uBlkSz, uStreamBufForSD, &oSdhc)) //+yktak Load a Stream from SDMMC into uStreamBufForSD
Assert(0);
FAT_GetFileExt(sel, fileExt, &oSdhc);
MFC_GetCodecModeByName(fileExt, true, &eDecMode);
uProcessIdx=0;
pucSrcMem = (u8 *) uStreamBufForSD;
switch(eDecMode)
{
case VC1_DEC:
bIsHeader = true;
uBufferByteSize = 0x10000;
auFrameStartAddr[0] = uStreamBufForSD;
Vsparser(eDecMode, auFrameStartAddr[0] , uBufferByteSize, bIsHeader,
&uFrameStartAddr, &uFrameSize, &uNumOfFrames,&bIsMpeg4ShrotHeader);
auFrameStartAddr[1] = uFrameStartAddr + uFrameSize;
bIsHeader =false;
Vsparser(eDecMode, auFrameStartAddr[1] , uBufferByteSize, bIsHeader,
&uFrameStartAddr, &uFrameSize, &uNumOfFrames,&bIsMpeg4ShrotHeader);
auFrameStartAddr[2] = uFrameStartAddr + uFrameSize;
uCopySize = auFrameStartAddr[2+uTemp32_1]- auFrameStartAddr[0];
uReadAmountByteSize = uReadAmountByteSize +uCopySize;
Copy8( auFrameStartAddr[0],uStreamBufStAddr,uCopySize);
bIsCnMSeq = true;
break;
case AVC_DEC:
// H.264 stream file parsing: Begin
//=============================================================================================
// Structure of H.264 encoded stream (in case 1 frame is composed of single slice).
// auFrameStartAddr[0] --- auFrameStartAddr[1]-1 : SPS+PPS+SEI+
// auFrameStartAddr[1] --- auFrameStartAddr[2]-1 : first I frame
// auFrameStartAddr[2] --- auFrameStartAddr[3]-1 : next P-frame
// ....
auFrameStartAddr[0] = (u32) pucSrcMem;
pucSrcMem++;
uNumOfFrames =1;
uMyFrameIndex =1;
uNumOfH264IFrame =0;
bIsFirstFrame = true;
// Multi Slice parsing!: 1 frame is composed of multi slices.
// find the first Non-IDR frame
for(i= 1; i < uStreamFileSize+1;i++)
{
if ((*(pucSrcMem) == 0x00) && (*(pucSrcMem+1) == 0x00)&& (*(pucSrcMem+2) == 0x00)
&& (*(pucSrcMem+3) == 0x01) && ( (*(pucSrcMem+4)&0x1f) == 0x01))
{
auFrameStartAddr[2] = (u32) pucSrcMem;
break;
}
pucSrcMem++;
}
pucSrcMem =(u8*) auFrameStartAddr[0] +1;
for(i= 1; i < auFrameStartAddr[2] - auFrameStartAddr[0] +1;i++)
{
if ((*(pucSrcMem) == 0x00) && (*(pucSrcMem+1) == 0x00)&& (*(pucSrcMem+2) == 0x00)
&& (*(pucSrcMem+3) == 0x01) && ( (*(pucSrcMem+4)&0x1f) == 0x05))
{
uNumOfH264IFrame++;
if(uNumOfH264IFrame ==1)
{
auFrameStartAddr[1] = (u32) pucSrcMem; // the first I frame
}
}
pucSrcMem++;
}
// finding the next P frame strat addresses.
j=3;
uTemp32 =0;
if (uNumOfH264IFrame != 1)
{
for(i= 1; i < uStreamFileSize - auFrameStartAddr[2] + auFrameStartAddr[0]+1;i++)
{
if ((*(pucSrcMem) == 0x00) && (*(pucSrcMem+1) == 0x00)&& (*(pucSrcMem+2) == 0x00)
&& (*(pucSrcMem+3) == 0x01) && ( (*(pucSrcMem+4)&0x1f) == 0x01))
{
uTemp32++;
if(uTemp32 == uNumOfH264IFrame)
{
auFrameStartAddr[j] = (u32) pucSrcMem;
j++;
uTemp32 =0;
uMyFrameIndex++;
}
}
pucSrcMem++;
}
uNumOfFrames = uMyFrameIndex+1;
Disp(" This file has %d frames \n", uNumOfFrames);
uCopySize = auFrameStartAddr[2]- auFrameStartAddr[0];
uReadAmountByteSize = uReadAmountByteSize +uCopySize;
// copy SPS+PPS+SEI+I-frame into Streambuffer
Copy8( auFrameStartAddr[0],uStreamBufStAddr,uCopySize);
break;
}
// 1 frame is composed of single slice.
pucSrcMem = (u8*) uStreamBufForSD;
for(i= 1; i < uStreamFileSize+1;i++)
{
if ((*(pucSrcMem) == 0x00) && (*(pucSrcMem+1) == 0x00)&& (*(pucSrcMem+2) == 0x00)
&& (*(pucSrcMem+3) == 0x01) &&( ( (*(pucSrcMem+4)&0x1f) == 0x01)||( (*(pucSrcMem+4)&0x1f) == 0x05)))
{
if(uMyFrameIndex > MAX_FRAME_NUM -1) { break;}
auFrameStartAddr[uMyFrameIndex] = (u32) pucSrcMem;
uMyFrameIndex++;
}
pucSrcMem++;
}
uNumOfFrames = uMyFrameIndex-1;
Disp(" This file has %d frames \n", uNumOfFrames);
uCopySize = auFrameStartAddr[2]- auFrameStartAddr[0];
uReadAmountByteSize = uReadAmountByteSize +uCopySize;
// copy SPS+PPS+SEI+I-frame into Streambuffer
Copy8( auFrameStartAddr[0],uStreamBufStAddr,uCopySize);
break;
case MP4_DEC:
// MPEG4 stream file parsing: Begin
//=============================================================================================
// Structure of MPEG4 encoded stream
// auFrameStartAddr[0] --- auFrameStartAddr[1]-1 : VOS + VOP layer header
// auFrameStartAddr[1] --- auFrameStartAddr[2]-1 : 1st frame
// ....
// find start_code
bIsHeader = true;
uBufferByteSize = 0x10000;
Vsparser(eDecMode, uStreamBufForSD , uBufferByteSize, bIsHeader,
&uFrameStartAddr, &uFrameSize, &uNumOfFrames,&bIsMpeg4ShrotHeader);
auFrameStartAddr[0] = uFrameStartAddr;
auFrameStartAddr[1] = uFrameStartAddr + uFrameSize;
if(bIsMpeg4ShrotHeader == true)
{
bIsFirstFrame = true;
}
uCopySize = auFrameStartAddr[1]- auFrameStartAddr[0];
uReadAmountByteSize = uReadAmountByteSize +uCopySize;
// copy VOP+VOS Header into Streambuffer
Copy8( auFrameStartAddr[0],uStreamBufStAddr,uCopySize);
break;
//=============================================================================================
// MPEG4 stream file parsing: End
default:
return;
}
// ##### FramebyFrame Decoding (fileplay mode) Init : Begin #####
//=============================================================================================
uFrameBufStAddr = uFreeMemBuf;
bFilePlayEn = true;
bDynBufAllocEn = true;
bDecRotModeEn = false;
bH264ReorderEn = false; // if reordering is enabled, then MFC needs 16 frames to decode in advance.
bMp4DeblkEn = false;
MFC_InitProcessForOneFrameDecoding(
uProcessIdx, eDecMode, uStreamBufStAddr,STREAM_BUF_SIZE,
uFrameBufStAddr, bDecRotModeEn,bMp4DeblkEn, bH264ReorderEn,bFilePlayEn, bDynBufAllocEn);
MFC_GetProcessBufEndAddr(uProcessIdx, &uFreeMemBuf);
INTC_SetVectAddr(NUM_MFC,Isr_Mfc); //SMDK S/W
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
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 Decoder");
// 5. Init POST
//-------------------------------------------
MFC_GetSrcPicSize(uProcessIdx, &uPicHsz, &uPicVsz);
MFC_GetDispFrameNum(uProcessIdx, &uDispFrameNum);
uRotWidth = (uDecRotDeg%180 == 0) ? uPicHsz : uPicVsz;
uRotHeight = (uDecRotDeg%180 == 0) ? uPicVsz : uPicHsz;
POST_InitIp1(
uRotWidth, uRotHeight, 0, 0, uRotWidth, uRotHeight, uFrameBufStAddr, 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);
fTotTime=0;
fTotDecTime=0;
frameCount=0;
MFC_GetDecSrcFormat(&picX, &picY, &frameRate);
LCD_Start();
// Decode all frames
//-------------------------------------------
j = 1; //Current Frame
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);
switch(eDecMode)
{
case VC1_DEC:
if(bIsCnMSeq == true)
{
bIsCnMSeq = false;
j++;
j = j+ uTemp32_1;
break;
}
bIsHeader =false;
uBufferByteSize = 0x10000;
Vsparser(eDecMode, auFrameStartAddr[j] , uBufferByteSize, bIsHeader,
&uFrameStartAddr, &uFrameSize, &uNumOfFrames,&bIsMpeg4ShrotHeader);
auFrameStartAddr[j+1] = uFrameStartAddr + uFrameSize;
uCopySize = auFrameStartAddr[j+1] - auFrameStartAddr[j];
uReadAmountByteSize = uReadAmountByteSize +uCopySize;
Copy8( auFrameStartAddr[j],uStreamBufStAddr,uCopySize);
MFC_SetWrPtr2(uProcessIdx, uStreamBufStAddr + uCopySize);
j++;
break;
case AVC_DEC:
if (bIsFirstFrame == true) // In H.264 case You, should not feed I-frame in the first PIC_RUN
{
bIsFirstFrame = false;
j++;
break;
}
uCopySize = auFrameStartAddr[j+1] - auFrameStartAddr[j];
uReadAmountByteSize = uReadAmountByteSize +uCopySize;
Copy8( auFrameStartAddr[j],uStreamBufStAddr,uCopySize);
j++;
break;
case MP4_DEC:
if(bIsFirstFrame == true)
{
bIsFirstFrame= false;
break;
}
bIsHeader =false;
uBufferByteSize = 0x10000;
bIsStreamCorrect = Vsparser(eDecMode, auFrameStartAddr[j] , uBufferByteSize, bIsHeader,
&uFrameStartAddr, &uFrameSize, &uNumOfFrames,&bIsMpeg4ShrotHeader);
if(bIsStreamCorrect == false)
{
break;
}
auFrameStartAddr[j+1] = uFrameStartAddr + uFrameSize;
uCopySize = auFrameStartAddr[j+1] - auFrameStartAddr[j];
uReadAmountByteSize = uReadAmountByteSize +uCopySize;
Copy8( auFrameStartAddr[j],uStreamBufStAddr,uCopySize);
j++;
break;
default:
return;
}
StartTimer(0);
if(bIsStreamCorrect == false)
{
bIsStreamCorrect = true;
Disp("Stream End or Stream Error! \n");
break;
}
MFC_InitStreamBufferForOneFrameDecoding(uProcessIdx, uStreamBufStAddr, uCopySize);
MFC_StartDecodingOneFrame(uProcessIdx);
while(bMfcDone != true);
fDecTime = StopTimer(0);
fTotTime += fDecTime;
fTotDecTime += fDecTime;
if (MFC_DoPostProcessingOfDecoding(uProcessIdx, bStreamBufEmpty, &uFrameIdx) == false)
break;
frameCount++;
if((s32)uFrameIdx==-3)
continue;
// 7. Convert the frame for display
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -