📄 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, 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, pred_type); if (ippStsNoErr != ret_code) { return ret_code; } refer_blk += SAMPLE_VIDEO_BLOCK_SQUARE_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -