📄 mp4dblck.c
字号:
/******************************************************************************
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2003 Intel Corporation. All Rights Reserved.
//
// Description: Block decoding functions of MPEG-4 video decoder sample
// code for Intel(R) Integrated Performance Primitives.
// Functions List:
// decode_block_inter_mpeg4()
// decode_block_intradc_mpeg4()
// decode_block_intradcac_mpeg4()
******************************************************************************/
#include "sampmp4.h"
/******************************************************************************
// Name: decode_block_inter_mpeg4
// Description: Decodes the INTER block coefficients. Inverse
// quantization, inversely zigzag positioning and IDCT,
// with appropriate clipping on each step, are performed
// on the coefficients. The results (residuals) are placed
// in a contiguous array of 64 elements.
//
// Input Arguments:
// stream_buf Pointer to the source video bitstream in which the
// inter block starts
// quant_para Quantization parameter of current MB
// quant_matrix Pointer to the quantization weighting matrix for inter
// macroblock. If it is NULL, it indicates to use the
// second inverse quantization method; if it is not NULL,
// the first inverse quantization method is used.
//
// Output Arguments:
// stream_buf Pointer to the updated video bitstream after the block
// is decoded
// dst_rsd pointer to the decoded residual buffer (a contiguous
// array of 64 elements of Ipp16s data type).
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_ERR If decoding fails
//
// Notes:
//
******************************************************************************/
sample_status decode_block_inter_mpeg4
(sample_bitstream *stream_buf, Ipp16s *dst_rsd, int quant_para,
const Ipp8u *quant_matrix)
{
/* 1. VLC decoding of inter DC and AC components and inverse zigzag scan */
/* dst_rsd must be 4 byte aligned */
if (ippStsNoErr != ippiDecodeVLCZigzag_Inter_MPEG4_1u16s (
&stream_buf->bs_cur_byte, &stream_buf->bs_cur_bitoffset, dst_rsd)) {
return SAMPLE_STATUS_ERR;
}
/* 2. inverse quantisation */
if (ippStsNoErr != ippiQuantInvInter_MPEG4_16s_I (dst_rsd, quant_para,
quant_matrix)) {
return SAMPLE_STATUS_ERR;
}
/* 3. inverse DCT */
/* dst_rsd must be 8 byte aligned */
if (ippStsNoErr != ippiDCT8x8Inv_Video_16s_C1I(dst_rsd)) {
return SAMPLE_STATUS_ERR;
}
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
//
// Name: decode_block_intradc_mpeg4
//
// Description: Decodes the INTRA block which has only intra DC
// transform coefficients in the bitstream. Inverse
// quantization, inversely zigzag positioning and IDCT,
// with appropriate clipping on each step, are performed
// on the coefficients.The results are then placed in the
// output frame/plane on a pixel basis.
//
// Input Arguments:
// stream_buf Pointer to the source video bitstream in which the
// intra block starts
// step Width of the destination plane.
// coef_bufrow Pointer to the coefficient row buffer.
// coef_bufcol Pointer to the coefficient column buffer.
// quant_para Quantization parameter of the macroblock which the
// current block belongs to.
// quant_buf Pointer to the quantization parameter buffer.
// quant_matrix Pointer to the quantization weighting matrix for intra
// MB. If it is NULL, it indicates to use the second
// inverse quantization method; if it is not NULL, the
// first inverse quantization method is used.
// blk_indx Block index indicating the component type and position
// as defined in subclause 6.1.3.8, Figure 6-5 of ISO/IEC
// 14496-2.
// intra_dcvlc_flag
// A flag determined by intra_dc_vlc_thr and Qp. This
// allows a mechanism to switch between two VLC's for
// coding of Intra DC coefficients as per Table 6-21 of
// ISO/IEC 14496-2.
// ac_pred_flag A flag indicating if the AC coefficients of the first
// row or first column are differentially coded for intra
// coded MB.
//
// Output Arguments:
// stream_buf Pointer to the source video bitstream after the block
// is decoded
// dst_val Pointer to the block in the destination plane.
// coef_bufrow Pointer to the updated coefficient row buffer.
// coef_bufcol Pointer to the updated coefficient column buffer.
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_ERR If decoding fails
// Notes:
//
//
******************************************************************************/
sample_status decode_block_intradc_mpeg4
(sample_bitstream *stream_buf, Ipp8u *dst_val, int step, Ipp16s *coef_bufrow,
Ipp16s *coef_bufcol, Ipp8u quant_para, Ipp8u *quant_buf,
const Ipp8u *quant_matrix, int blk_indx, int intra_dcvlc_flag,
int ac_pred_flag)
{
int pred_dir; /* prediction direction */
int dc_left, dc_top, dc_left_top; /* DC value of the left, top and
// left-top block */
Ipp16s qp_pred; /* The QP value of the prediction
// reference macroblock */
Ipp32u code;
int dc_size, i, level;
Ipp16s coef_buf[72], tmp_coef;
Ipp16s *dst_coef = (Ipp16s*)SAMPLE_ALIGN8(coef_buf);
IppVideoComponent video_comp;
qp_pred = quant_para;
/* 1. DC prediction direction */
/* Below is the neighboring blocks used in DC/AC prediction direction
// shown in Figure 7-5 of ISO/IEC 14496-2
// --- --- ---
// | b | | c | | d |
// --- --- ---
// --- --- ---
// | a | | x | | y |
// --- --- ---
// --- --- ---
// | e | | w | | z |
// --- --- ---
// Befor decoding this macroblock(block x, y, z, w), the DC coefficients
// are stored as: (Fx[0][0] means the DC coefficient of x block)
// vop_infor->coef_buf_row[-8] = Fa[0][0];
// vop_infor->coef_buf_row[0] = Fc[0][0];
// vop_infor->coef_buf_row[8] = Fd[0][0];
// vop_infor->coef_buf_col[0] = Fb[0][0];
// vop_infor->coef_buf_col[8] = Fe[0][0];
//
// After the x block has been decoded, the DC coefficients are stored as:
// vop_infor->coef_buf_row[-8] = Fa[0][0];
// vop_infor->coef_buf_row[0] = Fx[0][0];
// vop_infor->coef_buf_row[8] = Fd[0][0];
// vop_infor->coef_buf_col[0] = Fc[0][0];
// vop_infor->coef_buf_col[8] = Fe[0][0];
//
// After the y block has been decoded, the DC coefficients are stored as:
// vop_infor->coef_buf_row[-8] = Fe[0][0];
// vop_infor->coef_buf_row[0] = Fx[0][0];
// vop_infor->coef_buf_row[8] = Fy[0][0];
// vop_infor->coef_buf_col[0] = Fd[0][0];
// vop_infor->coef_buf_col[8] = Fa[0][0];
//
// After the w block has been decoded, the DC coefficients are stored as:
// vop_infor->coef_buf_row[-8] = Fe[0][0];
// vop_infor->coef_buf_row[0] = Fw[0][0];
// vop_infor->coef_buf_row[8] = Fy[0][0];
// vop_infor->coef_buf_col[0] = Fd[0][0];
// vop_infor->coef_buf_col[8] = Fx[0][0];
//
// After the z block has been decoded, the DC coefficients are stored as:
// vop_infor->coef_buf_row[-8] = Fe[0][0];
// vop_infor->coef_buf_row[0] = Fw[0][0];
// vop_infor->coef_buf_row[8] = Fy[0][0];
// vop_infor->coef_buf_col[0] = Fd[0][0];
// vop_infor->coef_buf_col[8] = Fz[0][0];
// vop_infor->coef_buf_row += 16;
// If this is the last macroblock in a row, buffer should be updated as:
// vop_infor->coef_buf_col[8] = Fz[0][0]; */
dc_top = (0 > coef_bufrow[0]) ? 1024 : coef_bufrow[0];
dc_left = (0 > coef_bufrow[-8]) ? 1024 : coef_bufrow[-8];
dc_left_top = (0 > coef_bufcol[0]) ? 1024 : coef_bufcol[0];
if (ABS_MP4(dc_left - dc_left_top) < ABS_MP4(dc_top - dc_left_top)) {
pred_dir = IPP_VIDEO_VERTICAL;
if((0 <= coef_bufrow[0]) && (Y_BLOCK3 != blk_indx)
&& (Y_BLOCK4 != blk_indx)) {
/* the reference block is from the top macro block */
qp_pred = quant_buf[1];
}
} else {
pred_dir = IPP_VIDEO_HORIZONTAL;
if((0 <= coef_bufrow[-8]) && (Y_BLOCK2 != blk_indx)
&& (Y_BLOCK4 != blk_indx)) {
/* the reference block is from the left macro block */
qp_pred = quant_buf[0];
}
}
video_comp = (Y_BLOCK4 >= blk_indx) ? IPP_VIDEO_LUMINANCE
: IPP_VIDEO_CHROMINANCE;
/* 2. intraDC VLC decoding */
if(intra_dcvlc_flag) {
if (IPP_VIDEO_LUMINANCE == video_comp) {
/* dct_dc_size_luminance */
/* prefetch 3 bits */
code = get_bits_mpeg4(stream_buf, 3);
rewind_buffer_mpeg4(stream_buf, 3 - dc_size_lum_tbl[code].numbit);
dc_size = dc_size_lum_tbl[code].value;
while ((0 == code) && (12 >= dc_size)) {
code = get_bits_mpeg4(stream_buf, 1);
if (0 == code) {
dc_size ++;
}
}
} else {
/* dct_dc_size_chrominance */
/* prefetch 2 bits */
code = get_bits_mpeg4(stream_buf, 2);
rewind_buffer_mpeg4(stream_buf, 2 - dc_size_chr_tbl[code].numbit);
dc_size = dc_size_chr_tbl[code].value;
while ((0 == code) && (12 >= dc_size)) {
code = get_bits_mpeg4(stream_buf, 1);
if (0 == code) {
dc_size++;
}
}
} /* end of decoding the length of DC coefficient */
if (12 < dc_size) {
return SAMPLE_STATUS_ERR;
}
/* dc_size bit dct_dc_differential */
code = get_bits_mpeg4(stream_buf, dc_size);
if (!(code >> (dc_size - 1))) {
level = (1 << dc_size) - code - 1;
level = - level;
} else {
level = (int)code;
}
if (8 < dc_size) {
/* assert one marker bit */
ASSERT_MARKER_BIT(stream_buf);
}
/* end of intraDC VLC decoding */
} else {
/* use_intra_dc_vlc == 0 */
level = 0;
}
dst_coef[0] = (Ipp16s)level;
/* reset all AC differential coeffs to zero */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -