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

📄 mp4dec.cpp

📁 一个使用 linux编写的mpeg4解码代码,包括mpeg4解码库和示例代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    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,
            (IppMacroblockType)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_ptrer))(
                    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_ptrer))(
                    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_ptrer))(
                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_ptrer))(
                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_ptrer))(
                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_ptrer))(
                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
//
//  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_intra_mb_mpeg4 
(sample_bitstream  *stream_buf, const mp4_dec_state *dec_state,
 mp4_dec_vop_infor *vop_infor)
{
    int     blk_indx;
    Ipp8u   *dst_blk = NULL;
    Ipp16s  *blkcoef_bufrow = NULL, *blkcoef_bufcol = NULL;
    sample_status ret_code;

    /* luminance blocks */
    for (blk_indx = Y_BLOCK1; blk_indx <= Y_BLOCK4; blk_indx++) {
        
        switch (blk_indx) {
        
        case Y_BLOCK1:
            dst_blk = vop_infor->cur_mb.y_ptr;
            blkcoef_bufrow = vop_infor->coef_buf_row.y_ptr;
            blkcoef_bufcol = vop_infor->coef_buf_col.y_ptr;
            break;
            
        case Y_BLOCK2:
            dst_blk = vop_infor->cur_mb.y_ptr + SAMP

⌨️ 快捷键说明

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