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

📄 framecode.c

📁 DM642的mpeg4编码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>


#include <csl.h>
#include <csl_dat.h>
#include <csl_edma.h>
#include <csl_edmahal.h>

#include "framecode.h"
#include "../mempry/mem.h"

#include "../dct/dct.h"
#include "../dct/idct.h" 
//#include "../motioncompute/motioncompute.h"
#include "../motioncompensation/pixel_motion_compensation.h"

#include "../mpeg4/writempegheader.h"
#include "../mpeg4/mpeg4vlc.h"
#include "../mpeg4/mblockcode.h"

#define	 SWAP(_T_,A,B)		{ _T_ tmp = A; A = B; B = tmp; }

#define IEXTMBWIDTH  26

#pragma DATA_ALIGN(DCT_COEFF, 8);
#pragma DATA_SECTION(DCT_COEFF, ".internal_data1");
short DCT_COEFF[384];

/*
#pragma DATA_ALIGN(PIXEL_COEFF, 8);
#pragma DATA_SECTION(PIXEL_COEFF, ".internal_data1");
short PIXEL_COEFF[384];
*/
#pragma DATA_ALIGN(iCurMBData1, 8);
#pragma DATA_SECTION(iCurMBData1, ".internal_data1");
short iCurMBData1[384];

#pragma DATA_ALIGN(curentPingBuffer, 8);
#pragma DATA_ALIGN(curentPongBuffer, 8);

#pragma DATA_SECTION(curentPingBuffer, ".internal_data1");
#pragma DATA_SECTION(curentPongBuffer, ".internal_data1");

//乒乓缓冲的数据
unsigned char curentPingBuffer[6*64*IEXTMBWIDTH];
unsigned char curentPongBuffer[6*64*IEXTMBWIDTH];


#pragma DATA_ALIGN(curentRecPingBuffer, 8);
#pragma DATA_ALIGN(curentRecPongBuffer, 8);

#pragma DATA_SECTION(curentRecPingBuffer, ".internal_data1");
#pragma DATA_SECTION(curentRecPongBuffer, ".internal_data1");

//乒乓缓冲的数据
unsigned char curentRecPingBuffer[6*64*IEXTMBWIDTH];
unsigned char curentRecPongBuffer[6*64*IEXTMBWIDTH];



#pragma DATA_ALIGN(refPingBuffer, 8);
#pragma DATA_ALIGN(refPongBuffer, 8);

#pragma DATA_SECTION(refPingBuffer, ".internal_data1");
#pragma DATA_SECTION(refPongBuffer, ".internal_data1");
	
unsigned char refPingBuffer[3*6*64*IEXTMBWIDTH];
unsigned char refPongBuffer[3*6*64*IEXTMBWIDTH];

//#pragma CODE_SECTION(IMG_fdct_8x8, ".internal_code1");
//#pragma CODE_SECTION(IMG_idct_8x8, ".internal_code1");

unsigned int Encode(unsigned char* pchBuffer, Encoder* pEncoder)
{  
	Stream	bs;
	int		iCodingType;

	StreamInitial(&bs, pchBuffer, 0);
	
	iCodingType = pEncoder->pCurFrameInfo->vop_coding_type;

	switch (iCodingType) 
	{
	case I_VOP:
		I_FrameCodingDMA(&bs, pEncoder);
		break;
	case P_VOP:
		pFrameEncode8EDMA(pEncoder,&bs);
		break;

	case B_VOP:
		printf("can't support B_VOP!\n");
		break;

	case S_VOP:
		printf("can't support S_VOP!\n");
		break;

	case N_VOP: 
		printf("can't support N_VOP!\n");
		break;

	default:
		break;
	}
    
	pEncoder->iFrameNo++;

	pEncoder->pCurFrameInfo->length = GetStreamLength(&bs);

	return GetStreamLength(&bs);
}


int I_FrameCodingDMA(Stream* bs, Encoder* pEncoder)
{
   short ix, iy;

   short i;
   
   int iPosition,iPositionLum, iPositionChro;

   short iMBWidth, iMBHeight;

   short iMBNo = 0, iQuant;

   short iDcScalarLum, iDcScalarChr;

   short iStride = pEncoder->pCurFrameInfo->vop_extwidth;

   short iStrideHalf = iStride/2;

   MacroBlock * pCurMB = NULL;			//当前编码的宏块

   MacroBlock * MBs =  pEncoder->pCurFrameInfo->pMB;
 
// EDMA_Handle hEdma1;
// EDMA_Handle hEdma2;
//   EDMA_Handle hEdma3;
    //乒乓缓存中放一行宏块的数据
   Image8 BufferPingPong[4];

   Image8 *CurrentFrameBufferPing=&BufferPingPong[0];
   Image8 *CurrentFrameBufferPong=&BufferPingPong[1];

   Image8 *CurRecFrameBufferPing=&BufferPingPong[2];
   Image8 *CurRecFrameBufferPong=&BufferPingPong[3];

	short iExtMBWidth; 
	int transferIdY,transferIdYRec;
	
   pEncoder->pCurFrameInfo->vop_quant = 5;

   WriteMpeg4Header(bs, pEncoder);
   iMBWidth = pEncoder->pVol->video_object_layer_width / 16;
   iMBHeight = pEncoder->pVol->video_object_layer_height / 16;

	iExtMBWidth=iMBWidth+4;
   //乒乓缓存中放一行宏块的数据
   CurrentFrameBufferPing->Y=curentPingBuffer;
   CurrentFrameBufferPing->Cb=curentPingBuffer+64*4*iExtMBWidth;
   CurrentFrameBufferPing->Cr=curentPingBuffer+64*4*iExtMBWidth+64*iExtMBWidth;
 
   CurrentFrameBufferPong->Y=curentPongBuffer;
   CurrentFrameBufferPong->Cb=curentPongBuffer+64*4*iExtMBWidth;
   CurrentFrameBufferPong->Cr=curentPongBuffer+64*4*iExtMBWidth+64*iExtMBWidth;

 //乒乓缓存中放一行宏块的数据
   CurRecFrameBufferPing->Y=refPingBuffer;
   CurRecFrameBufferPing->Cb=refPingBuffer+64*4*iExtMBWidth;
   CurRecFrameBufferPing->Cr=refPingBuffer+64*4*iExtMBWidth+64*iExtMBWidth;
 
   CurRecFrameBufferPong->Y=refPongBuffer;
   CurRecFrameBufferPong->Cb=refPongBuffer+64*4*iExtMBWidth;
   CurRecFrameBufferPong->Cr=refPongBuffer+64*4*iExtMBWidth+64*iExtMBWidth;

   GetStreamPosition(bs);
 
   //先将第一行的宏块拷贝到乓缓冲中
   //起始行的地址
	iPositionLum = -IMAGE_EDGE;
   iPositionChro =-IMAGE_EDGE_HALF;
	
	//Cb
	DAT_copy(iPositionChro + pEncoder->pCurImage8->Cb,CurrentFrameBufferPong->Cb,64*iExtMBWidth);
	DAT_copy(iPositionChro + pEncoder->pCurImage8->Cr,CurrentFrameBufferPong->Cr,64*iExtMBWidth);
	transferIdY=DAT_copy(iPositionLum + pEncoder->pCurImage8->Y,CurrentFrameBufferPong->Y,4*64*iExtMBWidth);
	
   //按行进行编码
   for (iy = 0; iy < iMBHeight; iy++) 
   {
		DAT_wait(transferIdY);
		SWAP(Image8*,CurrentFrameBufferPing, CurrentFrameBufferPong);
	
		//EDMA将图象的下一行从外存搬移到内存
		if(iy<iMBHeight-1)
		{
			//起始行的地址
			iPositionLum = (iy+1) * iStride * 16-IMAGE_EDGE;
			iPositionChro =(iy+1) * iStrideHalf * 8-IMAGE_EDGE_HALF;
			
			DAT_copy(iPositionChro + pEncoder->pCurImage8->Cb,CurrentFrameBufferPong->Cb,64*iExtMBWidth);
			DAT_copy(iPositionChro + pEncoder->pCurImage8->Cr,CurrentFrameBufferPong->Cr,64*iExtMBWidth);
			transferIdY=DAT_copy(iPositionLum + pEncoder->pCurImage8->Y,CurrentFrameBufferPong->Y,4*64*iExtMBWidth);
		}
		
		CurrentFrameBufferPing->Y+=IMAGE_EDGE;
		CurrentFrameBufferPing->Cb+=IMAGE_EDGE_HALF;
		CurrentFrameBufferPing->Cr+=IMAGE_EDGE_HALF;
	   
		CurRecFrameBufferPong->Y+=IMAGE_EDGE;
			CurRecFrameBufferPong->Cb+=IMAGE_EDGE_HALF;
			CurRecFrameBufferPong->Cr+=IMAGE_EDGE_HALF;
		//对一行内的宏块逐个进行编码
	   for (ix = 0; ix < iMBWidth; ix++)
	   { 
		   iMBNo = ix + iy * iMBWidth;		//获得当前编码的宏块号
			
		   pCurMB = &MBs[iMBNo];			//将当前编码的宏块给pCurMB
		
		   // I Frame's MacroBlock Type is INTRA, MV and DMV is 0 
		   //设置编码模式为帧内编码 ;将和运动相关的变量设为0
		   pCurMB->mb_type = MB_INTRA;		
		   pCurMB->Mv[0].x = pCurMB->Mv[0].y = pCurMB->Mv[1].x = pCurMB->Mv[1].y = pCurMB->Mv[2].x = pCurMB->Mv[2].y = pCurMB->Mv[3].x = pCurMB->Mv[3].y = 0;
	       pCurMB->DMV[0].x = pCurMB->DMV[0].y = pCurMB->DMV[1].x = pCurMB->DMV[1].y = pCurMB->DMV[2].x = pCurMB->DMV[2].y = pCurMB->DMV[3].x = pCurMB->DMV[3].y = 0;
			//设置当前宏块的量化值
		   iQuant = pCurMB->quant = pEncoder->pCurFrameInfo->vop_quant;
			
		   iDcScalarLum = GetDcScaler(iQuant, 1);
		   iDcScalarChr = GetDcScaler(iQuant, 0);

		   if (pCurMB->mb_type == MB_INTRA_Q || pCurMB->mb_type == MB_INTER_Q)
		   {
			   iQuant = iQuant + pCurMB->dquant;
			   CLIP(iQuant, 1, 31);
		   }	   

           //  DCT transform, and get the pEncoder->pDctImage  
         
			
		   //将待编码图象的当前宏块放到PIXEL_COEFF[384]中,并对其进行DCT变换,将得到的值放到DCT_COEFF[384]中,
		 //lvxu080326*************************************
		 	for (i = 0; i < 4; i++)
		   {   
			   	iPositionLum = ix*16+iStride * ((i/2)*8)+ (i%2)*8;
			   //将图象当前块的亮度值读到PIXEL_COEFF中
			    TransferImage8ToBlock16(DCT_COEFF+i*64, iPositionLum + CurrentFrameBufferPing->Y ,iStride);  
		   }
		     iPositionChro =ix * 8;
			//U
            TransferImage8ToBlock16(DCT_COEFF+4*64,  iPositionChro + CurrentFrameBufferPing->Cb, iStrideHalf);
			//V
		    TransferImage8ToBlock16(DCT_COEFF+5*64,  iPositionChro + CurrentFrameBufferPing->Cr, iStrideHalf);
			//对Y/U/V分量进行fdct变换
		  	IMG_fdct_8x8(DCT_COEFF,6);
			
		
			
	/*		 //Y
		   for (i = 0; i < 4; i++)
		   {   
			   	iPositionLum = ix*16+iStride * ((i/2)*8)+ (i%2)*8;
			   //将图象当前块的亮度值读到PIXEL_COEFF中
			    TransferImage8ToBlock16(PIXEL_COEFF+i*64, iPositionLum + CurrentFrameBufferPing->Y ,iStride);  
		   }
		     iPositionChro =ix * 8;
			//U
            TransferImage8ToBlock16(PIXEL_COEFF+4*64,  iPositionChro + CurrentFrameBufferPing->Cb, iStrideHalf);
			//V
		    TransferImage8ToBlock16(PIXEL_COEFF+5*64,  iPositionChro + CurrentFrameBufferPing->Cr, iStrideHalf);
			//对Y/U/V分量进行fdct变换
		   for(i=0;i<6;i++)
		   {
				 fdct(DCT_COEFF+i*64,PIXEL_COEFF+i*64);
		   }
	*/	   
		   //**********************************
			
		   //将DCT系数进行intra方式的量化,量化后的数值放到原处DCT_COEFF。
		   //  quant, default h263 type 
		   if (!pEncoder->pVol->quant_type)
		   {
			   Mpeg4IntraQuant2(DCT_COEFF, DCT_COEFF, iQuant, iDcScalarLum);
			   Mpeg4IntraQuant2(DCT_COEFF+64, DCT_COEFF+64, iQuant, iDcScalarLum);
			   Mpeg4IntraQuant2(DCT_COEFF+128, DCT_COEFF+128, iQuant, iDcScalarLum);
			   Mpeg4IntraQuant2(DCT_COEFF+192, DCT_COEFF+192, iQuant, iDcScalarLum);

			   Mpeg4IntraQuant2(DCT_COEFF+256, DCT_COEFF+256, iQuant, iDcScalarChr);
			   Mpeg4IntraQuant2(DCT_COEFF+320, DCT_COEFF+320, iQuant, iDcScalarChr);
		   }
		   else 
		   {
			   Mpeg4IntraQuant1(DCT_COEFF, DCT_COEFF, iQuant, iDcScalarLum, pEncoder->pVol->load_intra_quant_mat);
			   Mpeg4IntraQuant1(DCT_COEFF+64, DCT_COEFF+64, iQuant, iDcScalarLum, pEncoder->pVol->load_intra_quant_mat);
			   Mpeg4IntraQuant1(DCT_COEFF+128, DCT_COEFF+128, iQuant, iDcScalarLum, pEncoder->pVol->load_intra_quant_mat);
			   Mpeg4IntraQuant1(DCT_COEFF+192, DCT_COEFF+192, iQuant, iDcScalarLum, pEncoder->pVol->load_intra_quant_mat);

			   Mpeg4IntraQuant1(DCT_COEFF+256, DCT_COEFF+256, iQuant, iDcScalarChr, pEncoder->pVol->load_intra_quant_mat);
			   Mpeg4IntraQuant1(DCT_COEFF+320, DCT_COEFF+320, iQuant, iDcScalarChr, pEncoder->pVol->load_intra_quant_mat);
		   }
		   
		   // macroblock coding 
		   CodeIntraMB(bs, pEncoder, pCurMB, ix, iy, DCT_COEFF);

		   //  dequant 
           if (!pEncoder->pVol->quant_type)
		   {
			   Mpeg4IntraDeQuant2(DCT_COEFF, DCT_COEFF, iQuant, iDcScalarLum);
			   Mpeg4IntraDeQuant2(DCT_COEFF+64, DCT_COEFF+64, iQuant, iDcScalarLum);
			   Mpeg4IntraDeQuant2(DCT_COEFF+128, DCT_COEFF+128, iQuant, iDcScalarLum);
			   Mpeg4IntraDeQuant2(DCT_COEFF+192, DCT_COEFF+192, iQuant, iDcScalarLum);

			   Mpeg4IntraDeQuant2(DCT_COEFF+256, DCT_COEFF+256, iQuant, iDcScalarChr);
			   Mpeg4IntraDeQuant2(DCT_COEFF+320, DCT_COEFF+320, iQuant, iDcScalarChr);
		   }
		   else 
		   {
			   Mpeg4IntraDeQuant1(DCT_COEFF, DCT_COEFF, iQuant, iDcScalarLum, pEncoder->pVol->load_intra_quant_mat);
			   Mpeg4IntraDeQuant1(DCT_COEFF+64, DCT_COEFF+64, iQuant, iDcScalarLum, pEncoder->pVol->load_intra_quant_mat);
			   Mpeg4IntraDeQuant1(DCT_COEFF+128, DCT_COEFF+128, iQuant, iDcScalarLum, pEncoder->pVol->load_intra_quant_mat);
			   Mpeg4IntraDeQuant1(DCT_COEFF+192, DCT_COEFF+192, iQuant, iDcScalarLum, pEncoder->pVol->load_intra_quant_mat);

			   Mpeg4IntraDeQuant1(DCT_COEFF+256, DCT_COEFF+256, iQuant, iDcScalarChr, pEncoder->pVol->load_intra_quant_mat);
			   Mpeg4IntraDeQuant1(DCT_COEFF+320, DCT_COEFF+320, iQuant, iDcScalarChr, pEncoder->pVol->load_intra_quant_mat);
		   }	
	
		   //帧重建***************************************************************
		/*	for(i=0; i<6; i++)
				idct(DCT_COEFF+64*i);
 		*/
			IMG_idct_8x8(DCT_COEFF,6);
		
			for (i = 0; i < 384; i++)
				CLIP(DCT_COEFF[i],0,255);
		
			//reconstruct the image

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -