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

📄 umc_video_data.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
Status VideoData::Alloc()
{
    size_t nSize;

    // Release previous buffer
    ReleaseImage();

    // get size of buffer to allocate
    nSize = GetMappingSize();
    if (0 == nSize)
        return UMC_ERR_INVALID_STREAM;

    // allocate buffer
    m_pbAllocated = new Ipp8u[nSize + m_iAlignment - 1];
    if (NULL == m_pbAllocated)
        return UMC_ERR_ALLOC;

    // set pointer to image
    return SetBufferPointer(m_pbAllocated, nSize);

} // Status VideoData::Alloc()

// Links to provided image memory
// Image must be described before
Status VideoData::SetBufferPointer(Ipp8u *pbBuffer, size_t nSize)
{
    Ipp32s i;
    size_t mapsize;
    Ipp8u *ptr = align_pointer<Ipp8u *>(pbBuffer, m_iAlignment);

    // check error(s)
    if (NULL == m_pPlaneData) {
        SetDataSize(0);
        return UMC_ERR_FAILED;
    }

    mapsize = GetMappingSize();
    if (nSize < mapsize) {
        SetDataSize(0);
        return UMC_ERR_NOT_ENOUGH_BUFFER;
    }

    // set new plane pointers
    for(i=0; i<m_iPlanes; i++) {
        m_pPlaneData[i].m_pPlane = ptr + m_pPlaneData[i].m_nOffset;
    }

    // call parent class methods
    MediaData::SetBufferPointer(pbBuffer, nSize);
    // set valid data size
    SetDataSize(mapsize + (ptr - pbBuffer));
    MoveDataPointer(ptr - pbBuffer);

    return UMC_OK;

} // Status VideoData::SetBufferPointer(Ipp8u *pbBuffer, size_t nSize)

// Returns required image memory size according to alignment and current image description
size_t VideoData::GetMappingSize()
{
    Ipp32s i;
    size_t size = 0;

    UMC_CHECK(m_pPlaneData, 0);

    for (i = 0; i < m_iPlanes; i++) {
      size += m_pPlaneData[i].m_nMemSize;
    }

    return size;

} // size_t VideoData::GetMappingSize(Ipp32s iAlignment)

// Set pointer for specified plane. Should be used for additional planes,
// or when image layout is different.
Status VideoData::SetPlanePointer(void *pDest, Ipp32s iPlaneNumber)
{
    // check error(s)
    if ((m_iPlanes <= iPlaneNumber) ||
        (0 > iPlaneNumber) ||
        (NULL == m_pPlaneData))
        return UMC_ERR_FAILED;

    m_pPlaneData[iPlaneNumber].m_pPlane = (Ipp8u *) pDest;

    return UMC_OK;

} // Status VideoData::SetPlanePointer(void *pDest, Ipp32s iPlaneNumber)

// Set pitch for specified plane. Should be used for additional planes,
// or when image layout is different.
Status VideoData::SetPlanePitch(size_t nPitch, Ipp32s iPlaneNumber)
{
    // check error(s)
    if ((m_iPlanes <= iPlaneNumber) ||
        (0 > iPlaneNumber) ||
        (NULL == m_pPlaneData))
        return UMC_ERR_FAILED;

    m_pPlaneData[iPlaneNumber].m_nPitch = nPitch;
    m_pPlaneData[iPlaneNumber].m_nMemSize = nPitch * m_pPlaneData[iPlaneNumber].m_ippSize.height;

    return UMC_OK;

} // Status VideoData::SetPlanePitch(size_t nPitch, Ipp32s iPlaneNumber)

// Set bitdepth for specified plane, usually additional or when bitdepth differs
// for main planes
Status VideoData::SetPlaneBitDepth(Ipp32s iBitDepth, Ipp32s iPlaneNumber)
{
    // check error(s)
    if ((m_iPlanes <= iPlaneNumber) ||
        (0 > iPlaneNumber) ||
        (NULL == m_pPlaneData))
        return UMC_ERR_FAILED;

    m_pPlaneData[iPlaneNumber].m_iBitDepth = iBitDepth;
    if(m_pPlaneData[iPlaneNumber].m_iSampleSize*8 < iBitDepth)
        m_pPlaneData[iPlaneNumber].m_iSampleSize = (iBitDepth+7)>>3;

    return UMC_OK;

} // Status VideoData::SetPlaneBitDepth(Ipp32s iBitDepth, Ipp32s iPlaneNumber)

// Set sample size for specified plane, usually additional or when bitdepth differs
// for main planes
Status VideoData::SetPlaneSampleSize(Ipp32s iSampleSize, Ipp32s iPlaneNumber)
{
    // check error(s)
    if ((m_iPlanes <= iPlaneNumber) ||
        (0 > iPlaneNumber) ||
        (NULL == m_pPlaneData))
        return UMC_ERR_FAILED;

    m_pPlaneData[iPlaneNumber].m_iSampleSize = iSampleSize;
    if(iSampleSize*8 < m_pPlaneData[iPlaneNumber].m_iBitDepth)
        m_pPlaneData[iPlaneNumber].m_iBitDepth = iSampleSize*8;

    return UMC_OK;

} // Status VideoData::SetPlaneSampleSize(Ipp32s iSampleSize, Ipp32s iPlaneNumber)

// Links plane pointers to surface using provided pitch.
// All pitches and plane info are updated according to current
// color format.
// Supposes no gaps between planes.
Status VideoData::SetSurface(void* ptr, size_t nPitch)
{
    Status ret;
    size_t size = 0;
    int i;

    // check error(s)
    UMC_CHECK(ptr, UMC_ERR_NULL_PTR);
    UMC_CHECK(m_pPlaneData, UMC_ERR_NOT_INITIALIZED);

    if(nPitch == 0) // use current
      nPitch = m_pPlaneData[0].m_nPitch;

    m_pPlaneData[0].m_nOffset = 0;

    for (i = 0; i < m_iPlanes; i++) {
      m_pPlaneData[i].m_nPitch = nPitch;
      if (i > 0) {
        m_pPlaneData[i].m_nPitch *= m_pPlaneData[i].m_iSamples*m_pPlaneData[0].m_iWidthDiv;
        m_pPlaneData[i].m_nPitch /= m_pPlaneData[i].m_iWidthDiv*m_pPlaneData[0].m_iSamples;
        m_pPlaneData[i].m_nOffset = m_pPlaneData[i - 1].m_nOffset + m_pPlaneData[i - 1].m_nMemSize;
      }
      m_pPlaneData[i].m_pPlane = (Ipp8u*)ptr + m_pPlaneData[i].m_nOffset;
      m_pPlaneData[i].m_nMemSize = m_pPlaneData[i].m_nPitch * m_pPlaneData[i].m_ippSize.height;
      size += m_pPlaneData[i].m_nMemSize;
    }

    ret = MediaData::SetBufferPointer((Ipp8u*)ptr, size);
    ret = MediaData::SetDataSize(size);

    return ret;
}

#define PITCH_PREC  8

// Calculate pitch from mapping size
size_t VideoData::GetPitchFromMappingSize(size_t mappingSize)
{
    size_t size = 0;
    int i;

    // check error(s)
    UMC_CHECK(m_pPlaneData, 0);

    // calculate mapping size for pitch equal to (1 << PITCH_PREC)
    size = m_pPlaneData[0].m_ippSize.height << PITCH_PREC;
    for (i = 1; i < m_iPlanes; i++) {
      size_t plane_size = m_pPlaneData[i].m_ippSize.height << PITCH_PREC;
      plane_size *= m_pPlaneData[i].m_iSamples*m_pPlaneData[0].m_iWidthDiv;
      plane_size /= m_pPlaneData[i].m_iWidthDiv*m_pPlaneData[0].m_iSamples;
      size += plane_size;
    }

    UMC_CHECK(size, 0);

    // calculate real pitch
    return ((mappingSize << PITCH_PREC)/size);
}

Status VideoData::ConvertPictureStructure(PictureStructure newPicStructure)
{
  PictureStructure curr = (PictureStructure)(m_picStructure & PS_FRAME);
  int k;

  vm_debug_trace2(VM_DEBUG_VERBOSE, VM_STRING("VideoData::ConvertPictureStructure %d->%d\n"), curr, newPicStructure);

  if (curr == PS_FRAME && newPicStructure == PS_TOP_FIELD) {
    m_ippSize.height >>= 1;
    for (k = 0; k < m_iPlanes; k++) {
      m_pPlaneData[k].m_ippSize.height >>= 1;
      m_pPlaneData[k].m_nPitch <<= 1;
    }
    curr = PS_TOP_FIELD;
  }

  if (curr == PS_TOP_FIELD && newPicStructure == PS_BOTTOM_FIELD) {
    for (k = 0; k < m_iPlanes; k++) {
      m_pPlaneData[k].m_pPlane += (m_pPlaneData[k].m_nPitch >> 1);
    }
    curr = PS_BOTTOM_FIELD;
  }

  if (curr == PS_BOTTOM_FIELD && (newPicStructure == PS_TOP_FIELD || newPicStructure == PS_FRAME)) {
    for (k = 0; k < m_iPlanes; k++) {
      m_pPlaneData[k].m_pPlane -= (m_pPlaneData[k].m_nPitch >> 1);
    }
    curr = PS_TOP_FIELD;
  }

  if (curr == PS_TOP_FIELD && newPicStructure == PS_FRAME) {
    m_ippSize.height <<= 1;
    for (k = 0; k < m_iPlanes; k++) {
      m_pPlaneData[k].m_ippSize.height <<= 1;
      m_pPlaneData[k].m_nPitch >>= 1;
    }
    curr = PS_FRAME;
  }

  return SetPictureStructure(curr /*| (m_picStructure &~ PS_FRAME)*/);
}

// fills PlaneInfo structure
Status VideoData::GetPlaneInfo(PlaneInfo* pInfo, Ipp32s iPlaneNumber)
{
    // check error(s)
    if (NULL == pInfo)
        return UMC_ERR_NULL_PTR;
    if ((m_iPlanes <= iPlaneNumber) ||
        (0 > iPlaneNumber) ||
        (NULL == m_pPlaneData))
        return UMC_ERR_FAILED;

    *pInfo = m_pPlaneData[iPlaneNumber];
    return UMC_OK;

} // Status VideoData::GetPlaneInfo(PlaneInfo* pInfo, Ipp32s iPlaneNumber)

// converts display aspect ratio to pixel AR
// or vise versa with exchanged width and height
Status DARtoPAR(Ipp32s width, Ipp32s height, Ipp32s dar_h, Ipp32s dar_v,
                Ipp32s *par_h, Ipp32s *par_v)
{
  // (width*par_h) / (height*par_v) == dar_h/dar_v =>
  // par_h / par_v == dar_h * height / (dar_v * width)
  Ipp32s simple_tab[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
  Ipp32s i, denom;

  // suppose no overflow of 32s
  Ipp32s h = dar_h * height;
  Ipp32s v = dar_v * width;
  // remove common multipliers
  while( ((h|v)&1) == 0 ) {
    h>>=1;
    v>>=1;
  }

  for(i=0;i<sizeof(simple_tab)/sizeof(simple_tab[0]);i++) {
    denom = simple_tab[i];
    while(h%denom==0 && v%denom==0) {
      v /= denom;
      h /= denom;
    }
    if(v<=denom || h<=denom)
      break;
  }
  *par_h = h;
  *par_v = v;
  // can don't reach minimum, no problem
  if(i<sizeof(simple_tab)/sizeof(simple_tab[0]))
    return UMC_WRN_INVALID_STREAM;
  return UMC_OK;
}

void VideoData::operator=(VideoData &par)
{
    PlaneInfo *PlaneData = m_pPlaneData;
    if(m_iPlanes < par.m_iPlanes)
    {
        Close();
        PlaneData = new PlaneInfo[par.m_iPlanes];
    } else {
        ReleaseImage();
    }

    memcpy(PlaneData, par.m_pPlaneData, par.m_iPlanes*sizeof(PlaneInfo));
    memcpy(this, &par, sizeof(VideoData));
    m_pPlaneData = PlaneData;

    m_pbAllocated = NULL;

    // from MediaData
    m_bMemoryAllocated = false;
    m_pts_start        = par.m_pts_start;
    m_pts_end          = par.m_pts_end;
    m_FrameType        = par.m_FrameType;
}

} // end namespace UMC

⌨️ 快捷键说明

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