?? mbtransquant.c
字號:
/******************************************************************************
* *
* This file is part of XviD, a free MPEG-4 video encoder/decoder *
* *
* XviD is an implementation of a part of one or more MPEG-4 Video tools *
* as specified in ISO/IEC 14496-2 standard. Those intending to use this *
* software module in hardware or software products are advised that its *
* use may infringe existing patents or copyrights, and any such use *
* would be at such party's own risk. The original developer of this *
* software module and his/her company, and subsequent editors and their *
* companies, will have no liability for use of this software or *
* modifications or derivatives thereof. *
* *
* XviD is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* XviD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
* *
******************************************************************************/
/******************************************************************************
* *
* mbtransquant.c *
* *
* Copyright (C) 2001 - Peter Ross <pross@cs.rmit.edu.au> *
* Copyright (C) 2001 - Michael Militzer <isibaar@xvid.org> *
* *
* For more information visit the XviD homepage: http://www.xvid.org *
* *
******************************************************************************/
/******************************************************************************
* *
* Revision history: *
* *
* 29.03.2002 interlacing speedup - used transfer strides instead of
* manual field-to-frame conversion
* 26.03.2002 interlacing support - moved transfers outside loops
* 22.12.2001 get_dc_scaler() moved to common.h
* 19.11.2001 introduced coefficient thresholding (Isibaar) *
* 17.11.2001 initial version *
* *
******************************************************************************/
#include <string.h>
#include "../user_macro.h"
#include "../portab.h"
#include "mbfunctions.h"
#include "../global.h"
#include "mem_transfer.h"
#include "timer.h"
#include "../dct/fdct.h"
#include "../dct/idct.h"
#include "../quant/quant_mpeg4.h"
/*#include "../quant/quant_h263.h"*/
#include "../encoder.h"
/* whq,2002.12.19 */
/*#include "../prediction/mbprediction.h"*/
#include "../bitstream/cbp.h"
/*!
****************************************************************************
*
* Add prediction in MBTransQuantIntra, 2002.12.22, by whq
*
***************************************************************************
*/
#define TOOSMALL_LIMIT 1 /* skip blocks having a coefficient sum below this value */
/* whq,2002.12.19 prediction */
/*whq,2002.12.18*/
extern int16_t dc_quant[2][31];
/**************************ADD by zjy***************************/
extern FILE *ftestlog;
/***************************************************************/
/*whq,2002.12.18*/
static const int16_t default_acdc_values[15] = {
1024,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
};
/*!
****************************************************************************
* \brief
*
* predict ac,dc direction according to the neighbour blocks
*
***************************************************************************
*/
void
predict_acdc(MACROBLOCK * pMBs, /*<-- macroblock struct */
uint32_t x, /*<-- macroblock row pos */
uint32_t y, /*<-- macroblock column pos */
uint32_t mb_width, /*<-- macroblock number in a row */
uint32_t block, /*<-- block number in a macroblock */
int16_t qcoeff[64], /*<-- quant orig value,no use now*/
uint32_t current_quant, /*<-- quant value */
uint32_t chrom_lumflag, /*<-- chrom or lum block */
int16_t predictors[8]) /*<--> first row or column predict value */
{
/* whq,2002.12.17 ,delete */
/*
const int mbpos = (y * mb_width) + x;
*/
/*宏塊的左、上、對角宏塊的預測值*/
int16_t *left, *top, *diag, *current;
/* whq,2002.12.17 */
/* save the first col and first row predict value */
/*塊的左、上、對角塊的預測值*/
const int16_t *pLeft = default_acdc_values;
const int16_t *pTop = default_acdc_values;
const int16_t *pDiag = default_acdc_values;
int32_t level0,sign0;
uint32_t index = x + y * mb_width; /*current macroblock*/
int *acpred_direction = &pMBs[index].acpred_directions[block];
uint32_t i;
/*whq,2002.12.18*/
int16_t (*q)[31];
q = dc_quant;
left = top = diag = current = 0;
/* use x,y to judge the macroblocks position */
/* grab left,top and diag macroblocks*/
/* 當前宏塊的左邊、上邊,對角線宏塊 */
/* left macroblock*/
if (x &&
(pMBs[index - 1].mode == MODE_INTRA ||
pMBs[index - 1].mode == MODE_INTRA_Q))
{
left = pMBs[index - 1].pred_values[0];
}
/* top macroblock*/
if (y&&(pMBs[index - mb_width].mode == MODE_INTRA ||
pMBs[index - mb_width].mode == MODE_INTRA_Q)) {
top = pMBs[index - mb_width].pred_values[0];
}
/* diag macroblock */
if (x && y &&
(pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {
diag = pMBs[index - 1 - mb_width].pred_values[0];
}
current = pMBs[index].pred_values[0];
/* now grab pLeft, pTop, pDiag _blocks_,for block level only */
/* 判斷當前塊所使用左邊塊,上邊塊和對角線塊 */
switch (block) {
case 0:
if (left)
pLeft = left + MBPRED_SIZE;
if (top)
pTop = top + (MBPRED_SIZE << 1);
if (diag)
pDiag = diag + 3 * MBPRED_SIZE;
break;
case 1:
pLeft = current;
/* whq,2002.12.17 ,delete */
/*
left_quant = current_quant;
*/
if (top) {
pTop = top + 3 * MBPRED_SIZE;
pDiag = top + (MBPRED_SIZE << 1);
}
break;
case 2:
if (left) {
pLeft = left + 3 * MBPRED_SIZE;
pDiag = left + MBPRED_SIZE;
}
pTop = current;
/* whq,2002.12.17 ,delete */
/*
top_quant = current_quant;
*/
break;
case 3:
pLeft = current + (MBPRED_SIZE << 1);
/* whq,2002.12.17 ,delete */
/*
left_quant = current_quant;
top_quant = current_quant;
*/
pTop = current + MBPRED_SIZE;
pDiag = current;
break;
case 4:
if (left)
pLeft = left + (MBPRED_SIZE << 2);
if (top)
pTop = top + (MBPRED_SIZE << 2);
if (diag)
pDiag = diag + (MBPRED_SIZE << 2);
break;
case 5:
if (left)
pLeft = left + 5 * MBPRED_SIZE;
if (top)
pTop = top + 5 * MBPRED_SIZE;
if (diag)
pDiag = diag + 5 * MBPRED_SIZE;
break;
}
/* determine ac prediction direction & ac/dc predictor*/
/* place rescaled ac/dc predictions into predictors[] for later use*/
/* 根據水平和垂直梯度判斷預測值,pTop等中dc保存的是原始值,未經量化,
ac保存的是經過量化的,predictor中保存的是量化后的還是?????*/
if (abs(pLeft[0] - pDiag[0]) < abs(pDiag[0] - pTop[0])) {
*acpred_direction = 1; /* vertical*/
/*whq,2002.12.17, ???????????????*/
/* whq,2002.12.18,look up the table to convert div to mul */
/*predictors[0] = DIV_DIV(pTop[0], iDcScaler);*/
sign0 = max(min(pTop[0],1),-1);
level0 = abs(pTop[0]);
predictors[0] =(level0*(*(*(q+chrom_lumflag)+current_quant-1))+32768)>>16;
predictors[0] = sign0*predictors[0];
/*predictors[0] = pTop[0];*/
for (i = 1; i < 8; i++) {
/* whq,2002.12.17 ,delete */
/*
predictors[i] = rescale(top_quant, current_quant, pTop[i]);
*/
predictors[i] = pTop[i];
}
} else {
*acpred_direction = 2; /* horizontal*/
/*whq,2002.12.17, ???????????????*/
/*predictors[0] = DIV_DIV(pLeft[0], iDcScaler);*/
sign0 = max(min(pLeft[0],1),-1);
level0 = abs(pLeft[0]);
predictors[0] =(level0*(*(*(q+chrom_lumflag)+current_quant-1))+32768)>>16;
predictors[0] = sign0*predictors[0];
/*predictors[0] = pLeft[0];*/
for (i = 1; i < 8; i++) {
/* whq,2002.12.17 ,delete */
/*
predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
*/
predictors[i] = pLeft[i + 7];
}
}
}
/*!
****************************************************************************
* \brief
*
* compute the diff between sum of abs(level) and sum of
* abs(predict-diff) for deciding predict or not
*
***************************************************************************
*/
int32_t /*==> return the diff to judge use prediction or not*/
calc_acdc(MACROBLOCK * pMB, /*<-- macroblock struct */
uint32_t block, /*<-- block number in a macroblock */
int16_t qcoeff[64], /*<--> in:quant orig value/out:dc diff,other not change*/
uint32_t iDcScaler, /*<-- dc quant scaler */
int16_t predictors[8] /*<--> in:predict row or column value
/out:dc not change,but ac is the diff*/
)
{
int16_t *pCurrent = pMB->pred_values[block];
uint32_t i;
uint32_t S1 = 0, S2 = 0;
int16_t level;
/* store current coeffs to pred_values[] for future prediction */
/* pCurrent[0]??,whq,2002.12.17 ,
qcoeff[0]的意義是dc經過量化的結果
恢復成量化前的,用于以后塊的dc預測*/
pCurrent[0] = qcoeff[0] * iDcScaler;
for (i = 1; i < 8; i++) {
pCurrent[i] = qcoeff[i];
pCurrent[i + 7] = qcoeff[i * 8];
}
/* subtract predictors and store back in predictors[] */
/*whq,predictors ?? */
/*qcoeff[0] = qcoeff[0] - predictors[0];*/
/*dc must be predict,ac is not sure */
/* whq,2002.12.18 */
qcoeff[0] = qcoeff[0] - predictors[0];
if (pMB->acpred_directions[block] == 1) {
for (i = 1; i < 8; i++) {
level = qcoeff[i];
S2 += abs(level);
level -= predictors[i];
S1 += abs(level);
predictors[i] = level;
}
} else /*acpred_direction == 2*/
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -