📄 mvmb.c
字号:
#include <stdlib.h>
#include <string.h>
#include "MVGlobal.h"
#include "MVBitstream.h"
#include "MVCommon.h"
#include "MVMc.h"
#include "MVIdct.h"
#include "MVMb.h"
#include "MVBlock.h"
#include "MVMv.h"
extern VLC const mcbpc_intra_table[64];
extern VLC const cbpy_table[64];
extern const int16_t default_acdc_values[15];
extern VLC const dc_lum_tab[];
extern const VLC dcy_tab[511];
extern VLC const mcbpc_inter_table[257];
extern const int32_t dquant_table[4];
extern const uint32_t roundtab_76[16];
extern const uint32_t roundtab_79[4];
int get_mcbpc_intra(Bitstream * bs)
{
uint32_t index;
index = BitstreamShowBits(bs, 9);
index >>= 3;
BitstreamSkip(bs, mcbpc_intra_table[index].len);
return mcbpc_intra_table[index].code;
}
int get_mcbpc_inter(Bitstream * bs)
{
uint32_t index;
index = MIN(BitstreamShowBits(bs, 9), 256);
BitstreamSkip(bs, mcbpc_inter_table[index].len);
return mcbpc_inter_table[index].code;
}
int get_cbpy(Bitstream * bs, int intra)
{
int cbpy;
uint32_t index = BitstreamShowBits(bs, 6);
BitstreamSkip(bs, cbpy_table[index].len);
cbpy = cbpy_table[index].code;
if (!intra)
cbpy = 15 - cbpy;
return cbpy;
}
int32_t get_mbtype(Bitstream * bs)
{
int32_t mb_type;
for (mb_type = 0; mb_type <= 3; mb_type++)
if (BitstreamGetBit(bs))
return (mb_type);
return -1;
}
int get_dc_size_lum(Bitstream * bs)
{
int code, i;
code = BitstreamShowBits(bs, 11);
for (i = 11; i > 3; i--) {
if (code == 1) {
BitstreamSkip(bs, i);
return i + 1;
}
code >>= 1;
}
BitstreamSkip(bs, dc_lum_tab[code].len);
return dc_lum_tab[code].code;
}
int get_dc_size_chrom(Bitstream * bs)
{
uint32_t code, i;
code = BitstreamShowBits(bs, 12);
for (i = 12; i > 2; i--) {
if (code == 1) {
BitstreamSkip(bs, i);
return i;
}
code >>= 1;
}
return 3 - BitstreamGetBits(bs, 2);
}
int get_dc_dif(Bitstream * bs, uint32_t dc_size)
{
int code = BitstreamGetBits(bs, dc_size);
int msb = code >> (dc_size - 1);
if (msb == 0)
return (-1 * (code ^ ((1 << dc_size) - 1)));
return code;
}
void predict_acdc(MACROBLOCK * pMBs,
uint32_t x,
uint32_t y,
uint32_t mb_width,
uint32_t block,
int16_t qcoeff[64],
uint32_t current_quant,
int32_t iDcScaler,
int16_t predictors[8],
const int bound)
{
const int mbpos = (y * mb_width) + x;
int16_t *left, *top, *diag, *current;
int32_t left_quant = current_quant;
int32_t top_quant = current_quant;
const int16_t *pLeft = default_acdc_values;
const int16_t *pTop = default_acdc_values;
const int16_t *pDiag = default_acdc_values;
uint32_t index = x + y * mb_width; /* current macroblock */
int *acpred_direction = &pMBs[index].acpred_directions[block];
uint32_t i;
left = top = diag = current = NULL;
if (x && mbpos >= bound + 1 &&
(pMBs[index - 1].mode == MODE_INTRA ||
pMBs[index - 1].mode == MODE_INTRA_Q))
{
left = (int16_t*)pMBs[index - 1].pred_values[0];
left_quant = pMBs[index - 1].quant;
}
/* top macroblock */
if (mbpos >= bound + (int)mb_width &&
(pMBs[index - mb_width].mode == MODE_INTRA ||
pMBs[index - mb_width].mode == MODE_INTRA_Q))
{
top = (int16_t*)pMBs[index - mb_width].pred_values[0];
top_quant = pMBs[index - mb_width].quant;
}
/* diag macroblock */
if (x && mbpos >= bound + (int)mb_width + 1 &&
(pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q))
{
diag = (int16_t*)pMBs[index - 1 - mb_width].pred_values[0];
}
current = (int16_t*)pMBs[index].pred_values[0];
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;
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;
top_quant = current_quant;
break;
case 3:
pLeft = current + (MBPRED_SIZE << 1);
left_quant = current_quant;
pTop = current + MBPRED_SIZE;
top_quant = current_quant;
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;
}
if (abs(pLeft[0] - pDiag[0]) < abs(pDiag[0] - pTop[0]))
{
*acpred_direction = 1; /* vertical */
predictors[0] = DIV_DIV(pTop[0], iDcScaler);
for (i = 1; i < 8; i++)
{
predictors[i] = rescale(top_quant, current_quant, pTop[i]);
}
}
else
{
*acpred_direction = 2; /* horizontal */
predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
for (i = 1; i < 8; i++)
{
predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
}
}
return ;
}
void add_acdc(MACROBLOCK * pMB, uint32_t block,
int16_t dct_codes[64], uint32_t iDcScaler,
int16_t predictors[8], const int bsversion)
{
uint8_t acpred_direction = pMB->acpred_directions[block];
int16_t *pCurrent = (int16_t*)pMB->pred_values[block];
uint32_t i;
dct_codes[0] += predictors[0]; /* dc prediction */
pCurrent[0] = dct_codes[0]*iDcScaler;
if (!bsversion || bsversion > BS_VERSION_BUGGY_DC_CLIPPING)
{
pCurrent[0] = CLIP(pCurrent[0], -2048, 2047);
}
if (acpred_direction == 1)
{
for (i = 1; i < 8; i++)
{
int level = dct_codes[i] + predictors[i];
dct_codes[i] = level;
pCurrent[i] = level;
pCurrent[i + 7] = dct_codes[i * 8];
}
}
else
if(acpred_direction == 2)
{
for (i = 1; i < 8; i++)
{
int level = dct_codes[i * 8] + predictors[i];
dct_codes[i * 8] = level;
pCurrent[i + 7] = level;
pCurrent[i] = dct_codes[i];
}
}
else
{
for (i = 1; i < 8; i++)
{
pCurrent[i] = dct_codes[i];
pCurrent[i + 7] = dct_codes[i * 8];
}
}
}
void decoder_mbintra(DECODER * dec,
MACROBLOCK * pMB,
const uint32_t x_pos,
const uint32_t y_pos,
const uint32_t acpred_flag,
const uint32_t cbp,
Bitstream * bs,
const uint32_t quant,
const uint32_t intra_dc_threshold,
const unsigned int bound)
{
/* wuhaibin 2007-01-17*/
uint8_t block_header [1024];
uint8_t data_header [1024];
int16_t* block = (int16_t*)((uint32_t)(block_header + CACHE_LINE - 1)
&(~(uint32_t)(CACHE_LINE - 1)));
int16_t* data = (int16_t*)((uint32_t)(data_header + CACHE_LINE - 1)
&(~(uint32_t)(CACHE_LINE - 1)));
//DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
//DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
uint32_t stride = dec->edged_width;
uint32_t stride2 = stride / 2;
uint32_t next_block = stride * 8;
uint32_t i;
uint32_t iQuant = pMB->quant;
uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
memset(block, 0, 6 * 64 * sizeof(int16_t)); /* clear */
for (i = 0; i < 6; i++)
{
uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);
int16_t predictors[8];
int start_coeff;
predict_acdc(dec->mbs, x_pos, y_pos, dec->mb_width, i, &block[i * 64],
iQuant, iDcScaler, predictors, bound);
if (!acpred_flag)
{
pMB->acpred_directions[i] = 0;
}
if (quant < intra_dc_threshold)
{
int dc_size;
int dc_dif;
dc_size = i < 4 ? get_dc_size_lum(bs) : get_dc_size_chrom(bs);
dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0;
if (dc_size > 8)
{
BitstreamSkip(bs, 1); /* marker */
}
block[i * 64 + 0] = dc_dif;
start_coeff = 1;
}
else
{
start_coeff = 0;
}
if (cbp & (1 << (5 - i))) /* coded */
{
int direction = dec->alternate_vertical_scan ?
2 : pMB->acpred_directions[i];
get_intra_block(bs, &block[i * 64], direction, start_coeff);
}
add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors, dec->bs_version);
if (dec->quant_type == 0)
{
dequant_h263_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices);
}
else
{
dequant_mpeg_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices);
}
idct_int32((short * const)&data[i * 64]);
}
if(dec->interlacing && pMB->field_dct)
{
next_block = stride;
stride *= 2;
}
transfer_16to8copy(pY_Cur, &data[0 * 64], stride);
transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);
transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);
transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride);
transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);
transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);
}
void decoder_mbinter(DECODER * dec,
const MACROBLOCK * pMB,
const uint32_t x_pos,
const uint32_t y_pos,
const uint32_t cbp,
Bitstream * bs,
const uint32_t rounding,
const int ref,
const int bvop)
{
uint32_t stride = dec->edged_width;
uint32_t stride2 = stride / 2;
uint32_t i;
uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
int uv_dx, uv_dy;
VECTOR mv[4]; /* local copy of mvs */
pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
for (i = 0; i < 4; i++)
mv[i] = pMB->mvs[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -