⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4emblk.c

📁 Linux下的基于intel的ipp库的MPEG4编码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
//               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 + -