📄 vlx_test.c
字号:
/******************************************************************************
Filename: vlx_test.c
Descriptions
- vlx test main
History
-19.Dec.2003
draft
Copyright (c) 2003 SAMSUNG Electronics.
# However, Anybody can use this code without our permission.
******************************************************************************/
#include <stdlib.h>
#include <math.h>
#include "..\include\24a0addr.h"
#include "..\include\fim20_def.h"
#include "..\include\dctq_test.h"
#include "..\include\vlx_test.h"
#if (FIMVTEST_IMAGE_SIZE==QCIF)
#define FIMV_IMAGE_WIDTH (176)
#define FIMV_IMAGE_HEIGHT (144)
#define FIMV_DISPLAY_IMAGE_WIDTH (176+32)
#define FIMV_DISPLAY_IMAGE_HEIGHT (144+32)
#define TEST_PREV_IMAGE ((U32)image_a1p)
#define TEST_CURR_IMAGE ((U32)image_a2)
#elif (FIMVTEST_IMAGE_SIZE==CIF)
#define FIMV_IMAGE_WIDTH (352)
#define FIMV_IMAGE_HEIGHT (288)
#define FIMV_DISPLAY_IMAGE_WIDTH (240)
#define FIMV_DISPLAY_IMAGE_HEIGHT (196)
#define TEST_PREV_IMAGE ((U32)image_b1p)
#define TEST_CURR_IMAGE ((U32)image_b2)
#elif (FIMVTEST_IMAGE_SIZE==VGA)
#define FIMV_IMAGE_WIDTH (640)
#define FIMV_IMAGE_HEIGHT (480)
#define FIMV_DISPLAY_IMAGE_WIDTH (240)
#define FIMV_DISPLAY_IMAGE_HEIGHT (180)
#define TEST_PREV_IMAGE ((U32)image_c1p)
#define TEST_CURR_IMAGE ((U32)image_c2)
#endif
#define FIMV_MBLK_NUM ((FIMV_IMAGE_WIDTH/16)*(FIMV_IMAGE_HEIGHT/16))
#if (FIMVTEST_IMAGE_SIZE==QCIF)
extern const U8 image_a1p[];
extern const U8 image_a2[];
#endif
#if (FIMVTEST_IMAGE_SIZE==CIF)
extern const U8 image_b1p[];
extern const U8 image_b2[];
#endif
#if (FIMVTEST_IMAGE_SIZE==VGA)
extern U8 image_c1p[];
extern const U8 image_c2[];
#endif
extern volatile U32 dctqDone;
volatile U32 vlxDone;
void TestVlx(void)
{
IMAGE420 currImage; //no-padded image YCbCr420
IMAGE420 prevImage; //padded image YCbCr420
IMAGE420 refImage; //padded image YCbCr420
IMAGE420 refImage2; //padded image YCbCr420
IMAGE420 dctqCoeff; //no-padded, the size is twice than currImage.
IMAGE420 dctqCoeff2; //no-padded, the size is twice than currImage.
PQINFO pQInfo;
U32 *pVlcData;
U32 *pt;
U32 qinfoMode;
U32 dctq2VlcMode;
U32 imageWidth=FIMV_IMAGE_WIDTH;
U32 imageHeight=FIMV_IMAGE_HEIGHT;
U32 freeBufStartAddr=_NONCACHE_STARTADDRESS;
int i;
int j,k; //for debug
dctqDone = 0; vlxDone =0;
printf("clkdiv %08x\n", rCLKDIVN);
rCLKDIVN |= ( 1<<4);
printf("clkdiv %08x\n", rCLKDIVN);
printf("[DCTQ->VLC->VLD test]\n");
printf("Select VLC mode: 1) DCTQ->VLC 2) DCTQ->Mem->VLC :");
dctq2VlcMode=(getchar()=='1')?1:0;
printf("%s\n", dctq2VlcMode ? "1\n":"2\n" );
printf("Test Image size:%s\n",(FIMVTEST_IMAGE_SIZE==QCIF) ? "QCIF":
(FIMVTEST_IMAGE_SIZE==CIF) ? "CIF" :
(FIMVTEST_IMAGE_SIZE==VGA) ? "VGA" :
(FIMVTEST_IMAGE_SIZE==PQVGA)? "PQVGA":"Unknown");
printf("Select QINFO mode: 1)intra 2)intra_inter_0_2_4 3)intra_inter_01_45\n"
" 4)inter\n");
switch(getchar())
{
case '1':
qinfoMode=QINFO_INTRA_MODE;
break;
case '2':
qinfoMode=QINFO_INTRA_INTER_0_2_4;
break;
case '3':
qinfoMode=QINFO_INTRA_INTER_01_45;
break;
case '4':
qinfoMode=QINFO_INTER_MODE;
break;
default:
break;
}
printf("QINFO mode:%s\n",(qinfoMode &QINFO_INTRA_MODE) ? "Intra" :
(qinfoMode &QINFO_INTER_MODE) ? "Inter" :
(qinfoMode &QINFO_INTRA_INTER_0_2_4) ? "Intxx_0_2_4" :
(qinfoMode &QINFO_INTRA_INTER_01_45) ? "Intxx_01_45" : "" );
//currImage has already been in the read-only area.
AllocImage420(&currImage,TEST_CURR_IMAGE,imageWidth,imageHeight,IMAGE420_NO_PADDED);
printf("\ncurrImage addr: %x\n",TEST_CURR_IMAGE);
printf("The picture is the currImage. Press any key!\n");
getchar();
//previous mcedImage will be on the read-only area.
AllocImage420(&prevImage,TEST_PREV_IMAGE,imageWidth,imageHeight,IMAGE420_PADDED);
printf("prevImage addr(read only): %x\n",TEST_PREV_IMAGE);
//****************************************************************************
// (DCTQ-IDCTQ) -> VLC test
//****************************************************************************
//refImage is used for DctqEngine() as mced_input_image and recon_output image.
printf("\nreference image addr: %x\n",freeBufStartAddr);
freeBufStartAddr=AllocImage420(&refImage,freeBufStartAddr,imageWidth,imageHeight,
IMAGE420_PADDED|IMAGE420_CLEAR);
if(qinfoMode==QINFO_INTER_MODE)
{
CopyImage420(&refImage,&prevImage);
// if this image isn't copied, the result has to be almost same with the currImage.
}
printf("The picture is the refImage(mced & recon). Press any key!\n");
getchar();
printf("dctqCoeff addr: [%x,",freeBufStartAddr);
freeBufStartAddr=AllocImage420(&dctqCoeff,freeBufStartAddr,imageWidth,imageHeight,IMAGE420_DCTQ_COEFF|IMAGE420_CLEAR);
printf("qinfo%x)\n",freeBufStartAddr);
InitQInfo(&pQInfo,&freeBufStartAddr,imageWidth,imageHeight,qinfoMode);
//freeBufStartAddr+=4; //for debug
#if 1
// Initialize pVlcData area
pVlcData=(U32 *)0x12000000;
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));
#endif
if(dctq2VlcMode)
{
//DCTQ->direct->VLC
printf("\n=== DCTQ->direct->VLC path test ===\n");
VlxInitIsr();
DctqInitIsr();
#if VLX_GOB_OPERATION
for(i=0;i<(imageHeight/16);i++)
{
VlcConfig4DctqGob(imageWidth,(U32)pVlcData,(imageWidth/16),
((i==0)? VLX_FRAME_START_MODE: 0));
DctqEngineGob(&currImage,&refImage,&dctqCoeff,pQInfo,(imageWidth/16),
((i==0)? DCTQ_FRAME_START_MODE : 0) |
DCTQ_WITH_VLC_COEFF_WRITE);
while(dctqDone==0 || vlxDone==0); // ?? ows
printf("completed(DCTQ&VLC GOB=%d).\n",i);
}
#else
VlcConfig4Dctq(imageWidth,(U32)pVlcData,(imageWidth/16)*(imageHeight/16),0);
//mtimer_start();
DctqEngine(&currImage,&refImage,&dctqCoeff,pQInfo,DCTQ_WITH_VLC_COEFF_NOTWRITE);
printf("6= %08x\n",rVLX_OUT1);
//for debug
//printf("Wait until DCT_Q_IQ_IDCT & VLC is completed... ");
while(dctqDone==0 ){ printf("6= %08x\n",rVLX_OUT1);}
;
printf("completed!\n");
#endif
}
else
{
//DCTQ->MEM->VLC
printf("\n=== DCTQ->MEM->VLC path test ===\n");
DctqInitIsr();
VlxInitIsr();
#if VLX_GOB_OPERATION
for(i=0;i<(imageHeight/16);i++)
{
DctqEngineGob(&currImage,&prevImage,&dctqCoeff,pQInfo,(imageWidth/16),
((i==0)? DCTQ_FRAME_START_MODE: 0));
while(dctqDone==0);
printf("completed(DCTQ,GOB=%d),",i);
VlcEngineGob(&dctqCoeff,pQInfo,(U32)pVlcData,(imageWidth/16),
((i==0)? VLX_FRAME_START_MODE : 0));
while(vlxDone==0);
printf("completed(VLC,GOB=%d)!\n",i);
}
#else
DctqEngine(&currImage,&refImage,&dctqCoeff,pQInfo,0);
printf("1= %08x\n",rVLX_OUT1);
printf("Wait until DCT_Q_IQ_IDCT is completed... ");
while(dctqDone==0);
printf("completed!\n");
printf("2= %08x\n",rVLX_OUT1);
VlcEngine(&dctqCoeff,pQInfo,(U32)pVlcData,0);
printf("3= %08x\n",rVLX_OUT1);
printf("Wait until Mem->VLC is completed... ");
while(vlxDone==0);
printf("completed!\n");
#endif
}
printf("The picture is the recon image by DCTQ/IDCTQ. Press any key!\n");
getchar();
#if 0
//****************************************************************************
// VLD -> IDCTQ test
//****************************************************************************
printf("\n[VLD -> IDCTQ test]\n");
//refImage2 is used for DctqEngine() as mced_input_image and recon_output image.
freeBufStartAddr=AllocImage420(&refImage2,freeBufStartAddr,imageWidth,imageHeight,
IMAGE420_PADDED|IMAGE420_CLEAR);
/* //for debug
if(qinfoMode==QINFO_INTER_MODE)
{
CopyImage420(&refImage2,&prevImage);
//if this image isn't copied, the result has to be almost same with the currImage.
}
*/
printf("dctqCoeff2 addr: [%x,",freeBufStartAddr);
freeBufStartAddr=AllocImage420(&dctqCoeff2,freeBufStartAddr,imageWidth,imageHeight,IMAGE420_DCTQ_COEFF|IMAGE420_CLEAR);
printf("%x)\n",freeBufStartAddr);
DecodeVlcStream(&dctqCoeff2,pQInfo,(U32)pVlcData,0);
#if 1
printf("\nCompare the dctqCoeff & the dctqCoeff2!!\n");
for(i=0;i<(FIMV_IMAGE_HEIGHT*FIMV_IMAGE_WIDTH/2);i++)
{
j=*((U16 *)dctqCoeff.frameStartAddr+i);
k=*((U16 *)dctqCoeff2.frameStartAddr+i);
if(j!=k && (k!=0xffff)) // (k==0xffff) means a skipped m-block.
printf("Y: x,y=(%d,%d): dctq1:%x=%x, dctq2:%x=%x\n",
i%FIMV_IMAGE_WIDTH,i/FIMV_IMAGE_WIDTH,
dctqCoeff.frameStartAddr+i*2,j,dctqCoeff2.frameStartAddr+i*2,k);
}
for(i=0;i<(FIMV_IMAGE_HEIGHT*FIMV_IMAGE_WIDTH/4/2);i++)
{
j=*((U16 *)dctqCoeff.cbStartAddr+i);
k=*((U16 *)dctqCoeff2.cbStartAddr+i);
if(j!=k && (k!=0xffff))
printf("Cb: x,y=(%d,%d): dctq1:%x=%x, dctq2:%x=%x\n",
((i)%(FIMV_IMAGE_WIDTH/2)),(i/(FIMV_IMAGE_WIDTH/2)),
dctqCoeff.frameStartAddr+i*2,j,dctqCoeff2.frameStartAddr+i*2,k);
}
for(i=0;i<(FIMV_IMAGE_HEIGHT*FIMV_IMAGE_WIDTH/4/2);i++)
{
j=*((U16 *)dctqCoeff.crStartAddr+i);
k=*((U16 *)dctqCoeff2.crStartAddr+i);
if(j!=k && (k!=0xffff))
printf("Cr: x,y=(%d,%d): dctq1:%x=%x, dctq2:%x=%x\n",
((i)%(FIMV_IMAGE_WIDTH/2)),(i/(FIMV_IMAGE_WIDTH/2)),
dctqCoeff.frameStartAddr+i*2,j,dctqCoeff2.frameStartAddr+i*2,k);
}
printf("\n");
#endif
DctqEngine((PIMAGE420)0,&refImage2,&dctqCoeff2,pQInfo,DCTQ_DECODE_ONLY_MODE);
printf("Wait until IQ_IDCT is completed.\n");
while(dctqDone==0);
printf("IQ_IDCT is completed!\n");
printf("This is the recon image by VLD& IDCTQ from DctqCoeff & reference image.\n");
getchar();
#endif
}
/*****************************************************************************
subfunctons for decode vlc stream
*****************************************************************************/
void RestoreDcPredictedMblk(PIMAGE420 pDctqCoeff,U32 mx,U32 my,U32 qpStep,U32 cbpValue);
int CalDcScaler(int qp,int type);
void InitDcArray(void);
void DecodeVlcStream(PIMAGE420 pDctqCoeff,PQINFO pQInfo,U32 vlcDataAddr,U32 mode)
{
int i;
int opUnit;
U32 firstBitStuff;
U32 cbpValue,revCbpValue;
U32 wordCount;
U32 bitCount;
U32 *pStream=(U32 *)vlcDataAddr;
U32 xmbn,ymbn;
xmbn=pDctqCoeff->imageWidth/16;
ymbn=pDctqCoeff->imageHeight/16;
opUnit=xmbn*ymbn;
// VLCed stream data format
// not_coded_info[31:0], {word_count[31:16], bit_count[15:0]}, VLCed_coeff...
// - not_coded_info[5:0] : CBP_information , 0:skip 1:normal
// not_coded_info[31:6]: reserved
// The distance between not_coded_info: 0x200
InitDcArray();
for(i=0;i<opUnit;i++)
{
firstBitStuff=0; //VLCed stream starts always at firstBitStuff=0;
cbpValue=(*pStream&0x3f);
wordCount=*(pStream+1)>>16;
bitCount=*(pStream+1)&0xffff;
//printf("%dth MBlk:wc=%d,bc=%d,cbp=%xh \n",i,wordCount,bitCount,cbpValue);
VldEngine( pDctqCoeff,(U32)(pStream+2),firstBitStuff,cbpValue,pQInfo[i].qpStep,
(pQInfo[i].intraInter ? VLD_INTRA_MODE : VLD_INTER_MODE) |
((i==0) ? VLX_FRAME_START_MODE : 0) );
WaitForVldDone();
//This waiting time is waste of time. ...
//intraBlock needs S/W compensation because of VLC dc prediction.
if(pQInfo[i].intraInter==1)
{
RestoreDcPredictedMblk(pDctqCoeff,i%xmbn, i/xmbn,pQInfo[i].qpStep,cbpValue);
//macroBlock coordinate(x,my)=( i%xmbn , i/xmbn )
}
pStream+=(VLC_OUTPUT_OFFSET/4);
}
}
int CalDcScaler(int qp,int type)
{
int dcScaler;
if (type==1) // luminance :type=1
{
if (qp > 0 && qp < 5)
dcScaler = 8;
else if (qp > 4 && qp < 9)
dcScaler = 2 * qp;
else if (qp > 8 && qp < 25)
dcScaler = qp + 8;
else
dcScaler = 2 * qp - 16;
}
else // chrominance :type=2
{
if (qp > 0 && qp < 5)
dcScaler = 8;
else if (qp > 4 && qp < 25)
dcScaler = (qp + 13) / 2;
else
dcScaler = qp - 6;
}
return dcScaler;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -