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

📄 mp4dmblk.c

📁 Linux下的基于intel的ipp库的MPEG4解码程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
//  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 + SAMPLE_VIDEO_BLOCK_SIZE;
            blkcoef_bufrow = vop_infor->coef_buf_row.y_ptr
                + SAMPLE_VIDEO_BLOCK_SIZE;
            blkcoef_bufcol = vop_infor->coef_buf_col.y_ptr;
            break;

        case Y_BLOCK3:
            dst_blk = vop_infor->cur_mb.y_ptr + SAMPLE_VIDEO_BLOCK_SIZE
                * dec_state->frame_step_set.y_step;
            blkcoef_bufrow = vop_infor->coef_buf_row.y_ptr;
            blkcoef_bufcol = vop_infor->coef_buf_col.y_ptr
                + SAMPLE_VIDEO_BLOCK_SIZE;
            break;

        case Y_BLOCK4:
            dst_blk = vop_infor->cur_mb.y_ptr + SAMPLE_VIDEO_BLOCK_SIZE
                * dec_state->frame_step_set.y_step + SAMPLE_VIDEO_BLOCK_SIZE;
            blkcoef_bufrow = vop_infor->coef_buf_row.y_ptr
                + SAMPLE_VIDEO_BLOCK_SIZE;
            blkcoef_bufcol = vop_infor->coef_buf_col.y_ptr
                + SAMPLE_VIDEO_BLOCK_SIZE;
        }

        if (vop_infor->cbpy & (1 << (3 - blk_indx))) {
            ret_code = decode_block_intradcac_mpeg4(
                stream_buf,
                dst_blk,
                dec_state->frame_step_set.y_step,
                blkcoef_bufrow,
                blkcoef_bufcol,
                vop_infor->cur_qp,
                vop_infor->qp_buf,
                dec_state->qmatrix_intra,
                blk_indx,
                vop_infor->intra_dc_vlc,
                vop_infor->ac_pred_flag);

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

        } else {
            ret_code = decode_block_intradc_mpeg4(
                stream_buf,
                dst_blk,
                dec_state->frame_step_set.y_step,
                blkcoef_bufrow,
                blkcoef_bufcol,
                vop_infor->cur_qp,
                vop_infor->qp_buf,
                dec_state->qmatrix_intra,
                blk_indx,
                vop_infor->intra_dc_vlc,
                vop_infor->ac_pred_flag);

            if (SAMPLE_STATUS_NOERR != ret_code) {
                return ret_code;
            }
        }   
    }
    
    /* chrominance blocks */
    for (blk_indx = U_BLOCK; blk_indx <= V_BLOCK; blk_indx++) {

        switch (blk_indx) {

        case U_BLOCK:
            if (vop_infor->cbpc & 2) {
                ret_code = decode_block_intradcac_mpeg4(
                    stream_buf, 
                    vop_infor->cur_mb.cb_ptr,
                    dec_state->frame_step_set.cb_step,
                    vop_infor->coef_buf_row.cb_ptr,
                    vop_infor->coef_buf_col.cb_ptr,
                    vop_infor->cur_qp,
                    vop_infor->qp_buf,
                    dec_state->qmatrix_intra,
                    blk_indx,
                    vop_infor->intra_dc_vlc,
                    vop_infor->ac_pred_flag);
                if (SAMPLE_STATUS_NOERR != ret_code) {
                    return ret_code;
                }
            } else {
                ret_code = decode_block_intradc_mpeg4(
                    stream_buf, 
                    vop_infor->cur_mb.cb_ptr,
                    dec_state->frame_step_set.cb_step,
                    vop_infor->coef_buf_row.cb_ptr,
                    vop_infor->coef_buf_col.cb_ptr,
                    vop_infor->cur_qp,
                    vop_infor->qp_buf,
                    dec_state->qmatrix_intra,
                    blk_indx,
                    vop_infor->intra_dc_vlc,
                    vop_infor->ac_pred_flag);
                if (SAMPLE_STATUS_NOERR != ret_code) {
                    return ret_code;
                }
            }
            break;

        case V_BLOCK:
            if (vop_infor->cbpc & 1) {
                ret_code = decode_block_intradcac_mpeg4(
                    stream_buf, 
                    vop_infor->cur_mb.cr_ptr,
                    dec_state->frame_step_set.cr_step,
                    vop_infor->coef_buf_row.cr_ptr,
                    vop_infor->coef_buf_col.cr_ptr,
                    vop_infor->cur_qp,
                    vop_infor->qp_buf,
                    dec_state->qmatrix_intra,
                    blk_indx,
                    vop_infor->intra_dc_vlc,
                    vop_infor->ac_pred_flag);
                if (SAMPLE_STATUS_NOERR != ret_code) {
                    return ret_code;
                }
            } else {
                ret_code = decode_block_intradc_mpeg4(
                    stream_buf, 
                    vop_infor->cur_mb.cr_ptr,
                    dec_state->frame_step_set.cr_step,
                    vop_infor->coef_buf_row.cr_ptr,
                    vop_infor->coef_buf_col.cr_ptr,
                    vop_infor->cur_qp,
                    vop_infor->qp_buf,
                    dec_state->qmatrix_intra,
                    blk_indx,
                    vop_infor->intra_dc_vlc,
                    vop_infor->ac_pred_flag);
                if (SAMPLE_STATUS_NOERR != ret_code) {
                    return ret_code;
                }
            }
            break;
        }
    }

    return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name:        decode_mb_pvop_mpeg4
// Desicription:
//      Decode the texture data of a macroblock in current PVOP
//
//  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
//      mbx_indx    - MacroBlock index in the row    (x-coordinate)
//      mby_indx    - MacroBlock index in the column (y-coordinate)
//
//  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_mb_pvop_mpeg4
(sample_bitstream  *stream_buf, const mp4_dec_state *dec_state,
 mp4_dec_vop_infor *vop_infor,  int mbx_indx, int mby_indx)
{
    int           i;    
    sample_status ret_code;

    /* parse the Macroblock header */
    ret_code = parse_mb_mpeg4(stream_buf, vop_infor, PVOP);
    if (SAMPLE_STATUS_NOERR != ret_code) {
        return ret_code;
    }

    /* running Qp is the current macroblock quantisation parameter value
    // for the first coded macroblock in a VOP or a video packet */
    if (0 == vop_infor->mb_indx) {
        vop_infor->qp_buf[0] = vop_infor->cur_qp;
    }

    /* determine which vlc coding for intra dc coefficient */
    if (vop_infor->qp_buf[0] >= dc_switch_thresh_tbl[dec_state->intra_dc_thr]){
        vop_infor->intra_dc_vlc = 0;
    } else {
        vop_infor->intra_dc_vlc = 1;
    }

    /* decoding the current MB texture */
    if ((IPP_VIDEO_INTRA == vop_infor->mb_type) ||
        (IPP_VIDEO_INTRA_Q == vop_infor->mb_type)) {
        
        /* decode intra macroblock */
        ret_code = decode_intra_mb_mpeg4(stream_buf, dec_state, vop_infor);
        if (SAMPLE_STATUS_NOERR != ret_code) {
            return ret_code;
        }
        
        /* 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;
        }
    } else {

        /* decode inter macroblock */
        ret_code = decode_inter_mb_mpeg4(stream_buf, dec_state, vop_infor,
            mbx_indx, mby_indx);
        if (SAMPLE_STATUS_NOERR != ret_code) {
            return ret_code;
        }

        /* update dc/ac prediction coefficient row and column buffer
        // take y plane for example:
        // coef_buf_row[0] <- dc coefficient of block 3
        // coef_buf_row[8] <- dc coefficient of block 2
        // coef_buf_col[8] <- dc coefficient of block 4
        // the above three dc coefficient values should be set as -1 to imply
        // it's an INTER MB, besides that there're still two dc coefficients
        // which need to be updated
        // coef_buf_row[-8] <- coef_buf_col[8]
        // coef_buf_col[0]  <- coef_buf_row[8] */

        *(vop_infor->coef_buf_col.y_ptr) = *(vop_infor->coef_buf_row.y_ptr
            + SAMPLE_VIDEO_BLOCK_SIZE);
        *(vop_infor->coef_buf_row.y_ptr - SAMPLE_VIDEO_BLOCK_SIZE) =
            *(vop_infor->coef_buf_col.y_ptr + SAMPLE_VIDEO_BLOCK_SIZE);
        *(vop_infor->coef_buf_row.y_ptr) = -1;
        *(vop_infor->coef_buf_row.y_ptr + SAMPLE_VIDEO_BLOCK_SIZE) = -1;
        *(vop_infor->coef_buf_col.y_ptr + SAMPLE_VIDEO_BLOCK_SIZE) = -1;

        *(vop_infor->coef_buf_col.cb_ptr) = *(vop_infor->coef_buf_row.cb_ptr);
        *(vop_infor->coef_buf_row.cb_ptr) = -1;

        *(vop_infor->coef_buf_col.cr_ptr) = *(vop_infor->coef_buf_row.cr_ptr);
        *(vop_infor->coef_buf_row.cr_ptr) = -1;
    
    } /* if intra block */
    return SAMPLE_STATUS_NOERR;

}

/******************************************************************************
// Name:        decode_mb_ivop_mpeg4
// Desicription:
//      Decode the texture data of a macroblock in current IVOP
//
//  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
//
//      dec_state   - Pointer to the updated general state struct of MPEG-4
//                    decoder
//      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_mb_ivop_mpeg4
(sample_bitstream  *stream_buf, const mp4_dec_state *dec_state,
 mp4_dec_vop_infor *vop_infor)
{
    sample_status   ret_code;

    /* parse the Macroblock header */
    ret_code = parse_mb_mpeg4(stream_buf, vop_infor, IVOP);
    if (SAMPLE_STATUS_NOERR != ret_code) {
        return ret_code;
    }

    /* running Qp is the current macroblock quantisation parameter value
    // for the first coded macroblock in a VOP or a video packet */
    if (0 == vop_infor->mb_indx) {
        vop_infor->qp_buf[0] = vop_infor->cur_qp;
    }

    /* determine which vlc coding for intra dc coefficient */
    if (vop_infor->qp_buf[0] >= dc_switch_thresh_tbl[dec_state->intra_dc_thr]){
        vop_infor->intra_dc_vlc = 0;
    } else {
        vop_infor->intra_dc_vlc = 1;
    }
    /* decode intra MacroBlock */
    ret_code = decode_intra_mb_mpeg4(stream_buf, dec_state, vop_infor);
    if (SAMPLE_STATUS_NOERR != ret_code) {
        return ret_code;
    }

    return SAMPLE_STATUS_NOERR;
}

⌨️ 快捷键说明

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