📄 mp4eblck.c
字号:
/* PQFx[0][u] = QFx[0][u] - QFc[0][u] * QPc // QPx */
/* defined in subclause 7.4.3.3 of ISO/IEC 14496-2: 2001(E) */
if (cur_qp == pred_qp) {
/* QPc == QPx */
for (i=1; i < SAMPLE_VIDEO_BLOCK_SIZE; i++) {
level = coef[i] - coef_bufrow[i];
if ((128 <= level) || (-128 >= level)) {
sum_err = MPEG4_PRED_DISABLE;
i = SAMPLE_VIDEO_BLOCK_SIZE;
} else {
sum_err += ABS_MP4(coef[i]) - ABS_MP4(level);
pred_buf[blk_indx * 8 + i] = (Ipp16s)level;
}
}
} else {
/* QPc != QPx */
for (i=1; i < SAMPLE_VIDEO_BLOCK_SIZE; i++) {
if (0 <= coef_bufrow[i]) {
level = coef[i] - (coef_bufrow[i] * pred_qp
+ (cur_qp >> 1)) / cur_qp;
} else {
level = coef[i] - (coef_bufrow[i] * pred_qp
- (cur_qp >> 1)) / cur_qp;
}
if ((128 <= level) || (-128 >= level)) {
sum_err = MPEG4_PRED_DISABLE;
i = SAMPLE_VIDEO_BLOCK_SIZE;
} else {
sum_err += ABS_MP4(coef[i]) - ABS_MP4(level);
pred_buf[blk_indx * 8 + i] = (Ipp16s)level;
}
}
}
}
} else if (MPEG4_PRED_DISABLE != sum_err) {
/* pred_dir == IPP_VIDEO_HORIZONTAL */
if (0 > coef_bufrow[-8]) {
pred_buf[blk_indx * 8] = 0;
} else {
pred_buf[blk_indx * 8] = 1;
/* PQFx[v][0] = QFx[v][0] - QFa[v][0] * QPa // QPx */
/* defined in subclause 7.4.3.3 of ISO/IEC 14496-2: 2001(E) */
if (cur_qp == pred_qp) {
/* QPa == QPx */
for (i=1, j=8; i < SAMPLE_VIDEO_BLOCK_SIZE; i++, j+=8) {
level = coef[j] - coef_bufcol[i];
if ((128 <= level) || (-128 >= level)) {
sum_err = MPEG4_PRED_DISABLE;
i = SAMPLE_VIDEO_BLOCK_SIZE;
} else {
sum_err += ABS_MP4(coef[j]) - ABS_MP4(level);
pred_buf[blk_indx * 8 + i] = (Ipp16s)level;
}
}
} else {
/* QPa != QPx */
for (i=1, j=8; i < SAMPLE_VIDEO_BLOCK_SIZE; i++, j+=8) {
if (0 <= coef_bufcol[i]) {
level = coef[j] - (coef_bufcol[i] * pred_qp
+ (cur_qp >> 1)) / cur_qp;
} else {
level = coef[j] - (coef_bufcol[i] * pred_qp
- (cur_qp >> 1)) / cur_qp;
}
if ((128 <= level) || (-128 >= level)) {
sum_err = MPEG4_PRED_DISABLE;
i = SAMPLE_VIDEO_BLOCK_SIZE;
} else {
sum_err += ABS_MP4(coef[j]) - ABS_MP4(level);
pred_buf[blk_indx * 8 + i] = (Ipp16s)level;
}
}
}
}
}
/* 3. DC coefficient buffer update */
dc_coef = (Ipp16s)(coef[0] * dc_scaler);
/* The saturation range after inverse quantisation is listed in
// subclause 7.4.4.4 of ISO/IEC 14496-2:2001(E) */
if (2047 < dc_coef) {
dc_coef = 2047;
}
switch (blk_indx) {
case Y_BLOCK2:
tmp_coef = coef_bufcol[8];
coef_bufcol[8] = coef_bufrow[-16];
coef_bufrow[-16] = tmp_coef;
coef_bufcol[0] = coef_bufrow[0];
coef_bufrow[0] = dc_coef;
break;
case Y_BLOCK4:
coef_bufcol[0] = dc_coef;
break;
default:
coef_bufcol[0] = coef_bufrow[0];
coef_bufrow[0] = dc_coef;
break;
}
/* 4. AC coefficient buffer update */
for (i=1, j=8; i < SAMPLE_VIDEO_BLOCK_SIZE; i++, j+= 8) {
coef_bufrow[i] = coef[i];
coef_bufcol[i] = coef[j];
}
/* 5. DC prediction */
if (IPP_VIDEO_HORIZONTAL == pred_dir) {
/* PQFx[0][0] = QFx[0][0] - Fa[0][0] // dc_scaler
// defined in subclause 7.4.3.2 of ISO/IEC 14496-2:2001(E) */
coef[0] = (Ipp16s)(coef[0] - (dc_left + (dc_scaler >> 1))
/ dc_scaler);
} else {
/* PQFx[0][0] = QFx[0][0] - Fc[0][0] // dc_scaler
// defined in subclause 7.4.3.2 of ISO/IEC 14496-2:2001(E) */
coef[0] = (Ipp16s)(coef[0] - (dc_top + (dc_scaler >> 1))
/ dc_scaler);
}
}
/* 6. Determine ac_pred_flag based on the comparison result with the sum
// of the predicted coefficients absolute values and the sum of original
// coefficients absolute values */
if ((MPEG4_PRED_DISABLE != sum_err) && (0 <= sum_err)) {
*ac_pred_flag = 1;
/* AC prediction coefficients update */
for (blk_indx = Y_BLOCK1; blk_indx <= V_BLOCK; blk_indx++) {
if (2 <= pred_buf[blk_indx * 8]) {
pred_dir_buf[blk_indx] = IPP_VIDEO_VERTICAL;
}
else {
pred_dir_buf[blk_indx] = IPP_VIDEO_HORIZONTAL;
}
if (3 == pred_buf[blk_indx * 8]) {
for (i = 1; i < SAMPLE_VIDEO_BLOCK_SIZE; i++) {
src_dst_coeff[blk_indx*64 + i] = pred_buf[blk_indx*8 + i];
}
}
else if (1 == pred_buf[blk_indx * 8]) {
for (i = 1; i < SAMPLE_VIDEO_BLOCK_SIZE; i++) {
src_dst_coeff[blk_indx*64 + i*8] = pred_buf[blk_indx*8 + i];
}
}
}
} else {
*ac_pred_flag = 0;
for (blk_indx = Y_BLOCK1; blk_indx <= V_BLOCK; blk_indx++) {
pred_dir_buf[blk_indx] = IPP_VIDEO_NONE;
}
}
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
//
// Name: encode_block_inter_mpeg4
//
// Description: Quantize the DCT coefficients of the inter block and store
// them into buffer. Meanwhile, the texture residuals are
// reconstructed.
//
// Input Arguments:
// src_block - Pointer to the pixels of current inter block.
// cur_qp - Quantization parameter of the macroblock which the
// current block belongs to.
// q_matrix - If the second inverse quantization method is used, it is
// NULL; If the first inverse quantization method is used,
// it points to the quantization weighting coefficients
// buffer (for inter MB), whose first 64 elements are the
// quantization weighting matrix in Q0, the second 64
// elements are their reciprocals in Q21.
//
// Output Arguments:
// dst_coeff - Pointer to the quantized DCT coefficients buffer.
// rec_block - Pointer to the reconstructed texture residuals.
//
// Returns:
// SAMPLE_STATUS_NOERR - If succeeds.
// SAMPLE_STATUS_ERR - If encoding fails.
//
*********************************************************************************/
sample_status encode_block_inter_mpeg4(Ipp16s *src_block,
Ipp16s *rec_block,
Ipp16s *dst_coeff,
Ipp8u cur_qp,
const int *q_matrix)
{
Ipp8u q_matrix_8u[SAMPLE_VIDEO_BLOCK_SQUARE_SIZE];
Ipp16s dct_coef_buf[SAMPLE_VIDEO_BLOCK_SQUARE_SIZE + 8];
Ipp16s* dct_coef = (Ipp16s*)SAMPLE_ALIGN8(dct_coef_buf);
int i;
sample_status ret_code;
/* 1. DCT transform */
/* src_block, dct_coef must be 8 bytes aligned */
ret_code = ippiDCT8x8Fwd_Video_16s_C1(src_block, dct_coef);
if (ippStsNoErr != ret_code) {
return SAMPLE_STATUS_ERR;
}
/* 2. Quantisation */
ret_code = ippiQuantInter_MPEG4_16s_I(dct_coef, cur_qp, q_matrix);
if (ippStsNoErr != ret_code) {
return SAMPLE_STATUS_ERR;
} else {
memcpy((void*)dst_coeff, (void*)dct_coef, sizeof(Ipp16s) * 64);
}
/* 3. Inverse Quantisation */
if (q_matrix) {
for (i = 0; i < SAMPLE_VIDEO_BLOCK_SQUARE_SIZE; i++) {
q_matrix_8u[i] = (Ipp8u)q_matrix[i];
}
ret_code = ippiQuantInvInter_MPEG4_16s_I(dct_coef, cur_qp, q_matrix_8u);
} else {
ret_code = ippiQuantInvInter_MPEG4_16s_I(dct_coef, cur_qp, NULL);
}
if (ippStsNoErr != ret_code) {
return SAMPLE_STATUS_ERR;
}
/* 4. IDCT */
/* dct_coef, rec_block must be 8 bytes aligned */
ret_code = ippiDCT8x8Inv_Video_16s_C1(dct_coef, rec_block);
if (ippStsNoErr != ret_code) {
return SAMPLE_STATUS_ERR;
}
return SAMPLE_STATUS_NOERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -