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

📄 vlx_test.c

📁 支持三星原产的S3C24A0开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************

 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 + -