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

📄 mp4dmblk.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 decoding functions of MPEG-4 video decoder
//                  sample code for Intel(R) Integrated Performance Primitives.
//  Functions List:
//		decode_inter_mb_mpeg4()
//		decode_intra_mb_mpeg4()
//		decode_mb_pvop_mpeg4()
//      decode_mb_ivop_mpeg4()
******************************************************************************/

#include "sampmp4.h"

/******************************************************************************
// Name:        decode_inter_mb_mpeg4
// Desicription:
//      Decode the texture data of an INTER macroblock
//
//  Input Arguments:
//      stream_buf  - Pointer to the source video bitstream 
//      dec_state   - Pointer to the general state struct of MPEG-4 decoder
//      vop_infor   - Pointer to the vop information struct of MPEG-4 decoder
//
//  Output Arguments:
//      stream_buf  - Pointer to the updated video bitstream
//      vop_infor   - Pointer to the updated vop information struct of MPEG-4
//                    decoder
//
//  Returns:
//     SAMPLE_STATUS_NOERR      If succeeds
//     SAMPLE_STATUS_ERR        If decoding fails
//  Note:
//  
******************************************************************************/
sample_status decode_inter_mb_mpeg4
(sample_bitstream  *stream_buf, const mp4_dec_state *dec_state,
 mp4_dec_vop_infor *vop_infor,  int mbx_indx, int mby_indx)
{
    IppiRect         ref_rect_vop;
    int              i, blk_indx, mbx_pos, mby_pos, tmp_step, predict_type;
    IppMotionVector  mv_curmb_buf[8], mv_chr;
    IppMotionVector* mv_curmb = (IppMotionVector*)SAMPLE_ALIGN4(mv_curmb_buf);
    Ipp8u            transp_curmb_buf[8];
    Ipp8u*           transp_curmb = (Ipp8u*)SAMPLE_ALIGN4(transp_curmb_buf);
    sample_status    ret_code;

    /* residual block coefficients of inter MB */
    Ipp16s           inter_blk_coeff_buf[SAMPLE_VIDEO_BLOCK_SQUARE_SIZE + 8];
    Ipp16s*          inter_blk_coeff = (Ipp16s*)SAMPLE_ALIGN8(inter_blk_coeff_buf);
    
    /* for rectangular shape, 4 blocks in one MacroBlock are always opaque */
    for(i=0; i< 4; i++ ) {
        transp_curmb[i]   = IPP_VIDEO_OPAQUE;
    }

    /* coded mb */
    if (!vop_infor->mb_not_coded) {
        
        /* motion vector decoding */
        /* vop_infor->mv_buf, mv_curmb, vop_infor->tranp_buf, transp_curmb
        // must be 4 byte aligned */
        if (ippiDecodePadMV_PVOP_MPEG4(
            &stream_buf->bs_cur_byte,
            &stream_buf->bs_cur_bitoffset,
            vop_infor->mv_buf,
            vop_infor->mv_buf + 4, 
            vop_infor->mv_buf + 8,
            mv_curmb,
            vop_infor->tranp_buf,
            vop_infor->tranp_buf + 4,
            vop_infor->tranp_buf + 8,
            transp_curmb,
            vop_infor->fcode_fwd,
            vop_infor->mb_type) != ippStsNoErr) {
            return SAMPLE_STATUS_ERR;
        }

        /* update mv_buf to store unlimited motion vectors */
        vop_infor->mv_buf += 4;
        for(i=0;i<4;i++){
            vop_infor->mv_buf[i].dx = mv_curmb[i].dx;
            vop_infor->mv_buf[i].dy = mv_curmb[i].dy;
        }

        /* motion vector limitation */
        ref_rect_vop.x = - SAMPLE_VIDEO_MB_SIZE;
        ref_rect_vop.y = - SAMPLE_VIDEO_MB_SIZE;           
        ref_rect_vop.width  = dec_state->frame_dimension.width
            + SAMPLE_VIDEO_MB_SIZE * 2;
        ref_rect_vop.height = dec_state->frame_dimension.height
            + SAMPLE_VIDEO_MB_SIZE * 2;
            
        if (IPP_VIDEO_INTER4V == vop_infor->mb_type) {
            for(i=0; i<4; i++){
                mbx_pos = mbx_indx * SAMPLE_VIDEO_MB_SIZE + (i &  1)
                    * SAMPLE_VIDEO_BLOCK_SIZE;
                mby_pos = mby_indx * SAMPLE_VIDEO_MB_SIZE + (i >> 1)
                    * SAMPLE_VIDEO_BLOCK_SIZE;
                
                if (ippiLimitMVToRect_MPEG4(
                    &mv_curmb[i],
                    &mv_curmb[i],
                    &ref_rect_vop,
                    mbx_pos,
                    mby_pos,
                    SAMPLE_VIDEO_BLOCK_SIZE) != ippStsNoErr) {
                    return SAMPLE_STATUS_ERR;
                }
            }
        } else {
            mbx_pos = mbx_indx * SAMPLE_VIDEO_MB_SIZE;
            mby_pos = mby_indx * SAMPLE_VIDEO_MB_SIZE;

            if (ippiLimitMVToRect_MPEG4(
                mv_curmb,
                mv_curmb,
                &ref_rect_vop,
                mbx_pos,
                mby_pos,
                SAMPLE_VIDEO_MB_SIZE) != ippStsNoErr) {
                return SAMPLE_STATUS_ERR;
            }

            for(i=1;i<4;i++){
                mv_curmb[i].dx  = mv_curmb[0].dx;
                mv_curmb[i].dy  = mv_curmb[0].dy;
            }
        }

        /* Decoding the texture data of current Inter MB */
        /* luminace blocks */
        for (blk_indx = Y_BLOCK1; blk_indx <= Y_BLOCK4; blk_indx++) {
            
            /* calculate the current block position in MB */
            tmp_step = (blk_indx & 0x1) * SAMPLE_VIDEO_BLOCK_SIZE
                + (blk_indx >> 1) * dec_state->frame_step_set.y_step
                * SAMPLE_VIDEO_BLOCK_SIZE;
            
            vop_infor->cur_bk.y_ptr     = vop_infor->cur_mb.y_ptr
                + tmp_step;
            vop_infor->fwd_ref_bk.y_ptr = vop_infor->fwd_ref_mb.y_ptr
                + tmp_step;
            
            /* calculate the predict reference block position in MB */
            tmp_step = (mv_curmb[blk_indx].dx >> 1)
                + (mv_curmb[blk_indx].dy >> 1)
                * dec_state->frame_step_set.y_step;
            
            vop_infor->fwd_ref_bk.y_ptr += tmp_step;
                    
            /* determine interpolation type for half-pixel precision */
            predict_type = ((mv_curmb[blk_indx].dy & 0x1) << 1)
                | (mv_curmb[blk_indx].dx & 0x1);
            
            if (vop_infor->cbpy & (1 << (3 - blk_indx))) {
                /* inter block decoding */
                ret_code = decode_block_inter_mpeg4 (stream_buf,
                    inter_blk_coeff, vop_infor->cur_qp,
                    dec_state->qmatrix_inter);
                
                if(SAMPLE_STATUS_NOERR != ret_code) {
                    return  ret_code;              
                }
                
                /* motion compensation */
                /* vop_infor->cur_bk.y_ptr must be 8 byte aligned */
                if(ippStsNoErr != (*(vop_infor->recon_block_func_ptr))(
                    vop_infor->fwd_ref_bk.y_ptr,
                    dec_state->frame_step_set.y_step,
                    inter_blk_coeff,
                    vop_infor->cur_bk.y_ptr,
                    dec_state->frame_step_set.y_step,
                    predict_type)) {
                    return  SAMPLE_STATUS_ERR;
                }
            } else {
                /* no residual components in the block */
                /* block copy */
                /* vop_infor->cur_bk.y_ptr must be 8 byte aligned */
                if(ippStsNoErr != (*(vop_infor->copy_block_func_ptr))(
                    vop_infor->fwd_ref_bk.y_ptr,
                    dec_state->frame_step_set.y_step,
                    vop_infor->cur_bk.y_ptr,
                    dec_state->frame_step_set.y_step,
                    predict_type)) {
                    return  SAMPLE_STATUS_ERR;
                }
            }
        }

        /* chrominance blocks */
        /* look up motion vector for chorminance blocks */
        ret_code = lookup_uvmv_mpeg4 (vop_infor->mv_buf, &mv_chr,
            vop_infor->mb_type);
        
        if(SAMPLE_STATUS_NOERR != ret_code) {
            return  ret_code;
        }

        /* motion vector limitation */
        ref_rect_vop.x = - SAMPLE_VIDEO_BLOCK_SIZE;
        ref_rect_vop.y = - SAMPLE_VIDEO_BLOCK_SIZE;
        ref_rect_vop.width  = dec_state->frame_dimension.width  / 2
            + SAMPLE_VIDEO_MB_SIZE;
        ref_rect_vop.height = dec_state->frame_dimension.height / 2
            + SAMPLE_VIDEO_MB_SIZE;
        mbx_pos = mbx_indx * SAMPLE_VIDEO_BLOCK_SIZE;
        mby_pos = mby_indx * SAMPLE_VIDEO_BLOCK_SIZE;
        
        if (ippiLimitMVToRect_MPEG4(
            &mv_chr,
            &mv_chr,
            &ref_rect_vop,
            mbx_pos,
            mby_pos,
            SAMPLE_VIDEO_BLOCK_SIZE) != ippStsNoErr) {
            return SAMPLE_STATUS_ERR;
        }
        
        predict_type = ((mv_chr.dy & 0x1) << 1) | (mv_chr.dx & 0x1);
        
        /* U block */
        /* calculate the current block position */
        vop_infor->cur_bk.cb_ptr = vop_infor->cur_mb.cb_ptr;
        /* calculate the predict reference block position */
        tmp_step = (mv_chr.dx >> 1) + (mv_chr.dy >> 1)
            * dec_state->frame_step_set.cb_step;
        vop_infor->fwd_ref_bk.cb_ptr = vop_infor->fwd_ref_mb.cb_ptr + tmp_step;
        
        if (vop_infor->cbpc & 2) {
            /* inter block decoding */
            ret_code = decode_block_inter_mpeg4 (stream_buf,
                inter_blk_coeff, vop_infor->cur_qp, dec_state->qmatrix_inter);
            
            if(SAMPLE_STATUS_NOERR != ret_code) {
                return  ret_code;
            }
            /* motion compensation */
            /* vop_infor->cur_bk.cb_ptr must be 8 byte aligned */
            if(ippStsNoErr != (*(vop_infor->recon_block_func_ptr))(
                vop_infor->fwd_ref_bk.cb_ptr,
                dec_state->frame_step_set.cb_step,
                inter_blk_coeff,
                vop_infor->cur_bk.cb_ptr,
                dec_state->frame_step_set.cb_step,
                predict_type)) {
                return  SAMPLE_STATUS_ERR;              
            }
        } else {
            /* no residual components in the block */
            /* block copy */
            /* vop_infor->cur_bk.cb_ptr must be 8 byte aligned */
            if(ippStsNoErr != (*(vop_infor->copy_block_func_ptr))(
                vop_infor->fwd_ref_bk.cb_ptr,
                dec_state->frame_step_set.cb_step,
                vop_infor->cur_bk.cb_ptr,
                dec_state->frame_step_set.cb_step,
                predict_type)) {
                return  SAMPLE_STATUS_ERR;
            }
        }

        /* V block */
        /* calculate the current block position */
        vop_infor->cur_bk.cr_ptr = vop_infor->cur_mb.cr_ptr;
        /* calculate the predict reference block position */
        tmp_step = (mv_chr.dx >> 1) + (mv_chr.dy >> 1)
            * dec_state->frame_step_set.cr_step;
        vop_infor->fwd_ref_bk.cr_ptr = vop_infor->fwd_ref_mb.cr_ptr + tmp_step;
        
        if (vop_infor->cbpc & 1) {
            /* inter block decoding */
            ret_code = decode_block_inter_mpeg4 (stream_buf, inter_blk_coeff,
                vop_infor->cur_qp, dec_state->qmatrix_inter);
            
            if(SAMPLE_STATUS_NOERR != ret_code) {
                return  ret_code;
            }
            /* motion compensation */
            /* vop_infor->cur_bk.cr_ptr must be 8 byte aligned */
            if(ippStsNoErr != (*(vop_infor->recon_block_func_ptr))(
                vop_infor->fwd_ref_bk.cr_ptr,
                dec_state->frame_step_set.cr_step, 
                inter_blk_coeff,
                vop_infor->cur_bk.cr_ptr,
                dec_state->frame_step_set.cr_step,
                predict_type)) {
                return  SAMPLE_STATUS_ERR;
            }
        } else {
            /* no residual components in the block */
            /* block copy */
            /* vop_infor->cur_bk.cr_ptr must be 8 byte aligned */
            if(ippStsNoErr != (*(vop_infor->copy_block_func_ptr))(
                vop_infor->fwd_ref_bk.cr_ptr,
                dec_state->frame_step_set.cr_step,
                vop_infor->cur_bk.cr_ptr,
                dec_state->frame_step_set.cr_step,
                predict_type)) {
                return  SAMPLE_STATUS_ERR;                  
            }
        }    
    } else { /* if not coded */
        /* update mv_buf ptr */
        vop_infor->mv_buf += 4;
        for(i=0; i<4; i++) {
            vop_infor->mv_buf[i].dx  = 0;
            vop_infor->mv_buf[i].dy  = 0;
        }
        
        /* copy macroblock from fwd reference frame */
        ret_code = copy_mb_from_ref_plane(
            vop_infor->fwd_ref_mb.y_ptr,
            dec_state->frame_step_set.y_step,
            vop_infor->fwd_ref_mb.cb_ptr,
            dec_state->frame_step_set.cb_step,
            vop_infor->fwd_ref_mb.cr_ptr,
            dec_state->frame_step_set.cr_step,
            vop_infor->cur_mb.y_ptr,
            dec_state->frame_step_set.y_step,
            vop_infor->cur_mb.cb_ptr,
            dec_state->frame_step_set.cb_step,
            vop_infor->cur_mb.cr_ptr,
            dec_state->frame_step_set.cr_step);

        if(SAMPLE_STATUS_NOERR != ret_code) {
            return SAMPLE_STATUS_ERR;
        }
    }

    return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name:        decode_intra_mb_mpeg4
// Desicription:
//      Decode the texture data of an INTRA macroblock

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -