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

📄 umc_mpeg2_dec.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:

Status MPEG2VideoDecoderBase::GetInfo(BaseCodecParams* info)
{
  VideoDecoderParams *pParams;
  if(info == NULL)
    return UMC_ERR_NULL_PTR;

  // BaseCodecParams
  info->profile = sequenceHeader.profile;
  info->level = sequenceHeader.level;

  pParams = DynamicCast<VideoDecoderParams> (info);

  if (NULL != pParams) {
    pParams->info = m_ClipInfo;
    //VideoDecoder::GetInfo(pParams);
    pParams->lFlags = m_lFlags;
    if(m_bOwnAllocator)
      pParams->lpMemoryAllocator = 0;
    else
      pParams->lpMemoryAllocator = m_pMemoryAllocator;
    pParams->pPostProcessing = m_PostProcessing;
    pParams->numThreads = m_nNumberOfThreads;
  }
  return UMC_OK;
}


Status MPEG2VideoDecoderBase::GetPerformance    (Ipp64f * /*perf*/)
{
    return UMC_OK;
}

Status MPEG2VideoDecoderBase::SaveFrame(Ipp32s index, Ipp64f dTime, MediaData *output)
{
  Status ret;

  if (m_LastDecodedFrame.GetColorFormat() != m_ClipInfo.color_format ||
      m_LastDecodedFrame.GetWidth() != m_ClipInfo.clip_info.width ||
      m_LastDecodedFrame.GetHeight() != m_ClipInfo.clip_info.height) {
    m_LastDecodedFrame.Init(m_ClipInfo.clip_info.width, m_ClipInfo.clip_info.height, m_ClipInfo.color_format);
  }
  m_LastDecodedFrame.SetFrameType(frame_buffer.frame_p_c_n[index].frame_type);
  m_LastDecodedFrame.SetTime(dTime);
  m_LastDecodedFrame.SetPlanePitch(frame_buffer.Y_comp_pitch, 0);
  m_LastDecodedFrame.SetPlanePitch(frame_buffer.U_comp_pitch, 1);
  m_LastDecodedFrame.SetPlanePitch(frame_buffer.V_comp_pitch, 2);
  if (sequenceHeader.progressive_sequence || PictureHeader.progressive_frame) {
    m_LastDecodedFrame.SetPictureStructure(PS_FRAME);
  } else {
    if(PictureHeader.picture_structure == FRAME_PICTURE)
      m_LastDecodedFrame.SetPictureStructure(
        (PictureHeader.top_field_first) ? PS_TOP_FIELD_FIRST : PS_BOTTOM_FIELD_FIRST);
    else
      m_LastDecodedFrame.SetPictureStructure( // check last field type
        (PictureHeader.picture_structure == BOTTOM_FIELD) ? PS_TOP_FIELD_FIRST : PS_BOTTOM_FIELD_FIRST);
  }

  if (!m_PostProcessing) {
    m_PostProcessing = m_allocatedPostProcessing = new VideoProcessing;
  }

  if (UMC_OK != (ret = LockBuffers()))
    return ret;
  m_LastDecodedFrame.SetPlanePointer(frame_buffer.frame_p_c_n[index].Y_comp_data, 0);
  m_LastDecodedFrame.SetPlanePointer(frame_buffer.frame_p_c_n[index].U_comp_data, 1);
  m_LastDecodedFrame.SetPlanePointer(frame_buffer.frame_p_c_n[index].V_comp_data, 2);
  ret = m_PostProcessing->GetFrame(&m_LastDecodedFrame, output);
  UnlockBuffers();
  return ret;
}

void MPEG2VideoDecoderBase::ReadCCData()
{
    Status umcRes = UMC_OK;
    MediaData ccData;
    //we will not wait if there is not buffer
    //while(umcRes != UMC_OK)
    {
        umcRes = m_pCCData->LockInputBuffer(&ccData);
        //vm_time_sleep(1);
    }
    if(umcRes == UMC_OK)
    {
      IppVideoContext* video = Video[0];
      Ipp8u* ptr;
      Ipp8u* readptr;
      Ipp32s size;
      Ipp32s inputsize;
      Ipp32s code;

      ptr = (Ipp8u*)ccData.GetDataPointer() + ccData.GetDataSize();
      size = (Ipp32s)((Ipp8u*)ccData.GetBufferPointer() + ccData.GetBufferSize() - ptr);
      if(ptr==0 || size<4)
        return;

      inputsize = GET_REMAINED_BYTES(video->bs);
      readptr = GET_BYTE_PTR(video->bs);
      FIND_START_CODE(video->bs, code);
      if(code != UMC_ERR_NOT_ENOUGH_DATA)
        inputsize = GET_BYTE_PTR(video->bs) - readptr;

      ptr[0] = 0; ptr[1] = 0; ptr[2] = 1; ptr[3] = 0xb2;
      size -= 4;
      size = IPP_MIN(size, inputsize);

      ippsCopy_8u(readptr, ptr+4, size);
      ccData.SetDataSize(ccData.GetDataSize() + size+4);
      umcRes = m_pCCData->UnLockInputBuffer(&ccData);

      if(code == UMC_ERR_NOT_ENOUGH_DATA) {
        ptr = GET_END_PTR(video->bs);
        if(ptr[-1] <= 1) ptr--;
        if(ptr[-1] == 0) ptr--;
        if(ptr[-1] == 0) ptr--;
        SET_PTR(video->bs, ptr);
      }
    }
}

MPEG2VideoDecoder::MPEG2VideoDecoder()
{
    m_pDec = NULL;
}

MPEG2VideoDecoder::~MPEG2VideoDecoder(void)
{
    Close();
}

Status MPEG2VideoDecoder::Init(BaseCodecParams *init)
{
    Close();

    m_pDec = new MPEG2VideoDecoderBase;
    if(!m_pDec) return UMC_ERR_ALLOC;

    Status res = m_pDec->Init(init);

    if (UMC_OK != res) {
      Close();
    }

    return res;
}


Status MPEG2VideoDecoder::GetFrame(MediaData* in, MediaData* out)
{
    if(m_pDec)
    {
        return m_pDec->GetFrame(in, out);
    }

    return UMC_ERR_NOT_INITIALIZED;
}

Status MPEG2VideoDecoder::Close()
{
    if(m_pDec)
    {
        m_pDec->Close();
        delete m_pDec;
        m_pDec = NULL;
    }

    return UMC_OK;
}

Status MPEG2VideoDecoder::Reset()
{
    if(m_pDec)
    {
        return m_pDec->Reset();
    }

    return UMC_ERR_NOT_INITIALIZED;
}

Status MPEG2VideoDecoder::GetInfo(BaseCodecParams* info)
{
    if(m_pDec)
    {
        return m_pDec->GetInfo(info);
    }

    return UMC_ERR_NOT_INITIALIZED;
}

Status MPEG2VideoDecoder::GetPerformance(Ipp64f *perf)
{
    if(m_pDec)
    {
        return m_pDec->GetPerformance(perf);
    }

    return UMC_ERR_NOT_INITIALIZED;
}

Status MPEG2VideoDecoder::ResetSkipCount()
{
    if(m_pDec)
    {
        return m_pDec->ResetSkipCount();
    }

    return UMC_ERR_NOT_INITIALIZED;
}

Status MPEG2VideoDecoder::SkipVideoFrame(Ipp32s count)
{
    if(m_pDec)
    {
        return m_pDec->SkipVideoFrame(count);
    }

    return UMC_ERR_NOT_INITIALIZED;
}


Ipp32u MPEG2VideoDecoder::GetNumOfSkippedFrames()
{
    if(m_pDec)
    {
        return m_pDec->GetNumOfSkippedFrames();
    }

    return (Ipp32u)(-1); // nobody check for -1 really

}

Status MPEG2VideoDecoder::PreviewLastFrame(VideoData *out, BaseCodec *pPostProcessing)
{
    if(m_pDec)
    {
        return m_pDec->PreviewLastFrame(out, pPostProcessing);
    }
    return UMC_ERR_NOT_INITIALIZED;
}

Status MPEG2VideoDecoder::GetUserData(MediaData* pCC)
{
    if(m_pDec)
    {
        return m_pDec->GetUserData(pCC);
    }

    return UMC_ERR_NOT_INITIALIZED;
}

Status MPEG2VideoDecoder::SetParams(BaseCodecParams* params)
{
    if(m_pDec)
    {
        return m_pDec->SetParams(params);
    }
    return UMC_ERR_NOT_INITIALIZED;

}

Status MPEG2VideoDecoderBase::SetParams(BaseCodecParams* params)
{
    VideoDecoderParams *pParams = DynamicCast<VideoDecoderParams>(params);

    if (NULL == pParams)
        return UMC_ERR_NULL_PTR;

    if(pParams->lTrickModesFlag == 3)
    {
        m_bNoBframes = true;
        m_bNoPframes = false;
    }
    else if(pParams->lTrickModesFlag == 5)
    {
         m_bNoBframes = true;
         m_bNoPframes = true;
    }
    else
    {
         m_bNoBframes = false;
         m_bNoPframes = false;
    }

    if(pParams->lTrickModesFlag == 7)
    {
        m_dPlaybackRate = pParams->dPlaybackRate;
    }

    return UMC_OK;
}

Status MPEG2VideoDecoderBase::UpdateFrameBuffer(void)
{
  Ipp32s pitch_l, pitch_c;
  Ipp32s size_l, size_c;
  Ipp8u* ptr;
  Ipp32s i;
  Ipp32s buff_size;

  if(frame_buffer.allocated_mb_width == sequenceHeader.mb_width &&
     frame_buffer.allocated_mb_height == sequenceHeader.mb_height &&
     frame_buffer.allocated_cformat == m_ClipInfo.color_format)
    return UMC_OK; // all is the same

  pitch_l = align_value<Ipp32s>(sequenceHeader.mb_width*16, ALIGN_VALUE);
  size_l = sequenceHeader.mb_height*16*pitch_l;
  if (m_ClipInfo.color_format != YUV444) {
    pitch_c = align_value<Ipp32s>(sequenceHeader.mb_width*8, ALIGN_VALUE);
    size_c = sequenceHeader.mb_height*8*pitch_c;
    if (m_ClipInfo.color_format == YUV422)
      size_c *= 2;
  } else {
    pitch_c = pitch_l;
    size_c = size_l;
  }

  frame_buffer.Y_comp_pitch = pitch_l;
  frame_buffer.U_comp_pitch = pitch_c;
  frame_buffer.V_comp_pitch = pitch_c;
  frame_buffer.pic_size = size_l;

  blkOffsets[0][0] = 0;
  blkOffsets[0][1] = 8;
  blkOffsets[0][2] = 8*pitch_l;
  blkOffsets[0][3] = 8*pitch_l + 8;
  blkOffsets[0][4] = 0;
  blkOffsets[0][5] = 0;
  blkOffsets[0][6] = 8*pitch_c;
  blkOffsets[0][7] = 8*pitch_c;
  blkOffsets[1][0] = 0;
  blkOffsets[1][1] = 8;
  blkOffsets[1][2] = pitch_l;
  blkOffsets[1][3] = pitch_l + 8;
  blkOffsets[1][4] = 0;
  blkOffsets[1][5] = 0;
  blkOffsets[1][6] = pitch_c;
  blkOffsets[1][7] = pitch_c;
  blkOffsets[2][0] = 0;
  blkOffsets[2][1] = 8;
  blkOffsets[2][2] = 16*pitch_l;
  blkOffsets[2][3] = 16*pitch_l + 8;
  blkOffsets[2][4] = 0;
  blkOffsets[2][5] = 0;
  blkOffsets[2][6] = 16*pitch_c;
  blkOffsets[2][7] = 16*pitch_c;

  blkPitches[0][0] = pitch_l;
  blkPitches[0][1] = pitch_c;
  blkPitches[1][0] = 2*pitch_l;
  blkPitches[1][1] = pitch_c;
  if (m_ClipInfo.color_format != YUV420) blkPitches[1][1] = 2 * pitch_c;
  blkPitches[2][0] = 2*pitch_l;
  blkPitches[2][1] = 2*pitch_c;

  if(frame_buffer.allocated_mb_width >= sequenceHeader.mb_width &&
     frame_buffer.allocated_mb_height >= sequenceHeader.mb_height &&
     frame_buffer.allocated_cformat >= m_ClipInfo.color_format)
    return UMC_OK; // use allocated before

  frame_buffer.allocated_mb_width = sequenceHeader.mb_width;
  frame_buffer.allocated_mb_height = sequenceHeader.mb_height;
  frame_buffer.allocated_cformat = m_ClipInfo.color_format;

  for (i = 0; i < 3; i++)
  {
    frame_buffer.frame_p_c_n[i].va_index = -1;
  }

  // Alloc frames

  if(frame_buffer.mid_context_data != MID_INVALID)
    m_pMemoryAllocator->Free(frame_buffer.mid_context_data);

  buff_size = 3*size_l + 6*size_c;
#ifdef KEEP_HISTORY
  buff_size += 3*sequenceHeader.numMB;
#endif
  if(UMC_OK != m_pMemoryAllocator->Alloc(&frame_buffer.mid_context_data,
    buff_size, UMC_ALLOC_PERSISTENT, ALIGN_VALUE)) {
    vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External allocation failed\n"));
    return UMC_ERR_ALLOC;
  }

  frame_buffer.ptr_context_data = (Ipp8u*)m_pMemoryAllocator->Lock(frame_buffer.mid_context_data);
  if(!frame_buffer.ptr_context_data) {
    vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Lock failed\n"));
    return UMC_ERR_ALLOC;
  }

  ptr = frame_buffer.ptr_context_data;
  ptr = align_pointer<Ipp8u*>(ptr, ALIGN_VALUE);

  for (i = 0; i < 3; i++) {
    frame_buffer.frame_p_c_n[i].Y_comp_data = ptr;
    ptr += size_l;
    frame_buffer.frame_p_c_n[i].U_comp_data = ptr;
    ptr += size_c;
    frame_buffer.frame_p_c_n[i].V_comp_data = ptr;
    ptr += size_c;
  }

#ifdef KEEP_HISTORY
  ippsSet_8u(0, ptr, 3*sequenceHeader.numMB);
    frame_buffer.frame_p_c_n[0].frame_history = ptr;
    frame_buffer.frame_p_c_n[1].frame_history = ptr + sequenceHeader.numMB;
    frame_buffer.frame_p_c_n[2].frame_history = ptr + 2*sequenceHeader.numMB;
#endif
  if (UMC_OK != m_pMemoryAllocator->Unlock(frame_buffer.mid_context_data)) {
    vm_debug_trace(VM_DEBUG_ERROR, VM_STRING("External Unlock failed\n"));
  }

  return UMC_OK;
}


#define SHIFT_PTR(oldptr, oldbase, newbase) \
  ( (newbase) + ( (Ipp8u*)(oldptr) - (Ipp8u*)(oldbase) ) )

Status MPEG2VideoDecoderBase::LockBuffers(void)
{
  Ipp32s i;
  Ipp8u* newptr;
  if (frame_buffer.ptr_context_data == 0) // wasn't allocated, error
    return UMC_ERR_NOT_INITIALIZED;
  newptr = (Ipp8u*) m_pMemoryAllocator->Lock(frame_buffer.mid_context_data);
  if(newptr == frame_buffer.ptr_context_data) //ptr not changed
    return UMC_OK;
  // else need to reset pointers
  for (i = 0; i < 3; i++) {
    frame_buffer.frame_p_c_n[i].Y_comp_data =
      (Ipp8u*)SHIFT_PTR(frame_buffer.frame_p_c_n[i].Y_comp_data,
      frame_buffer.ptr_context_data, newptr);
    frame_buffer.frame_p_c_n[i].U_comp_data =
      (Ipp8u*)SHIFT_PTR(frame_buffer.frame_p_c_n[i].U_comp_data,
      frame_buffer.ptr_context_data, newptr);
    frame_buffer.frame_p_c_n[i].V_comp_data =
      (Ipp8u*)SHIFT_PTR(frame_buffer.frame_p_c_n[i].V_comp_data,
      frame_buffer.ptr_context_data, newptr);
#ifdef KEEP_HISTORY
    frame_buffer.frame_p_c_n[i].frame_history =
      (Ipp8u*)SHIFT_PTR(frame_buffer.frame_p_c_n[i].frame_history,
      frame_buffer.ptr_context_data, newptr);
#endif
  }
  frame_buffer.ptr_context_data = newptr;
  return UMC_OK;
}

Status MPEG2VideoDecoderBase::UnlockBuffers(void)
{
  return m_pMemoryAllocator->Unlock(frame_buffer.mid_context_data);
}

// need to lock internal buffer before call
Status MPEG2VideoDecoderBase::PreviewLastFrame(VideoData *out, BaseCodec *pPostProcessing)
{
  Status ret = UMC_ERR_NOT_ENOUGH_DATA;
  if (frame_buffer.retrieve < 0 || UMC_OK != (ret = LockBuffers()))
    return ret;
  m_LastDecodedFrame.SetPlanePointer(frame_buffer.frame_p_c_n[frame_buffer.retrieve].Y_comp_data, 0);
  m_LastDecodedFrame.SetPlanePointer(frame_buffer.frame_p_c_n[frame_buffer.retrieve].U_comp_data, 1);
  m_LastDecodedFrame.SetPlanePointer(frame_buffer.frame_p_c_n[frame_buffer.retrieve].V_comp_data, 2);
  ret = VideoDecoder::PreviewLastFrame(out, pPostProcessing);
  UnlockBuffers();
  return ret;
}

#endif // UMC_ENABLE_MPEG2_VIDEO_DECODER

⌨️ 快捷键说明

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