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

📄 mp4dblck.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:    Block decoding functions of MPEG-4 video decoder sample
//                  code for Intel(R) Integrated Performance Primitives.
//  Functions List:
//		decode_block_inter_mpeg4()
//		decode_block_intradc_mpeg4()
//		decode_block_intradcac_mpeg4()
******************************************************************************/

#include "sampmp4.h"

/******************************************************************************
//  Name:               decode_block_inter_mpeg4
//  Description:        Decodes the INTER block coefficients. Inverse 
//                      quantization, inversely zigzag positioning and IDCT,
//                      with appropriate clipping on each step, are performed
//                      on the coefficients. The results (residuals) are placed
//                      in a contiguous array of 64 elements.
//
//  Input Arguments:    
//  stream_buf          Pointer to the source video bitstream in which the
//                      inter block starts
//  quant_para          Quantization parameter of current MB
//  quant_matrix        Pointer to the quantization weighting matrix for inter
//                      macroblock. 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.
//
//  Output Arguments:   
//  stream_buf          Pointer to the updated video bitstream after the block
//                      is decoded
//  dst_rsd             pointer to the decoded residual buffer (a contiguous
//                      array of 64 elements of Ipp16s data type).
//
//  Returns:
//     SAMPLE_STATUS_NOERR      If succeeds
//     SAMPLE_STATUS_ERR        If decoding fails
//
//  Notes:              
//
******************************************************************************/
sample_status decode_block_inter_mpeg4
(sample_bitstream *stream_buf, Ipp16s *dst_rsd, int quant_para, 
 const Ipp8u *quant_matrix)
{
    /* 1. VLC decoding of inter DC and AC components and inverse zigzag scan */
    /* dst_rsd must be 4 byte aligned */
    if (ippStsNoErr != ippiDecodeVLCZigzag_Inter_MPEG4_1u16s (
        &stream_buf->bs_cur_byte, &stream_buf->bs_cur_bitoffset, dst_rsd)) {
        return SAMPLE_STATUS_ERR;
    }

    /* 2. inverse quantisation */
    if (ippStsNoErr != ippiQuantInvInter_MPEG4_16s_I (dst_rsd, quant_para,
        quant_matrix)) {
        return SAMPLE_STATUS_ERR;
    }

    /* 3. inverse DCT */
    /* dst_rsd must be 8 byte aligned */
    if (ippStsNoErr != ippiDCT8x8Inv_Video_16s_C1I(dst_rsd)) {
        return SAMPLE_STATUS_ERR;
    }

    return SAMPLE_STATUS_NOERR;
}


/******************************************************************************
//
// Name:                decode_block_intradc_mpeg4
//
// Description:         Decodes the INTRA block which has only intra DC
//                      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:           
//  
//
******************************************************************************/
sample_status decode_block_intradc_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 */    
    Ipp32u  code;
    int     dc_size, i, level;    
    Ipp16s  coef_buf[72], tmp_coef;
    Ipp16s  *dst_coef = (Ipp16s*)SAMPLE_ALIGN8(coef_buf);
    IppVideoComponent video_comp;
    
    qp_pred = quant_para;

    /* 1. DC 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];
        }
    }

    video_comp = (Y_BLOCK4 >= blk_indx) ? IPP_VIDEO_LUMINANCE
        : IPP_VIDEO_CHROMINANCE;
    
    /* 2. intraDC VLC decoding */
    if(intra_dcvlc_flag) {
        
        if (IPP_VIDEO_LUMINANCE == video_comp) {
            /* dct_dc_size_luminance */
            /* prefetch 3 bits */
            code = get_bits_mpeg4(stream_buf, 3);

            rewind_buffer_mpeg4(stream_buf, 3 - dc_size_lum_tbl[code].numbit);
            dc_size = dc_size_lum_tbl[code].value;

            while ((0 == code) && (12 >= dc_size)) {
                code = get_bits_mpeg4(stream_buf, 1);
                if (0 == code) {
                    dc_size ++;
                }
            }
        } else {
            /* dct_dc_size_chrominance */
            /* prefetch 2 bits */
            code = get_bits_mpeg4(stream_buf, 2);
            rewind_buffer_mpeg4(stream_buf, 2 - dc_size_chr_tbl[code].numbit);
            dc_size = dc_size_chr_tbl[code].value;

            while ((0 == code) && (12 >= dc_size)) {
                code = get_bits_mpeg4(stream_buf, 1);
                if (0 == code) {
                    dc_size++;
                }
            }
        }   /* end of decoding the length of DC coefficient */

        if (12 < dc_size) {
            return SAMPLE_STATUS_ERR;
        }
        /* dc_size bit dct_dc_differential */
        code = get_bits_mpeg4(stream_buf, dc_size);

        if (!(code >> (dc_size - 1))) {
            level = (1 << dc_size) - code - 1;
            level = - level;
        } else {
            level = (int)code;
        }

        if (8 < dc_size) {
            /* assert one marker bit */
            ASSERT_MARKER_BIT(stream_buf);
        }
        /* end of intraDC VLC decoding */       
    } else {
        /* use_intra_dc_vlc == 0 */
        level = 0;
    }
    dst_coef[0] = (Ipp16s)level;
    
    /* reset all AC differential coeffs to zero */

⌨️ 快捷键说明

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