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

📄 umc_h263_video_decoder.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    return status;
  m_dec_time_fr = 0.0;
  m_dec_time_base = -1.0;
  m_dec_time_prev = 0.0;
  m_dec_time_frinc = (pParam->info.framerate > 0) ? 1.0 / pParam->info.framerate : 0.0;
  m_is_skipped_b = m_skipped_fr = m_b_prev = 0;
  m_Param = *pParam;
  m_IsInit = false;
  memset(m_decInfo, 0, sizeof(h263_Info));
  if (NULL != pParam->m_pData) {
    if (pParam->m_pData->GetTime() >= 0.0)
      m_dec_time_base = pParam->m_pData->GetTime();
    m_decInfo->buflen = pParam->m_pData->GetDataSize();
    if (m_decInfo->buflen > 0) {
      m_decInfo->bufptr = m_decInfo->buffer = reinterpret_cast<Ipp8u *> (pParam->m_pData->GetDataPointer());
//      m_decInfo->bitoff = 0;
      status = InsideInit(&m_Param);
    }
  }
  if (UMC_OK == status) {
    m_PostProcessing = pParam->pPostProcessing;
    if (pParam->info.clip_info.width == 0 || pParam->info.clip_info.height == 0) {
      if (m_decInfo->VideoSequence.VideoPicture.width == 0 && m_decInfo->VideoSequence.VideoPicture.height== 0)
        return UMC_ERR_INIT;
      else {
        pParam->info.clip_info.width = m_Param.info.clip_info.width; // = m_decInfo->VideoSequence.VideoPicture.width;
        pParam->info.clip_info.height = m_Param.info.clip_info.height; // = m_decInfo->VideoSequence.VideoPicture.height;
      }
    }
    if (pParam->info.framerate <= 0) {
      Ipp32s frameInterval;
      if (m_decInfo->VideoSequence.VideoPicture.clock_divisor)
        frameInterval = m_decInfo->VideoSequence.VideoPicture.clock_divisor * (1000 + m_decInfo->VideoSequence.VideoPicture.clock_conversion_code);
      else
        frameInterval = H263_DEFAULT_FRAME_INTERVAL;
      pParam->info.framerate = m_Param.info.framerate = (Ipp64f)m_decInfo->VideoSequence.picture_time_increment_resolution / (Ipp64f)frameInterval;
    }
  }
  m_ClipInfo = m_Param.info;
  m_IsInitBase = true;
  return status;
}

Status H263VideoDecoder::InsideInit(VideoDecoderParams *pParam)
{
  Status status = UMC_OK;
  m_buffered_frame = m_Param.lFlags & FLAG_VDEC_REORDER;
  m_P_part_of_PB_pending = false; /* can be true only if !(m_Param.lFlags & FLAG_VDEC_REORDER) */

  m_decInfo->number_threads = m_Param.numThreads;

  if (!h263_SeekStartCodePtr(m_decInfo)) {
    vm_debug_trace(VM_DEBUG_INFO,__VM_STRING("Error: Can't find picture start code\n"));
    return UMC_ERR_SYNC;
  }

  if (h263_Parse_PictureHeader(m_decInfo) != H263_STATUS_OK)
    return UMC_ERR_INVALID_STREAM;

  if (h263_InitVSeq(m_decInfo, -1, -1) != H263_STATUS_OK) {
    vm_debug_trace(VM_DEBUG_INFO,__VM_STRING("Error: No memory to allocate internal buffers\n"));
    return UMC_ERR_ALLOC;
  }

  pParam->info.clip_info.width = m_decInfo->VideoSequence.VideoPicture.width;
  pParam->info.clip_info.height = m_decInfo->VideoSequence.VideoPicture.height;

  status = AllocateBuffers();
  if (status != UMC_OK)
    return status;

  m_decInfo->bufptr = m_decInfo->buffer;
  m_decInfo->bitoff = 0;

  m_IsInit = true;
  return status;
}

Status H263VideoDecoder::GetFrame(MediaData* in, MediaData* out)
{
  Status status = UMC_OK;
  Ipp64f pts;
  Ipp32s resizeMask;

#ifdef _OMP_KARABAS
  m_decInfo->mTreadPriority = vm_get_current_thread_priority();
#endif // _OMP_KARABAS

  if (!m_IsInitBase)
    return UMC_ERR_NOT_INITIALIZED;
  if (out == NULL)
    return UMC_ERR_NULL_PTR;

  if (in) {
    m_decInfo->bitoff = 0;
    m_decInfo->bufptr = m_decInfo->buffer = (Ipp8u *)in->GetDataPointer();
    m_decInfo->buflen = in->GetDataSize();
  }
  if (!m_IsInit) {
    if (in == NULL)
      return UMC_ERR_NULL_PTR;
    m_Param.m_pData = in;
    status = InsideInit(&m_Param);
    if (status != UMC_OK) {
      in->MoveDataPointer(in->GetDataSize() - m_decInfo->buflen);
      return UMC_ERR_INIT;
    }
  }
  LockBuffers();
  for (;;) {
    if (in == NULL) {
        // show last frame (it can be only if (m_Param.lFlags & FLAG_VDEC_REORDER))
      if (!m_buffered_frame) {
        UnlockBuffers();
        return UMC_ERR_NOT_ENOUGH_DATA;
      }
      if (m_decInfo->VideoSequence.Ppics_to_show > 0) {
        m_decInfo->VideoSequence.vFrame = &m_decInfo->VideoSequence.rFrame;
        m_decInfo->VideoSequence.PicIndex++;
        m_decInfo->VideoSequence.Ppics_to_show = 0;
      } else if (m_decInfo->VideoSequence.Bpics_to_show > 0) {
        m_decInfo->VideoSequence.vFrame = &m_decInfo->VideoSequence.nFrame;
        m_decInfo->VideoSequence.PicIndex++;
        m_decInfo->VideoSequence.Bpics_to_show = 0;
      } else {
        m_decInfo->VideoSequence.vFrame = &m_decInfo->VideoSequence.cFrame;
        m_buffered_frame = false;
      }
    } else {
      if (m_decInfo->VideoSequence.Ppics_to_show < 1 && !m_P_part_of_PB_pending) {
        /* Seek the picture start code, and then begin the picture decoding */
        if (!h263_SeekStartCodePtr(m_decInfo)) {
          vm_debug_trace(VM_DEBUG_INFO,__VM_STRING("Error: Can't find picture start code\n"));
          status = UMC_ERR_SYNC;
          break;
        }
        if (h263_Parse_PictureHeader(m_decInfo) != H263_STATUS_OK) {
          status = UMC_WRN_INVALID_STREAM;
          break;
        }

        if (m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_B) {
          if (0 < m_is_skipped_b && !m_b_prev) {
            m_is_skipped_b--;
            m_skipped_fr++;
            m_b_prev = 1;
            m_decInfo->bufptr = m_decInfo->buffer + m_decInfo->buflen;
            status = UMC_ERR_NOT_ENOUGH_DATA;
            break;
          } else
            m_b_prev = 0;
        }
/*
        if (m_decInfo->VideoSequence.VideoPicture.enh_layer_num > 1) {
          status = UMC_ERR_NOT_ENOUGH_DATA;
          break;
        }
*/
        resizeMask = h263_Check_Resize(m_decInfo);
        if (resizeMask < 0) {
          status = UMC_WRN_INVALID_STREAM;
          break;
        }
        if (resizeMask) {
          status = ReAlLockBuffers(resizeMask);
          if (status != UMC_OK)
            break;
        }
        if (m_decInfo->VideoSequence.VideoPicture.enh_layer_num > 1)
          LockEnhancedLayerBuffers(m_decInfo->VideoSequence.VideoPicture.enh_layer_num, m_decInfo->VideoSequence.VideoPicture.ref_layer_num, (resizeMask >> 4));
      }

      if (!m_P_part_of_PB_pending) {
        if ((h263_DecodeVideoPicture(m_decInfo)) != H263_STATUS_OK) {
          status = UMC_WRN_INVALID_STREAM;
        }
        if (!(m_Param.lFlags & FLAG_VDEC_REORDER)) {
          m_decInfo->VideoSequence.Ppics_to_show = 0;
          m_decInfo->VideoSequence.Bpics_to_show = 0;
          m_P_part_of_PB_pending = (m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_PB || m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_iPB);
        }
      } else
        m_P_part_of_PB_pending = false;

      // TODO: add enh layer output optional processing and skipping ???
      if (m_decInfo->VideoSequence.VideoPicture.enh_layer_num > 1) {
        m_decInfo->VideoSequence.enhLayers[m_decInfo->VideoSequence.VideoPicture.enh_layer_num - 2]->picIndex++;
        UnlockEnhancedLayerBuffers(m_decInfo->VideoSequence.VideoPicture.enh_layer_num, m_decInfo->VideoSequence.VideoPicture.ref_layer_num);
        status = UMC_ERR_NOT_ENOUGH_DATA;
        break;
      }
/*
if (m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_EP || m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_EI)  {
  m_decInfo->VideoSequence.vFrame = m_decInfo->VideoSequence.enhLayers[m_decInfo->VideoSequence.VideoPicture.enh_layer_num - 2]->v_Frame;
}
*/
      m_decInfo->VideoSequence.PicIndex++;

      if ((m_Param.lFlags & FLAG_VDEC_REORDER) && (m_decInfo->VideoSequence.vFrame == NULL)) {
          // buffer first frame in VDEC_REORDER mode
          status = UMC_ERR_NOT_ENOUGH_DATA;
          break;
      }

      if (!(m_Param.lFlags & FLAG_VDEC_REORDER)) {
        if (m_P_part_of_PB_pending || m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_B) {
          m_decInfo->VideoSequence.vFrame = &m_decInfo->VideoSequence.nFrame;
        } else {
          m_decInfo->VideoSequence.vFrame = &m_decInfo->VideoSequence.cFrame;
        }
      }
    }
    break;
  }
  if (in)
    if (in->GetTime() >= 0.0 && m_dec_time_base < 0.0)
      m_dec_time_base = in->GetTime();

  if (m_dec_time_frinc > 0.0) {
    if (m_Param.lFlags & FLAG_VDEC_REORDER)
      pts = m_dec_time_prev;
    if (in) {
      if (in->GetTime() >= 0.0) {
        // take right PTS for I-, P- frames
        m_dec_time_prev = in->GetTime();
      } else {
        // when PB...  are in one AVI chunk, first PTS from in->GetTime() is right and second is -1.0
        m_dec_time_prev += m_dec_time_frinc;
      }
    }
    if (!(m_Param.lFlags & FLAG_VDEC_REORDER))
      pts = m_dec_time_prev;
  } else {
    if (in && in->GetTime() >= 0.0)
      pts = in->GetTime();
    else {
      // internal pts
      if (m_decInfo->VideoSequence.vFrame)
        pts = (Ipp64f)m_decInfo->VideoSequence.vFrame->time / m_decInfo->VideoSequence.picture_time_increment_resolution;
      else
        pts = 0.0;
      if (m_dec_time_base > 0.0)
        pts += m_dec_time_base;
    }
  }
  if ((UMC_OK == status || UMC_WRN_INVALID_STREAM == status) && m_decInfo->VideoSequence.vFrame != NULL) {
    FrameType ft = (m_decInfo->VideoSequence.vFrame->type) == H263_PIC_TYPE_I ? I_PICTURE :
                    (m_decInfo->VideoSequence.vFrame->type) == H263_PIC_TYPE_B ? B_PICTURE :
                                                                                P_PICTURE;
    if (m_LastDecodedFrame.GetColorFormat() != YUV420) {
      m_LastDecodedFrame.Init(m_decInfo->VideoSequence.vFrame->width,
                              m_decInfo->VideoSequence.vFrame->height,
                              YUV420);
    }
    m_LastDecodedFrame.SetFrameType(ft);
    m_LastDecodedFrame.SetTime(pts);
    m_LastDecodedFrame.SetPlanePointer(m_decInfo->VideoSequence.vFrame->pY, 0);
    m_LastDecodedFrame.SetPlanePointer(m_decInfo->VideoSequence.vFrame->pCb, 1);
    m_LastDecodedFrame.SetPlanePointer(m_decInfo->VideoSequence.vFrame->pCr, 2);
    m_LastDecodedFrame.SetPlanePitch(m_decInfo->VideoSequence.vFrame->stepY, 0);
    m_LastDecodedFrame.SetPlanePitch(m_decInfo->VideoSequence.vFrame->stepCb, 1);
    m_LastDecodedFrame.SetPlanePitch(m_decInfo->VideoSequence.vFrame->stepCr, 2);
    if (!m_PostProcessing) {
      m_PostProcessing = m_allocatedPostProcessing = createVideoProcessing();
    }
    status = m_PostProcessing->GetFrame(&m_LastDecodedFrame, out);
  }
  if (in) {
    size_t stDecidedData;
    if ((size_t)m_decInfo->bufptr - (size_t)m_decInfo->buffer < m_decInfo->buflen)
      stDecidedData = m_decInfo->buflen - ((size_t)m_decInfo->bufptr - (size_t)m_decInfo->buffer);
    else
      stDecidedData = 0;

    in->MoveDataPointer(in->GetDataSize() - static_cast<Ipp32u>(stDecidedData));
    // can't calculate time for the next frame
    in->SetTime(-1.0);
  }
  UnlockBuffers();

  return status;
}

Status H263VideoDecoder::Close(void)
{
  m_IsInitBase = false;
  if (m_IsInit) {
    FreeBuffers();
    // close default memory allocator
    BaseCodec::Close();
    h263_FreeVSeq(m_decInfo);
    m_IsInit = false;
  }
  return UMC_OK;
}

H263VideoDecoder::H263VideoDecoder(void)
{
  m_IsInit = m_IsInitBase = false;
  m_decInfo = new h263_Info;
}

H263VideoDecoder::~H263VideoDecoder(void)
{
  Close();
  delete m_decInfo;
}

Status H263VideoDecoder::GetInfo(BaseCodecParams* info)
{
  VideoDecoderParams *pParams;
  if (!m_IsInitBase)
    return UMC_ERR_NOT_INITIALIZED;
  if (info == NULL)
    return UMC_ERR_NULL_PTR;
  pParams = DynamicCast<VideoDecoderParams> (info);
  if (NULL != pParams) {
    *pParams = m_Param;
  } else {
    if (!m_IsInit)
      return UMC_ERR_NOT_INITIALIZED;
//    info->profile = m_Param.profile;
//    info->level = m_Param.level;
  }
  return UMC_OK;
}

/*
h263_Frame* H263VideoDecoder::GetCurrentFramePtr(void)
{
  return m_decInfo->VideoSequence.vFrame;
}
*/

Status  H263VideoDecoder::ResetSkipCount()
{
  if (!m_IsInitBase)
    return UMC_ERR_NOT_INITIALIZED;
  m_is_skipped_b = m_skipped_fr = m_b_prev = 0;
  return UMC_OK;
}

Status  H263VideoDecoder::SkipVideoFrame(Ipp32s count)
{
  if (!m_IsInitBase)
    return UMC_ERR_NOT_INITIALIZED;
  if (count < 0) {
    m_is_skipped_b = 0;
    return UMC_OK;
  }
  m_is_skipped_b += count;
  return UMC_OK;
}

Ipp32u H263VideoDecoder::GetNumOfSkippedFrames(void)
{
    return m_skipped_fr;
}

Status H263VideoDecoder::Reset(void)
{
  if (!m_IsInitBase) {
    return UMC_ERR_NOT_INITIALIZED;
  } else if (m_IsInit) {
    m_decInfo->VideoSequence.PicIndex = 0;
    m_decInfo->VideoSequence.Bpics_to_show = m_decInfo->VideoSequence.Ppics_to_show = 0;
    m_decInfo->VideoSequence.prevP_pic_time = m_decInfo->VideoSequence.ref_pic_time = 0;
    m_decInfo->VideoSequence.prevP_temporal_reference = 0;
    m_P_part_of_PB_pending = false;
    m_dec_time_base = -1.0;
    m_dec_time_prev = 0.0;
    m_decInfo->VideoSequence.vFrame = NULL;
  }
  return UMC_OK;
}

Status H263VideoDecoder::GetPerformance(Ipp64f *perf)
{
  return UMC_ERR_NOT_IMPLEMENTED;
}

} // end namespace UMC

⌨️ 快捷键说明

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