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

📄 mp4dec.cpp

📁 一个使用 linux编写的mpeg4解码代码,包括mpeg4解码库和示例代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    /* dst_coef, coef_bufrow, coef_bufcol must be 4 byte aligned */
    if (ippStsNoErr != ippiPredictReconCoefIntra_MPEG4_16s (dst_coef,
        coef_bufrow, coef_bufcol, quant_para, qp_pred, pred_dir, ac_pred_flag,
        video_comp)) {
        return SAMPLE_STATUS_ERR;
    }

    /* 4. inverse quantisation */
    if (ippStsNoErr != ippiQuantInvIntra_MPEG4_16s_I(dst_coef, quant_para,
        quant_matrix, video_comp)) {
        return SAMPLE_STATUS_ERR;
    }

    /* 5. inverse DCT */
    /* dst_coef and dst_val must be 8 byte aligned */
    if (ippStsNoErr != ippiDCT8x8Inv_Video_16s8u_C1R(dst_coef, dst_val, step)) {
        return SAMPLE_STATUS_ERR;
    }

    /* 6. DC buffer update */
    switch (blk_indx){
    case Y_BLOCK2:
        tmp_coef         = coef_bufcol[8];
        coef_bufcol[8]   = coef_bufrow[-16];
        coef_bufrow[-16] = tmp_coef;
        
        coef_bufcol[0]   = coef_bufrow[0];
        coef_bufrow[0]   = dst_coef[0];

        break;
    case Y_BLOCK4:
        coef_bufcol[0]   = dst_coef[0];
        break;
    default:
        coef_bufcol[0]   = coef_bufrow[0];
        coef_bufrow[0]   = dst_coef[0];
        break;
    }
    
    return SAMPLE_STATUS_NOERR;
}



/******************************************************************************
//
// Name:                decode_block_intradcac_mpeg4
//
// Description:         Decodes the INTRA block coefficients with both intra DC
//                      and AC transform coefficients in the bitstream. Inverse
//                      quantization, inversely zigzag positioning and IDCT,
//                      with appropriate clipping on each step, are performed
//                      on the coefficients.The results are then placed in the
//                      output frame/plane on a pixel basis.
//
// Input Arguments: 
//      stream_buf      Pointer to the source video bitstream in which the
//                      intra block starts  
//      step            Width of the destination plane.
//      coef_bufrow     Pointer to the coefficient row buffer.
//      coef_bufcol     Pointer to the coefficient column buffer.
//      quant_para      Quantization parameter of the macroblock which the 
//                      current block belongs to.
//      quant_buf       Pointer to the quantization parameter buffer.
//      quant_matrix    Pointer to the quantization weighting matrix for intra 
//                      MB. If it is NULL, it indicates to use the second
//                      inverse quantization method; if it is not NULL, the 
//                      first inverse quantization method is used.
//      blk_indx        Block index indicating the component type and position
//                      as defined in subclause 6.1.3.8, Figure 6-5 of ISO/IEC
//                      14496-2. 
//      intra_dcvlc_flag
//                      A flag determined by intra_dc_vlc_thr and Qp. This
//                      allows a mechanism to switch between two VLC's for
//                      coding of Intra DC coefficients as per Table 6-21 of
//                      ISO/IEC 14496-2.
//      ac_pred_flag    A flag indicating if the AC coefficients of the first 
//                      row or first column are differentially coded for intra
//                      coded MB.
//
// Output Arguments:    
//      stream_buf      Pointer to the source video bitstream after the block
//                      is decoded
//      dst_val         Pointer to the block in the destination plane.
//      coef_bufrow     Pointer to the updated coefficient row buffer.
//      coef_bufcol     Pointer to the updated coefficient column buffer.
//
// Returns:
//     SAMPLE_STATUS_NOERR      If succeeds
//     SAMPLE_STATUS_ERR        If decoding fails
//
// Notes:           
//  1) No boundary check for the bitstream buffer.
//  
******************************************************************************/
sample_status 
decode_block_intradcac_mpeg4
(sample_bitstream *stream_buf, Ipp8u *dst_val, int step, Ipp16s *coef_bufrow,
 Ipp16s *coef_bufcol, Ipp8u quant_para, Ipp8u *quant_buf,
 const Ipp8u *quant_matrix, int blk_indx, int intra_dcvlc_flag,
 int ac_pred_flag)
{
    int     pred_dir;                     /* prediction direction */
    int     dc_left, dc_top, dc_left_top; /* DC value of the left, top and
                                          // left-top block */
    Ipp16s  qp_pred;                      /* The QP value of the prediction
                                          // reference macroblock */
    Ipp16s      coef_buf[72], tmp_coef;
    Ipp16s*     dst_coef = (Ipp16s*)SAMPLE_ALIGN8(coef_buf);
    IppStatus   ret_code;
    IppVideoComponent video_comp;
    

    qp_pred = quant_para;   
    
    /* 1. DC/AC prediction direction */

    /* Below is the neighboring blocks used in DC/AC prediction direction
    // shown in Figure 7-5 of ISO/IEC 14496-2
    //  ---   ---   --- 
    // | b | | c | | d |
    //  ---   ---   ---  
    //  ---   ---   --- 
    // | a | | x | | y |
    //  ---   ---   --- 
    //  ---   ---   --- 
    // | e | | w | | z |
    //  ---   ---   --- 
    // Befor decoding this macroblock(block x, y, z, w), the DC coefficients
    // are stored as: (Fx[0][0] means the DC coefficient of x block)
    // vop_infor->coef_buf_row[-8] = Fa[0][0];
    // vop_infor->coef_buf_row[0]  = Fc[0][0];
    // vop_infor->coef_buf_row[8]  = Fd[0][0];
    // vop_infor->coef_buf_col[0]  = Fb[0][0];
    // vop_infor->coef_buf_col[8]  = Fe[0][0];
    //
    // After the x block has been decoded, the DC coefficients are stored as:
    // vop_infor->coef_buf_row[-8] = Fa[0][0];
    // vop_infor->coef_buf_row[0]  = Fx[0][0];
    // vop_infor->coef_buf_row[8]  = Fd[0][0];
    // vop_infor->coef_buf_col[0]  = Fc[0][0];
    // vop_infor->coef_buf_col[8]  = Fe[0][0];
    //
    // After the y block has been decoded, the DC coefficients are stored as:
    // vop_infor->coef_buf_row[-8] = Fe[0][0];
    // vop_infor->coef_buf_row[0]  = Fx[0][0];
    // vop_infor->coef_buf_row[8]  = Fy[0][0];
    // vop_infor->coef_buf_col[0]  = Fd[0][0];
    // vop_infor->coef_buf_col[8]  = Fa[0][0];
    //
    // After the w block has been decoded, the DC coefficients are stored as:
    // vop_infor->coef_buf_row[-8] = Fe[0][0];
    // vop_infor->coef_buf_row[0]  = Fw[0][0];
    // vop_infor->coef_buf_row[8]  = Fy[0][0];
    // vop_infor->coef_buf_col[0]  = Fd[0][0];
    // vop_infor->coef_buf_col[8]  = Fx[0][0];
    //
    // After the z block has been decoded, the DC coefficients are stored as:
    // vop_infor->coef_buf_row[-8] = Fe[0][0];
    // vop_infor->coef_buf_row[0]  = Fw[0][0];
    // vop_infor->coef_buf_row[8]  = Fy[0][0];
    // vop_infor->coef_buf_col[0]  = Fd[0][0];
    // vop_infor->coef_buf_col[8]  = Fz[0][0];
    // vop_infor->coef_buf_row  += 16;

    // If this is the last macroblock in a row, buffer should be updated as:
    // vop_infor->coef_buf_col[8] = Fz[0][0]; */

    dc_top      = (0 > coef_bufrow[0])  ? 1024 : coef_bufrow[0];
    dc_left     = (0 > coef_bufrow[-8]) ? 1024 : coef_bufrow[-8];
    dc_left_top = (0 > coef_bufcol[0])  ? 1024 : coef_bufcol[0];

    if (ABS_MP4(dc_left - dc_left_top) < ABS_MP4(dc_top - dc_left_top)) {   
        
        pred_dir = IPP_VIDEO_VERTICAL;      
        if((0 <= coef_bufrow[0]) && (Y_BLOCK3 != blk_indx) && (Y_BLOCK4
            != blk_indx)) {
            /* the reference block is from the top macro block */
            qp_pred = quant_buf[1];             
        }
    } else {
        
        pred_dir = IPP_VIDEO_HORIZONTAL;        
        if((0 <= coef_bufrow[-8]) && (Y_BLOCK2 != blk_indx) && (Y_BLOCK4
            != blk_indx)) {
            /* the reference block is from the left macro block */
            qp_pred = quant_buf[0];
        }
    }

    /* 2. VLC decoding of intra DC and AC and inverse scan */   
    video_comp = (Y_BLOCK4 >= blk_indx) ? IPP_VIDEO_LUMINANCE
        : IPP_VIDEO_CHROMINANCE;

    if (intra_dcvlc_flag) {
        if (ac_pred_flag) {
            /* dst_coef must be 4 byte aligned */
            ret_code = ippiDecodeVLCZigzag_IntraDCVLC_MPEG4_1u16s(
                &stream_buf->bs_cur_byte,
                &stream_buf->bs_cur_bitoffset,
                dst_coef,
                pred_dir,
                video_comp);
        } else {
            /* dst_coef must be 4 byte aligned */
            ret_code = ippiDecodeVLCZigzag_IntraDCVLC_MPEG4_1u16s(
                &stream_buf->bs_cur_byte,
                &stream_buf->bs_cur_bitoffset,
                dst_coef,
                IPP_VIDEO_NONE,
                video_comp);
        }
    } else {
        if (ac_pred_flag) {
            /* dst_coef must be 4 byte aligned */
            ret_code = ippiDecodeVLCZigzag_IntraACVLC_MPEG4_1u16s(
                &stream_buf->bs_cur_byte,
                &stream_buf->bs_cur_bitoffset,
                dst_coef,
                pred_dir);
        } else {
            /* dst_coef must be 4 byte aligned */
            ret_code = ippiDecodeVLCZigzag_IntraACVLC_MPEG4_1u16s(
                &stream_buf->bs_cur_byte,
                &stream_buf->bs_cur_bitoffset,
                dst_coef,
                IPP_VIDEO_NONE);
        }
    }
    if (ippStsNoErr != ret_code) {
        return SAMPLE_STATUS_ERR;
    }

    /* 3. inverse DC and AC prediction, AC buffer update */
    /* dst_coef, coef_bufrow, coef_bufcol must be 4 byte aligned */
    if (ippStsNoErr != ippiPredictReconCoefIntra_MPEG4_16s(dst_coef,
        coef_bufrow, coef_bufcol, quant_para, qp_pred, pred_dir, ac_pred_flag,
        video_comp)) {
        return SAMPLE_STATUS_ERR;
    }

    /* 4. inverse quantisation */
    if (ippStsNoErr != ippiQuantInvIntra_MPEG4_16s_I(dst_coef, quant_para,
        quant_matrix, video_comp)) {
        return SAMPLE_STATUS_ERR;
    }

    /* 5. inverse DCT */
    /* dst_coef, dst_val must be 8 byte aligned */
    if (ippStsNoErr != ippiDCT8x8Inv_Video_16s8u_C1R(dst_coef, dst_val, step)) {
        return SAMPLE_STATUS_ERR;
    }

    /* 6. DC buffer update */
    switch (blk_indx){
    case Y_BLOCK2:
        tmp_coef         = coef_bufcol[8];
        coef_bufcol[8]   = coef_bufrow[-16];
        coef_bufrow[-16] = tmp_coef;
        
        coef_bufcol[0]   = coef_bufrow[0];
        coef_bufrow[0]   = dst_coef[0];

        break;
    case Y_BLOCK4:
        coef_bufcol[0]   = dst_coef[0];
        break;
    default:
        coef_bufcol[0]   = coef_bufrow[0];
        coef_bufrow[0]   = dst_coef[0];
        break;
    }

    return SAMPLE_STATUS_NOERR;
}

/******************************************************************************
// Name:            rewind_buffer_mpeg4
// Description:     Skip N bits back in video buffer
// Input Arguments: 
//      stream_buf          - Pointer to the source compressed video bitstream
//      n_bits              - Number of bits to skip back
//
//  Output Arguments:
//      stream_buf          - Pointer to the updated source video stream after
//                            the N bits is skipped back
//
//  Returns:    
//      None
******************************************************************************/
void rewind_buffer_mpeg4 (sample_bitstream *stream_buf, int n_bits)
{
    int n_bytes;
    
    n_bytes  = (n_bits  >> 3);
    n_bits  -= (n_bytes << 3);

    if (stream_buf->bs_cur_bitoffset < n_bits) {
        stream_buf->bs_cur_byte -= 1;
        stream_buf->bs_cur_bitoffset += 8;
    }
    stream_buf->bs_cur_byte    -= n_bytes;
    stream_buf->bs_cur_bitoffset -= n_bits;
}
/******************************************************************************
// Name:                get_bits_mpeg4
// Description:         Read N bits from video buffer
// Input Arguments: 
//      stream_buf      - Pointer to the source compressed video bitstream
//      n_bits          - Number of bits to read, i.e., N. (N <= 32)
//
//  Output Arguments:
//      stream_buf      - Pointer to the updated source video stream after
//                        the N bits is taken out
//
//  Returns:    
//      the value of the N bits in big endian
******************************************************************************/
Ipp32u  get_bits_mpeg4 (sample_bitstream *stream_buf, int n_bits)
{
    Ipp32u  code = 0;
    int     n_head_bits, n_tail_bits, n_bytes;

    n_head_bits = stream_buf->bs_cur_bitoffset;
    
    n_bytes   = (n_head_bits + n_bits + 7) / 8;

    n_tail_bits = n_bytes * 8 - n_head_bits - n_bits;
    
    while (n_bytes--) {
        code = (code << 8) | (*(stream_buf->bs_cur_byte)++);
    }

    code = (code >> n_tail_bits) & bits_mask_tbl[n_bits];   

    if (n_tail_bits) {
        stream_buf->bs_cur_byte--;
        stream_buf->bs_cur_bitoffset = 8 - n_tail_bits;
    }

⌨️ 快捷键说明

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