📄 mp4emblk.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: Macroblock encoding functions of MPEG-4 video encoder
// sample code for Intel(R) Integrated Performance Primitives.
// Functions List:
// encode_intra_mb_mpeg4()
// encode_inter_mb_mpeg4()
******************************************************************************/
#include "sampmp4.h"
/******************************************************************************
// Name: encode_intra_mb_mpeg4
// Desicription:
// Encode the texture data of an INTRA macroblock
//
// Input Arguments:
// enc_state - Pointer to the general state struct of MPEG-4 encoder
// vop_infor - Pointer to the vop information struct of MPEG-4 encoder
//
// Output Arguments:
// stream_buf - Pointer to the updated output video bitstream after the
// INTRA macroblock header and its encoded texture data is
// filled in the bitstream
// vop_infor - Pointer to the updated vop information struct of MPEG-4
// encoder
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_ERR If encoding fails
// Note:
//
******************************************************************************/
sample_status encode_intra_mb_mpeg4 (sample_bitstream *stream_buf,
mp4_enc_state *enc_state,
mp4_enc_vop_infor *vop_infor)
{
int blk_indx = 0, start_coef = 0, i = 0;
Ipp16s mb_coef_buf[SAMPLE_VIDEO_BLOCK_SQUARE_SIZE * 6 + 8];
Ipp16s* mb_coef = (Ipp16s*)SAMPLE_ALIGN8(mb_coef_buf);
sample_status ret_code;
/* 1. Encode the block coefficients */
/* Determine intra_dc_vlc based on Table 6-21 of ISO/IEC 14496-2:2001(E) */
if (vop_infor->qp_buf[0] >= dc_switch_thresh_tbl[enc_state->intra_dc_thr]){
vop_infor->intra_dc_vlc = FALSE;
start_coef = 0;
} else {
vop_infor->intra_dc_vlc = TRUE;
start_coef = 1;
}
for (blk_indx = Y_BLOCK1; blk_indx <= Y_BLOCK4; blk_indx++) {
/* Encode block coefficients: DCT, quantisation */
ret_code = encode_block_intra_mpeg4(
vop_infor->cur_mb.y_ptr + (blk_indx & 1) * 8
+ (blk_indx >> 1) * 8 * enc_state->frame_step_set.y_step,
vop_infor->rec_mb.y_ptr + (blk_indx & 1) * 8
+ (blk_indx >> 1) * 8 * enc_state->frame_step_set.y_step,
mb_coef + blk_indx * SAMPLE_VIDEO_BLOCK_SQUARE_SIZE,
blk_indx,
vop_infor->cur_qp,
enc_state->frame_step_set.y_step,
enc_state->qmatrix_intra);
if (SAMPLE_STATUS_NOERR != ret_code) {
return ret_code;
}
}
for (blk_indx = U_BLOCK; blk_indx <= V_BLOCK; blk_indx++) {
if (U_BLOCK == blk_indx) {
ret_code = encode_block_intra_mpeg4(
vop_infor->cur_mb.cb_ptr,
vop_infor->rec_mb.cb_ptr,
mb_coef + blk_indx * SAMPLE_VIDEO_BLOCK_SQUARE_SIZE,
blk_indx,
vop_infor->cur_qp,
enc_state->frame_step_set.cb_step,
enc_state->qmatrix_intra);
} else {
ret_code = encode_block_intra_mpeg4(
vop_infor->cur_mb.cr_ptr,
vop_infor->rec_mb.cr_ptr,
mb_coef + blk_indx * SAMPLE_VIDEO_BLOCK_SQUARE_SIZE,
blk_indx,
vop_infor->cur_qp,
enc_state->frame_step_set.cr_step,
enc_state->qmatrix_intra);
}
if (SAMPLE_STATUS_NOERR != ret_code) {
return ret_code;
}
}
/* 2. AC/DC prediction */
ret_code = acdc_prediction_intra_mb_mpeg4(
mb_coef,
vop_infor->coef_buf_row.y_ptr,
vop_infor->coef_buf_col.y_ptr,
vop_infor->coef_buf_row.cb_ptr,
vop_infor->coef_buf_col.cb_ptr,
vop_infor->coef_buf_row.cr_ptr,
vop_infor->coef_buf_col.cr_ptr,
vop_infor->cur_qp,
vop_infor->qp_buf,
&vop_infor->ac_pred_flag,
vop_infor->pred_dir_buf);
if (SAMPLE_STATUS_NOERR != ret_code) {
return ret_code;
}
/* Determine the cbpc and cbpy */
vop_infor->mb_not_coded = 0;
for (blk_indx = Y_BLOCK1; blk_indx <= V_BLOCK; blk_indx++) {
vop_infor->pattern_buf[blk_indx] = FALSE;
for (i = start_coef; i < SAMPLE_VIDEO_BLOCK_SQUARE_SIZE; i++) {
if (mb_coef[i + blk_indx * SAMPLE_VIDEO_BLOCK_SQUARE_SIZE]) {
vop_infor->pattern_buf[blk_indx] = TRUE;
break;
}
}
}
vop_infor->cbpc = (vop_infor->pattern_buf[U_BLOCK] << 1)
| (vop_infor->pattern_buf[V_BLOCK]);
/* For RECTANGULAR shape, each macroblock must have four opaque blocks */
vop_infor->num_non_trans_blk = 4;
vop_infor->cbpy = 0;
for (blk_indx = Y_BLOCK1; blk_indx <= Y_BLOCK4; blk_indx++) {
vop_infor->cbpy |= vop_infor->pattern_buf[blk_indx]
<< (vop_infor->num_non_trans_blk - 1 - blk_indx);
}
/* 3. Dump out MB level information */
create_mb_mpeg4(stream_buf, enc_state, vop_infor);
/* 4. Zigzag scan and VLC encoding */
for (blk_indx = Y_BLOCK1; blk_indx <= V_BLOCK; blk_indx ++) {
if (vop_infor->intra_dc_vlc) {
if ((U_BLOCK == blk_indx) || (V_BLOCK == blk_indx)) {
ret_code = ippiEncodeVLCZigzag_IntraDCVLC_MPEG4_16s1u(
&stream_buf->bs_cur_byte,
&stream_buf->bs_cur_bitoffset,
mb_coef + blk_indx * SAMPLE_VIDEO_BLOCK_SQUARE_SIZE,
vop_infor->pred_dir_buf[blk_indx],
vop_infor->pattern_buf[blk_indx],
IPP_VIDEO_CHROMINANCE);
} else {
ret_code = ippiEncodeVLCZigzag_IntraDCVLC_MPEG4_16s1u(
&stream_buf->bs_cur_byte,
&stream_buf->bs_cur_bitoffset,
mb_coef + blk_indx * SAMPLE_VIDEO_BLOCK_SQUARE_SIZE,
vop_infor->pred_dir_buf[blk_indx],
vop_infor->pattern_buf[blk_indx],
IPP_VIDEO_LUMINANCE);
}
} else {
ret_code = ippiEncodeVLCZigzag_IntraACVLC_MPEG4_16s1u(
&stream_buf->bs_cur_byte,
&stream_buf->bs_cur_bitoffset,
mb_coef + blk_indx * SAMPLE_VIDEO_BLOCK_SQUARE_SIZE,
vop_infor->pred_dir_buf[blk_indx],
vop_infor->pattern_buf[blk_indx]);
}
if (ippStsNoErr != ret_code) {
return SAMPLE_STATUS_NOERR;
}
}
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: encode_inter_mb_mpeg4
// Desicription:
// Encode the motion vectors and texture residuals of an INTER macroblock
//
// Input Arguments:
// enc_state - Pointer to the general state struct of MPEG-4 encoder
// vop_infor - Pointer to the vop information struct of MPEG-4 encoder
// mv_cur_mb - Pointer to the four motion vectors of current macroblock
// transp_cur_mb
// - Pointer to the four blocks transparent information of
// current macroblock
//
// Output Arguments:
// stream_buf - Pointer to the updated output video bitstream after the
// INTER macroblock header, its encoded motion vectors
// and texture residuals are filled in the bitstream
// vop_infor - Pointer to the updated vop information struct of MPEG-4
// encoder
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_ERR If encoding fails
// Note:
//
******************************************************************************/
sample_status encode_inter_mb_mpeg4 (sample_bitstream *stream_buf,
mp4_enc_state *enc_state,
mp4_enc_vop_infor *vop_infor,
IppMotionVector *mv_cur_mb,
Ipp8u *transp_cur_mb)
{
int blk_indx, i, j, k, sad[6];
int temp, pred_type, y_step, u_step, v_step, step;
Ipp16s *resid_blk, *coeff_blk, *rec_resid_blk;
Ipp8u *src_blk, *dst_blk, *refer_blk;
IppMotionVector *mv_left_mb, *mv_top_mb, *mv_top_right_mb, mv_chr, mv_blk;
sample_status ret_code;
y_step = enc_state->frame_step_set.y_step;
u_step = enc_state->frame_step_set.cb_step;
v_step = enc_state->frame_step_set.cr_step;
/* 1. look up motion vector for chorminance blocks */
ret_code = lookup_uvmv_mpeg4(mv_cur_mb, &mv_chr, vop_infor->mb_type);
if (SAMPLE_STATUS_NOERR != ret_code) {
return ret_code;
}
/* 2. motion compensation for luminance and chrominance blocks */
/* dst reference block after motion compensation */
refer_blk = enc_state->blk_ref_buf;
for (blk_indx = Y_BLOCK1; blk_indx <= V_BLOCK; blk_indx ++) {
switch (blk_indx) {
case U_BLOCK:
src_blk = vop_infor->fwd_ref_rec_mb.cb_ptr;
mv_blk = mv_chr;
step = u_step;
break;
case V_BLOCK:
src_blk = vop_infor->fwd_ref_rec_mb.cr_ptr;
mv_blk = mv_chr;
step = v_step;
break;
default:
src_blk = vop_infor->fwd_ref_rec_mb.y_ptr + (blk_indx & 1) * 8
+ (blk_indx >> 1) * y_step * 8;
mv_blk = mv_cur_mb[blk_indx];
step = y_step;
break;
}
/* get src reference block in the reconstructed reference plane */
temp = (mv_blk.dx >> 1) + (mv_blk.dy >> 1) * step;
src_blk += temp;
/* determine prediction type based on pixel or half-pixel resolution of
// motion vector in x and y dimension */
pred_type = ((mv_blk.dy & 1) << 1) | (mv_blk.dx & 1);
/* motion compensation and copy the result to dst reference block */
/* refer_blk must be 8 byte aligned */
ret_code = (*(vop_infor->copy_block_func_ptr)) (
src_blk,
step,
refer_blk,
8,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -