📄 mfc_test.c
字号:
/**************************************************************************************
*
* Project Name : S3C6400 Validation
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is only for validating functions of the S3C6400.
* Anybody can use this software without our permission.
*
*--------------------------------------------------------------------------------------
*
* File Name : mfc_test.c
*
* File Description : This file implements mfc test functions.
*
* Author : Haksoo,Kim
* Dept. : AP Development Team
* Created Date : 2007/01/xx
* Version : 0.1
*
* History
* - Created(Haksoo,Kim 2007/01/xx)
*
**************************************************************************************/
#include "option.h"
#include "library.h"
#include "mfc.h"
#include "sdhc.h"
#include "lcd.h"
#include "post.h"
#include "glib.h"
#include "timer.h"
#include "fat.h"
#include "intc.h"
#include "sysc.h"
#include "vsparser.h"
#include <string.h>
#include <stdlib.h>
#define MFC_MEMORY_BASE (_DRAM_BaseAddress+0x01000000)
#define STREAM_BUF_SIZE (720*576*3) // >= 720*576*3 (worst case)
#define DMB_STREAM_BUF_SIZE (64*1024) // for DMB decoding
#define USE_SD_STORAGE TRUE
#define MULTI_DEC_ONE_ENC TRUE
#define MFC_CLOCK_CHANGE FALSE
static volatile bool bMfcDone;
static volatile bool bPostDone;
static volatile bool bStreamBufEmpty;
static bool bH264ReorderEn;
static bool bDecRotModeEn;
static u32 uDecRotDeg;
static bool bDecMirHor;
static bool bDecMirVer;
static MFC_CODEC_MODE eEncMode;
static bool bIsH263;
static char pSrcYUVFileName[256];
static u32 uEncWidth;
static u32 uEncHeight;
static u32 uEncTotalFrameNum;
#if (USE_SD_STORAGE && MULTI_DEC_ONE_ENC)
static u32 uEncFrameRate;
static bool bEncSliceMode;
static bool bEncSliceSizeMode;
static u32 uEncSliceSizeNum;
static u32 uEncIntraRefreshNum;
static u32 uEncGopNum;
static bool bEncRcEnable;
static u32 uEncRcBitRate;
static u32 uEncRcInitDelay;
static u32 uEncRcBufSize;
static u32 uEncPicQs;
static int uEncChromaQpOffset;
static u32 uEncDeblkMode;
static int uEncDeblkAOffset;
static int uEncDeblkBOffset;
static bool bEncAnnexJ;
static bool bEncAnnexK;
static bool bEncAnnexT;
static bool bEncDataPartEn;
static bool bEncRevVlcEn;
static u32 uEncIntraDcVlcThr;
#endif //#if (MULTI_DEC_ONE_ENC)
static bool bAllRotating=false;
static bool bAllRotateFirst=false;
#if (USE_SD_STORAGE)
static SDHC oSdhc;
#endif
static POST oPost;
//////////
// Function Name : Isr_Mfc
// Function Description : MFC ISR
// Input : NONE
// Output : NONE
// Version :
static void __irq Isr_Mfc(void)
{
MFC_INT_FLAG eFlag;
MFC_GetIntFlag(&eFlag);
if (eFlag == INT_MFC_BIT_BUF_EMPTY)
{
bStreamBufEmpty = true;
Disp(" empty ");
}
MFC_ClearPending(eFlag);
bMfcDone = true;
INTC_ClearVectAddr();
}
//////////
// Function Name : Isr_Post
// Function Description : Post Processor ISR defined for MFC test
// Input : NONE
// Output : NONE
// Version :
static void __irq Isr_Post(void)
{
POST_ClearPending(&oPost);
bPostDone = true;
INTC_ClearVectAddr();
}
//////////
// Function Name : SetRotationMode
// Function Description : This function sets rotation mode of decoder
// Input : NONE
// Output : NONE
// Version :
static void SetRotationMode(void)
{
int sel;
Disp("MFC Rotation mode ( [1]enable, [2]disable ) : ");
sel = GetIntNum();
bDecRotModeEn = (sel == 1) ? true : false;
if (bDecRotModeEn == true) // rot enable
{
Disp("Select Rot degree ([0]0, [1]90, [2]180, [3]270) :");
sel = GetIntNum();
Assert(sel >= 0 && sel < 4);
uDecRotDeg = sel*90;
Disp("Select Mirror mode ([0]No Mirroring, [1]Mirroring Horizontally [2]Mirroring Vertically [3]Mirroring in both way) :");
sel = GetIntNum();
Assert(sel >= 0 && sel < 4);
bDecMirHor = (sel == 1 || sel == 3) ? true : false;
bDecMirVer = (sel == 2 || sel == 3) ? true : false;
}
else
{
uDecRotDeg = 0;
bDecMirHor = false;
bDecMirVer = false;
}
}
//////////
// Function Name : TestDecoding
// Function Description : This function decodes an stream file and displays the generated YUV
// Input : NONE
// Output : NONE
// Version :
static void TestDecoding(void)
{
u32 uFreeMemBuf = MFC_MEMORY_BASE;
#if (USE_SD_STORAGE)
char pFileName[256];
u32 uTotalNumOfFiles;
char fileExt[50];
static int sel, i;
const int uBlkSz = 512;
bool bFat_FileLoad=false;
#else
u32 uStreamFileAddr;
#endif
const int nReadUnit = STREAM_BUF_SIZE/2;
static 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 uDecWidth, uDecHeight;
float fDecTime=0,fPostTime=0,fOtherTime=0;
double fTotTime,fTotDecTime;
u32 uFrameIdx;
u32 frameCount;
static MFC_CODEC_MODE eDecMode;
float frameRate;
u32 picX, picY;
bool bRealTimePlay=false;
#if (!USE_SD_STORAGE)
// 0. Download the stream file thru USB.
//-------------------------------------------
uStreamFileAddr = uFreeMemBuf;
if((bAllRotating==false)||(bAllRotateFirst==true))
{
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_InitBaseForProcesses(uFreeMemBuf);
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((bAllRotating==false)||(bAllRotateFirst==true))
{
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 += 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 += 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);
#else
if((bAllRotating==false)||(bAllRotateFirst==true))
{
Disp("\nSelect Decoder mode: \n");
Disp("[0] MPEG4/H.263\n");
Disp("[1] H.264\n");
Disp("[2] VC-1\n");
eDecMode = (MFC_CODEC_MODE)GetIntNum();
if(eDecMode>2)
return;
eDecMode = (eDecMode==0) ? MP4_DEC : (eDecMode==1) ? AVC_DEC : VC1_DEC ;
}
#endif
if((bAllRotating==false)&&(eDecMode != AVC_DEC))
{
Disp("\n If you want to play the recon image in real time mode, \n");
Disp(" press 'y' key [Default : non-real time mode]\n");
if(Getc()=='y')
bRealTimePlay = true;
Putc('\n');
}
uProcessIdx=0;
bH264ReorderEn = true;
uFrameBufStAddr = uFreeMemBuf;
if (eDecMode == MP4_DEC)
MFC_InitProcessForDecodingMpeg4(uProcessIdx, uStreamBufStAddr, STREAM_BUF_SIZE,
uFrameBufStAddr, bDecRotModeEn, true);
else if (eDecMode == AVC_DEC)
MFC_InitProcessForDecodingH264(uProcessIdx, uStreamBufStAddr, STREAM_BUF_SIZE,
uFrameBufStAddr, bDecRotModeEn, bH264ReorderEn);
else if (eDecMode == VC1_DEC)
MFC_InitProcessForDecodingVc1(uProcessIdx, uStreamBufStAddr, STREAM_BUF_SIZE,
uFrameBufStAddr, bDecRotModeEn);
else
Assert(0);
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
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);
uRotWidth = (uDecRotDeg%180 == 0) ? uPicHsz : uPicVsz;
uRotHeight = (uDecRotDeg%180 == 0) ? uPicVsz : uPicHsz;
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();
while (GetKey() == 0) // loop until any key is pressed.
{
// 6. Decode one frame
//---------------------
StartTimer(0);
bStreamBufEmpty = false;
bMfcDone = false;
MFC_SetDecRotEn(bDecRotModeEn);
if (bDecRotModeEn)
MFC_SetDecRotationMode(bDecMirHor, bDecMirVer, uDecRotDeg);
MFC_StartDecodingOneFrame(uProcessIdx);
while(bMfcDone != true);
fDecTime = StopTimer(0);
fTotTime += fDecTime;
fTotDecTime += fDecTime;
if (MFC_DoPostProcessingOfDecoding(uProcessIdx, bStreamBufEmpty, &uFrameIdx) == false)
{
while(bPostDone == false);
break;
}
if((bRealTimePlay==true)&&((fPostTime!=0)||(fOtherTime!=0)))
{
s32 sDelay=1000000/frameRate-fDecTime-fPostTime-fOtherTime;
if(sDelay>0)
DelayfrTimer(micro, (u32)sDelay);
fPostTime = 0;
fOtherTime = 0;
}
// 7. Convert the frame for display
//----------------------------------
StartTimer(0);
MFC_GetDispFrameNum(uProcessIdx, &uDispFrameNum);
if (frameCount==0)
bPostDone = true;
while(bPostDone == false);
bPostDone = false;
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);
POST_StartProcessing1(uFrameIdx, 0, &oPost);
LCD_Trigger();
fPostTime = StopTimer(0);
fTotTime += fPostTime;
frameCount++;
// 8. Load stream if necessary
//------------------------------
StartTimer(0);
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%STREAM_BUF_SIZE, &oSdhc))
Assert(0);
#else
memcpy((void *)(uStreamBufStAddr+uStreamOffset%STREAM_BUF_SIZE), (void *)(uStreamFileAddr+uStreamOffset), nReadSize);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -