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

📄 umc_mpeg1_dec.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "umc_defs.h"
#if defined (UMC_ENABLE_MPEG2_VIDEO_DECODER)

#include "umc_mpeg2_dec_base.h"

#pragma warning(disable: 4244)

using namespace UMC;

#define BlockIntra_mpeg1(dc_past, pDst, Pitch)                    \
  if (ippiDecodeIntra8x8IDCT_MPEG1_1u8u(&video->bs_curr_ptr,      \
                                        &video->bs_bit_offset,    \
                                        &video->decodeIntraSpec,  \
                                        video->cur_q_scale,       \
                                        flag,                     \
                                        dc_past,                  \
                                        pDst,                     \
                                        Pitch))                   \
  {                                                               \
    return UMC_ERR_INVALID_STREAM;                                        \
  }

Status MPEG2VideoDecoderBase::DecodeSlice_MPEG1(IppVideoContext *video)
{
  Ipp32s pitch_l = frame_buffer.Y_comp_pitch;
  Ipp32s pitch_c = frame_buffer.U_comp_pitch;
  Ipp32s coded_block_pattern = 0;
  Ipp32s end_of_macroblock;
  Ipp32s macroblock_type;
  Ipp32s macroblock_quant;
  Ipp32s macroblock_pattern;
  Ipp32s macroblock_intra;
  Ipp32s macroblock_address_increment;
  Ipp32u code;
  Ipp32s mb_row_prev, mb_col_prev;

  video->prediction_type = IPPVC_MC_FRAME;

  video->dct_dc_past[0] = 128;
  video->dct_dc_past[1] = 128;
  video->dct_dc_past[2] = 128;

  for (;;) {
    SHOW_BITS(video->bs, 11, code);
    while (code == 0x00f) {
      SKIP_BITS(video->bs, 11); //macroblock_stuffing
      SHOW_BITS(video->bs, 11, code)
    }

    macroblock_address_increment = 0;

    if(code == 0)
      return UMC_OK; // end of slice or bad code. Anyway, stop slice

    while(code == 0x008)
    {
      macroblock_address_increment += 33;//macroblock_escape
      GET_BITS(video->bs, 11, code);
      SHOW_BITS(video->bs,11,code)
    }

    DECODE_VLC(code, video->bs, vlcMBAdressing);
    if (GET_REMAINED_BYTES(video->bs) <= 0)
      return UMC_OK;

    macroblock_address_increment += code;

    if(macroblock_address_increment > 1 || video->m_bNewSlice)
      video->dct_dc_past[0] =
      video->dct_dc_past[1] =
      video->dct_dc_past[2] = 128;

    if(video->m_bNewSlice) {
      video->mb_row = video->slice_vertical_position - 1;
      video->mb_col = macroblock_address_increment - 1;
      video->mb_address_increment = 1;
      mb_row_prev = video->mb_row;
      mb_col_prev = video->mb_col;
      video->m_bNewSlice = false;
    } else {
      video->mb_address_increment = macroblock_address_increment;
      mb_row_prev = video->mb_row;
      mb_col_prev = video->mb_col+1;
      video->mb_col += macroblock_address_increment;
      if(video->mb_col >= sequenceHeader.mb_width) {
        if(m_ClipInfo.stream_type != MPEG1_VIDEO)
          return UMC_OK;
        video->mb_row += video->mb_col / sequenceHeader.mb_width;
        if(video->mb_row >= sequenceHeader.mb_height)
            return UMC_OK;
        video->mb_col %= sequenceHeader.mb_width;
        // prev points to this or first skipped, could change row in mpeg1
        mb_row_prev += mb_col_prev / sequenceHeader.mb_width;
        mb_col_prev %= sequenceHeader.mb_width;
      }
    }

    if(video->mb_address_increment > 1)
    {
      Ipp32s toskip = video->mb_address_increment-1;
      Ipp32s row_l = mb_row_prev << 4;
      Ipp32s col_l = mb_col_prev << 4;
      Ipp32s nmb;

      if (PictureHeader.picture_coding_type == P_PICTURE) {
        video->PMV[0] = 0;
        video->PMV[1] = 0;
      }
      video->vector[0] = video->PMV[0];
      video->vector[1] = video->PMV[1];
      video->vector[2] = video->PMV[2];
      video->vector[3] = video->PMV[3];

      while(toskip>0){
        nmb = sequenceHeader.mb_width - (col_l >> 4);
        if (nmb > toskip) nmb = toskip;
        video->offset_l = row_l * pitch_l + col_l;
        video->offset_c = (row_l >> 1) * pitch_c + (col_l >> 1);

        video->mb_address_increment = nmb + 1;

        if (video->macroblock_motion_forward && video->macroblock_motion_backward) {
          mc_mp2_420b_skip(video);
        } else {
          mc_mp2_420_skip(video);
        }

        toskip -= nmb;
        if (toskip > 0) {
          col_l = 0;
          row_l += 16;
          if(row_l >= sequenceHeader.mb_height*16) {
            return UMC_ERR_INVALID_STREAM;
          }
        }
      }
    }// skipped macroblocks

    if(PictureHeader.picture_coding_type != D_PICTURE)
    {
      DECODE_VLC(macroblock_type, video->bs, vlcMBType[PictureHeader.picture_coding_type - 1]);
      macroblock_quant          = macroblock_type & 0x10;
      video->macroblock_motion_forward = macroblock_type & 0x08;
      video->macroblock_motion_backward= macroblock_type & 0x04;
      macroblock_pattern        = macroblock_type & 0x02;
      macroblock_intra          = macroblock_type & 0x01;
    }
    else//D picture
    {
      GET_1BIT(video->bs,macroblock_type);
      VM_ASSERT(macroblock_type == 1);
      macroblock_intra           = 1;
      macroblock_quant           = 0;
      video->macroblock_motion_forward = 0;
      video->macroblock_motion_backward= 0;
      macroblock_pattern        = 0;
    }//switch(PictureHeader.picture_coding_type)

    if(macroblock_quant)
    {
      GET_TO9BITS(video->bs, 5, video->cur_q_scale);
      VM_ASSERT(video->cur_q_scale >= 1);
    }

    video->offset_l = (video->mb_row*pitch_l + video->mb_col) << 4;
    video->offset_c = (video->mb_row*pitch_c + video->mb_col) << 3;
    Ipp32s curr_index = frame_buffer.curr_index;
    Ipp8u *cur_Y_data = frame_buffer.frame_p_c_n[curr_index].Y_comp_data;
    Ipp8u *cur_U_data = frame_buffer.frame_p_c_n[curr_index].U_comp_data;
    Ipp8u *cur_V_data = frame_buffer.frame_p_c_n[curr_index].V_comp_data;
    cur_Y_data += video->offset_l;
    cur_U_data += video->offset_c;
    cur_V_data += video->offset_c;
    video->blkCurrYUV[0] = cur_Y_data;
    video->blkCurrYUV[1] = cur_U_data;
    video->blkCurrYUV[2] = cur_V_data;

    if(macroblock_intra)
    {
      Ipp32s flag = (PictureHeader.picture_coding_type & D_PICTURE);

      video->PMV[0] = 0;
      video->PMV[1] = 0;
      video->PMV[2] = 0;
      video->PMV[3] = 0;

      BlockIntra_mpeg1(&video->dct_dc_past[0], cur_Y_data, pitch_l);
      BlockIntra_mpeg1(&video->dct_dc_past[0], cur_Y_data + 8, pitch_l);
      BlockIntra_mpeg1(&video->dct_dc_past[0], cur_Y_data + 8*pitch_l, pitch_l);
      BlockIntra_mpeg1(&video->dct_dc_past[0], cur_Y_data + 8*pitch_l + 8, pitch_l);
      flag |= 1; // 1=ChromaFlag
      BlockIntra_mpeg1(&video->dct_dc_past[1], cur_U_data, pitch_c);
      BlockIntra_mpeg1(&video->dct_dc_past[2], cur_V_data, pitch_c);

      if (PictureHeader.picture_coding_type == D_PICTURE)
      {
        GET_1BIT(video->bs,end_of_macroblock);
        VM_ASSERT(end_of_macroblock);
        if(!end_of_macroblock)
          return UMC_ERR_INVALID_STREAM;
      }
    }
    else
    {
      video->dct_dc_past[0] = 128;
      video->dct_dc_past[1] = 128;
      video->dct_dc_past[2] = 128;

      if (video->macroblock_motion_forward) {
        if (PictureHeader.full_pel_forward_vector) {
          mc_fullpel_forward(video);
        } else {
          mc_frame_forward_420(video);
        }
        if (video->macroblock_motion_backward) {
          if (PictureHeader.full_pel_backward_vector) {
            mc_fullpel_backward_add(video);
          } else {
            mc_frame_backward_add_420(video);
          }
        }
      } else {
        if (video->macroblock_motion_backward) {
          if (PictureHeader.full_pel_backward_vector) {
            mc_fullpel_backward(video);
          } else {
            mc_frame_backward_420(video);
          }
        } else /*if (PictureHeader.picture_coding_type == P_FRAME)*/ {
          RESET_PMV(video->PMV)
            mc_frame_forward0_420(video);
        }
      }

      if(macroblock_pattern)
      {
        DECODE_VLC(coded_block_pattern, video->bs, vlcMBPattern);
      }

      Ipp32s blk;
      for (blk = 0; blk < 6; blk++) {
        if (coded_block_pattern & 32) {
          Ipp32s chromaFlag = blk >> 2;
          Ipp32s cc = chromaFlag + (blk & chromaFlag);
          IppiDecodeInterSpec_MPEG2 *interSpec;
          interSpec = chromaFlag ? &video->decodeInterSpecChroma : &video->decodeInterSpec;

          ippiDecodeInter8x8IDCTAdd_MPEG1_1u8u(
            &video->bs_curr_ptr,
            &video->bs_bit_offset,
            interSpec,
            video->cur_q_scale,
            video->blkCurrYUV[cc] + blkOffsets[0][blk],
            blkPitches[0][chromaFlag]);
        }
        coded_block_pattern += coded_block_pattern;
      }
    }
  }

  return UMC_OK;
}

#endif // UMC_ENABLE_MPEG2_VIDEO_DECODER

⌨️ 快捷键说明

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