📄 framecode.c
字号:
#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 + -