?? encoder.c
字號:
#ifdef _DEBUG_PSNR
float psnr;
#endif
/* decide by Overflow. Add by fyh */
if(pEnc->rc_type)
IsOverFlow=IsSkipFrame(&pEnc->rc);/*判斷是否需要跳幀 */
else
IsOverFlow=FALSE;
/* skip frame flag is used by outputing reconstructed frame. */
pFrame->flag_skipframe=IsOverFlow;
if(!IsOverFlow)/*判斷是否需要跳幀*/
{
start_global_timer();
/* swap current frame structure and reference frame structure */
SWAP(pEnc->current, pEnc->reference);
pEnc->current->global_flags = pFrame->general;
pEnc->current->motion_flags = pFrame->motion;
/* copy source YUV buffer to YUV buffer of edged extending. Add by fyh */
start_timer();
/*
if (image_input
(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height,
pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace) < 0)
return XVID_ERR_FORMAT;
*/
image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height,
pEnc->mbParam.edged_width, pFrame->image);
stop_conv_timer();
/* copy source YUV data from pEnc->current->image to pEnc->sOriginal,
in order to calculate psnr value */
#ifdef _DEBUG_PSNR
image_copy(&pEnc->sOriginal, &pEnc->current->image,
pEnc->mbParam.edged_width, pEnc->mbParam.height);
#endif
/* bits streams initialize */
BitstreamInit(&bs, pFrame->bitstream, 0);
/* decide frame encoding type(I,P). Add by fyh */
if ((pEnc->iFrameNum == 0)
|| ((pEnc->iMaxKeyInterval > 0)
&& (pEnc->iFrameNum >= pEnc->iMaxKeyInterval)))
{
frametype=0;
}
else
{
frametype=1;
}
/* get frame level quantization step */
if(pEnc->rc_type)
pEnc->current->quant=RC_GetQ(pEncLogFile,&pEnc->rc,frametype,0);
else
pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0);
pEnc->mbParam.m_quant_type = MPEG4_QUANT;
/*write_vol_header=0;*/
/* coding I/P frame */
if(frametype==0)
/* pFrame->intra = FrameCodeI(pEnc, &bs, &bits,&head_vector,FALSE,&mad);*/
{
// pEnc->current->quant = pEnc->current->quant * 2 / 3;
pFrame->intra = FrameCodeI(pEnc, &bs, &bits,&head_vector,&mad);
}
else
/*pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header,&head_vector,&mad);*/
pFrame->intra = FrameCodeP(pEnc, &bs, &bits,&head_vector,&mad);
/* fyh comment code */
/*
BitstreamPutBits(&bs, 0xFFFF, 16);
BitstreamPutBits(&bs, 0xFFFF, 16);
*/
/* Pad bitstream to the next byte boundary. Add by fyh */
BitstreamPad(&bs);
/* Get frame bitstream length. Add by fyh */
pFrame->length = BitstreamLength(&bs);
/* reset frametype for scene changing. Add by fyh (comment code)*/
/*if(pFrame->intra) frametype=0;*/
/* update rate control model after encoding a frame. Add by fyh */
if(pEnc->rc_type)
After_encoding_current(pEncLogFile, &pEnc->rc,frametype,
pFrame->length*8,head_vector,mad);
else
RateControlUpdate(&pEnc->rate_control, pEnc->current->quant,
pFrame->length, pFrame->intra);
/* claculate psnr value for current encoding iamge */
#ifdef _DEBUG_PSNR
psnr =
image_psnr(&pEnc->sOriginal, &pEnc->current->image,
pEnc->mbParam.edged_width, pEnc->mbParam.width,
pEnc->mbParam.height);
pFrame->psnr=psnr;
#endif
/* output constructed image */
#ifdef _OUT_CONSTRUCT_IMAGE
/* image_output(&pEnc->current->image , pEnc->mbParam.width,pEnc->mbParam.height,
pEnc->mbParam.edged_width, pFrame->constructimage,
pFrame->stride ,pFrame->colorspace );*/
image_output(&pEnc->current->image , pEnc->mbParam.width,pEnc->mbParam.height,
pEnc->mbParam.edged_width, pFrame->constructimage,
pFrame->stride);
#endif
pEnc->iFrameNum++;
stop_global_timer();
write_timer();
}
else
{ pEnc->iFrameNum++;
pFrame->length=0;
pFrame->intra=0;
}
return XVID_ERR_OK;/* normal exit */
}
/*
set macoblock coding mode and quantization step size.
zero motion vector and sad value for motion estimation.
*/
static __inline void
CodeIntraMB(Encoder * pEnc,
MACROBLOCK * pMB)
{
/* set macoblock coding mode */
pMB->mode = MODE_INTRA;
/* zero mv statistics */
pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
pMB->mv16.x=pMB->mv16.y=0;/* fyh add code 2002.12.22*/
/* zero sad value */
pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
pMB->sad16 = 0;
/* set macoblock quantization step size */
pMB->quant = pEnc->current->quant;
}
/* store dct transform coefficient */
static int16_t dct_codes_storage[6*64+CACHE_LINE-1];
/* store quantization coefficient */
static int16_t qcoeff_storage[6*64+CACHE_LINE-1];
/*
scence_change: no meaning(delete)
*/
/*
static int
FrameCodeI(Encoder * pEnc,
Bitstream * bs,
uint32_t * pBits,int* head,BOOL scence_change,int *mad)*/
/*
Finish I frame encoding.
*/
static int /* frame type flag */
FrameCodeI(Encoder * pEnc, /* ponit to global Encoder structure */
Bitstream * bs, /* ponit to Bitstream structure */
uint32_t * pBits,/* bit streams length */
int* head,/* header information encoding bits number */
int *mad/* use mad value to measure encoding complexity */
)
{
uint16_t x, y;/* macroblock coordinate */
MACROBLOCK *pMB;
/*
int16_t dct_codes_storage[6*64+16-1];
int16_t *dct_codes=(int16_t *)((uint32_t)dct_codes_storage+
(16-1))&~((uint32_t)((uint32_t)(16)-1));
alloc dctcodes[6][64] and qcoeff[6][64]
*/
/* modify */
/*
DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
*/
/* point to dct transform coefficient buffer */
int16_t *dct_codes=(int16_t *)(((uint32_t)dct_codes_storage+
CACHE_LINE-1)&~(CACHE_LINE-1));
/* point to quantization coefficient buffer */
int16_t *qcoeff=(int16_t *)(((uint32_t)qcoeff_storage+
CACHE_LINE-1)&~(CACHE_LINE-1));
/* whq,2002.12.18,get dcscaler here */
/*
add dcscaler
*/
pEnc->current->lum_dcscaler = get_dc_scaler(pEnc->current->quant, 1);
pEnc->current->chrom_dcscaler = get_dc_scaler(pEnc->current->quant, 0);
/* whq,2002.12.18,get dcscaler here */
/*
if(scence_change==FALSE)
pEnc->iFrameNum = 0;
*/
pEnc->iFrameNum = 0;
/*
半像素插值時使用四舍五入
*/
/* pEnc->mbParam.m_rounding_type = 1;*/
pEnc->mbParam.m_rounding_type = 0;
pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
/* calculate mad value for I frame */
*mad=compute_MAD(pEnc);
pEnc->current->coding_type = I_VOP;
/* write vol and vop headers */
*head=BitstreamPos(bs);
BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
*pBits = BitstreamPos(bs);
*head=BitstreamPos(bs)-*head;
/* process all macroblock of frame */
for (y = 0; y < pEnc->mbParam.mb_height; y++)
{
for (x = 0; x < pEnc->mbParam.mb_width; x++)
{
/* get current macroblock structure address */
/*MACROBLOCK *pMB =
&pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];*/
pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
/* modify */
/* get mb quantization step size. Add by fyh */
CodeIntraMB(pEnc, pMB);
/*
pMB->mode = MODE_INTRA;
pMB->quant = pEnc->current->quant;
*/
/*whq,2002.12.18,add a param or struct member in pEnc->current*/
/* transform and quantize. */
MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,
dct_codes, qcoeff);
/* whq,2002.12.19,add prediction into transquant */
/*start_timer();
MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
stop_prediction_timer();
*/
/* whq */
/* vlc coding */
start_timer();
MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
stop_coding_timer();
}
}
/* get bit stream length */
*pBits = BitstreamPos(bs) - *pBits;
pEnc->mbParam.m_fcode = 1;
/* decide P frame type by use amvfast . Add by fyh */
first_P_gop=1;
return 1;
}
/*#define INTRA_THRESHOLD 0.5*/
/*
static int
FrameCodeP(Encoder * pEnc,
Bitstream * bs,
uint32_t * pBits,
bool force_inter,
bool vol_header,int* head_vector,int *mad)
*/
/*
Finish P frame encoding.
*/
static int /* frame type flag */
FrameCodeP(Encoder * pEnc,
Bitstream * bs, /* ponit to global Encoder structure */
uint32_t * pBits, /* bit streams length */
int* head_vector, /* header information and vector encoding bits number */
int *mad /* use mad value to measure encoding complexity */
)
{
/* int iLimit;*/
uint32_t x, y;/* current macroblock coordinate(unit: 16 pixel) */
int bIntra; /* intra macroblock flag */
MACROBLOCK *pMB;/* current macroblock structure address */
IMAGE *pRef = &pEnc->reference->image;/* reference image address */
/* midify */
/*
DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
*/
/* point to dct transform coefficient buffer */
int16_t *dct_codes=(int16_t *)(((uint32_t)dct_codes_storage+
CACHE_LINE-1)&~(CACHE_LINE-1));
/* point to quantization coefficient buffer */
int16_t *qcoeff=(int16_t *)(((uint32_t)qcoeff_storage+
CACHE_LINE-1)&~(CACHE_LINE-1));
/* reference image edge padding (include Y/U/V component) */
start_timer();
/* image_setedges(pRef, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
pEnc->mbParam.width, pEnc->mbParam.height,
pEnc->current->global_flags & XVID_INTERLACING);*/
image_setedges(pRef, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
pEnc->mbParam.width, pEnc->mbParam.height);
stop_edges_timer();
pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
pEnc->current->fcode = pEnc->mbParam.m_fcode;
/*
if (!force_inter)
iLimit =
(int) (pEnc->mbParam.mb_width * pEnc->mbParam.mb_height *
INTRA_THRESHOLD);
else
iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
*/
/* iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;*/
/* reference image half pixel interpolation (only process Y component)*/
if ((pEnc->current->global_flags & XVID_HALFPEL)) {
start_timer();
image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV,
&pEnc->vInterHV, pEnc->mbParam.edged_width,
pEnc->mbParam.edged_height,
pEnc->current->rounding_type);
stop_inter_timer();
}
/* motion estimation for current image */
start_timer();
/*bIntra =
MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference,
&pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,mad,
iLimit);*/
MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference,
&pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,mad);
stop_motion_timer();
/*
if (bIntra == 1)
{
return FrameCodeI(pEnc, bs, pBits,head_vector,TRUE,mad);
}
*/
/* write vop header and get header length */
*head_vector=BitstreamPos(bs);
pEnc->current->coding_type = P_VOP;
/*
if (vol_header)
BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
*/
BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
*pBits = BitstreamPos(bs);
*head_vector=BitstreamPos(bs)-*head_vector;
*head_vector=0;
/* whq,2002.12.18,get dcscaler here */
/*
add dcscaler
*/
pEnc->current->lum_dcscaler = get_dc_scaler(pEnc->current->quant, 1);
pEnc->current->chrom_dcscaler = get_dc_scaler(pEnc->current->quant, 0);
/* whq,2002.12.18,get dcscaler here */
/* macroblock level loop */
for (y = 0; y < pEnc->mbParam.mb_height; y++) {
for (x = 0; x < pEnc->mbParam.mb_width; x++) {
/* get current macroblock structure address */
/*
MACROBLOCK *pMB =
&pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];*/
pMB =&pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
if (!bIntra) {/* process inter macroblock */
/* motion compensation for inter macroblock */
start_timer();
MBMotionCompensation(pMB, x, y, &pEnc->reference->image,
&pEnc->vInterH, &pEnc->vInterV,
&pEnc->vInterHV, &pEnc->current->image,
dct_codes, pEnc->mbParam.width,
pEnc->mbParam.height,
pEnc->mbParam.edged_width,
pEnc->current->rounding_type);
stop_comp_timer();
pMB->quant = pEnc->current->quant;
/* modify */
/* pMB->field_pred = 0; */
/* transform and quantize for inter macroblock */
pMB->cbp =
MBTransQuantInter(&pEnc->mbParam, pEnc->current, pMB, x, y,
dct_codes, qcoeff);
} else {
/* process intra macroblock */
/* get quantization step size */
CodeIntraMB(pEnc, pMB);
/* transform and quantize for intra macroblock */
MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,
dct_codes, qcoeff);
/* whq,2002.12.19,add prediction into transquant*/
/*start_timer(); */
/*MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
stop_prediction_timer();*/
/*whq */
}
/* vlc coding for current macroblock */
start_timer();
*head_vector+=MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
stop_coding_timer();
}
}
pEnc->mbParam.m_fcode=1;/* motion vector range code */
*pBits = BitstreamPos(bs) - *pBits;/* get bit streams length */
/* decide P frame type by use amvfast . Add by fyh */
first_P_seq=0;
first_P_gop=0;
return 0; /* normal exit */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -