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

📄 umc_color_space_conversion.cpp

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

#include "umc_color_space_conversion.h"
#include "umc_video_data.h"
#include "ippi.h"
#include "ippcc.h"
#include "ippvc.h"

using namespace UMC;

template <class T> inline
void SwapValues(T &one, T& two)
{
  T tmp;
  tmp = one;
  one = two;
  two = tmp;
}

static void ConvertImage_16s8u_C1R(const Ipp16s *pSrc,
                                  Ipp32s   iSrcStride,
                                  Ipp32s   iSrcBitsPerSample,
                                  Ipp8u    *pDst,
                                  Ipp32s   iDstStride,
                                  IppiSize size);
static IppStatus cc_BGRAToBGR(const Ipp8u *pSrc,
                              Ipp32s   iSrcStride,
                              Ipp8u    *pDst,
                              Ipp32s   iDstStride,
                              IppiSize srcSize);
static IppStatus cc_BGRToBGRA(const Ipp8u *pSrc,
                              Ipp32s   iSrcStride,
                              Ipp8u    *pDst,
                              Ipp32s   iDstStride,
                              IppiSize srcSize);
static IppStatus cc_BGR555ToBGR(const Ipp16u *pSrc,
                                Ipp32s   iSrcStride,
                                Ipp8u    *pDst,
                                Ipp32s   iDstStride,
                                IppiSize srcSize);
static IppStatus cc_BGR565ToBGR(const Ipp16u *pSrc,
                                Ipp32s   iSrcStride,
                                Ipp8u    *pDst,
                                Ipp32s   iDstStride,
                                IppiSize srcSize);
static IppStatus cc_Y41P_to_I420(const Ipp8u *pSrc,
                                 Ipp32s   iSrcStride,
                                 Ipp8u    **pDst,
                                 Ipp32s   *iDstStride,
                                 IppiSize srcSize);
static IppStatus cc_I420_to_Y41P(const Ipp8u **pSrc,
                                 Ipp32s   *iSrcStride,
                                 Ipp8u    *pDst,
                                 Ipp32s   iDstStride,
                                 IppiSize srcSize);

static IppStatus cc_YUV411_to_YUV420(const Ipp8u *pSrc[3],
                                     Ipp32s   iSrcStride[3],
                                     Ipp8u    *pDst[3],
                                     Ipp32s   iDstStride[3],
                                     IppiSize srcSize);

static Status CopyImage(VideoData *pSrc, VideoData *pDst, int flag, int bSwapUV)
{
  VideoData::PlaneInfo src;
  VideoData::PlaneInfo dst;
  IppiSize size;
  int cPlanes;
  int iDstPlane;

  cPlanes = pSrc->GetNumPlanes();
  if (cPlanes > pDst->GetNumPlanes()) cPlanes = pDst->GetNumPlanes();

  for (iDstPlane = 0; iDstPlane < cPlanes; iDstPlane++) {
    int iSrcPlane = iDstPlane;
    if (bSwapUV) {
      if (iDstPlane == 1) iSrcPlane = 2; else
      if (iDstPlane == 2) iSrcPlane = 1;
    }

    pSrc->GetPlaneInfo(&src, iSrcPlane);
    pDst->GetPlaneInfo(&dst, iDstPlane);

    size.width = src.m_ippSize.width * src.m_iSamples;
    size.height = src.m_ippSize.height;

    if (src.m_iSampleSize == dst.m_iSampleSize) {
      size.width *= src.m_iSampleSize;
      if (flag == 2 && src.m_iBitDepth >= 0) { // case VC1->YUV420
        ippiRangeMapping_VC1_8u_C1R(src.m_pPlane, src.m_nPitch, dst.m_pPlane, dst.m_nPitch, size, src.m_iBitDepth);
      } else {
        ippiCopy_8u_C1R(src.m_pPlane, src.m_nPitch, dst.m_pPlane, dst.m_nPitch, size);
      }
    } else if (src.m_iSampleSize == 2 && dst.m_iSampleSize == 1) {
      ConvertImage_16s8u_C1R((const Ipp16s*)src.m_pPlane, src.m_nPitch, src.m_iBitDepth, dst.m_pPlane, dst.m_nPitch, size);
    } else {
      return UMC_ERR_UNSUPPORTED;
    }
  }
  return UMC_OK;
}

Status ColorSpaceConversion::GetFrame(MediaData *input, MediaData *output)
{
  VideoData *in = DynamicCast<VideoData>(input);
  VideoData *out = DynamicCast<VideoData>(output);

  if (NULL == in || NULL == out) {
    return UMC_ERR_NULL_PTR;
  }

  IppiSize srcSize = {in->GetWidth(), in->GetHeight()};
  IppiSize dstSize = {out->GetWidth(), out->GetHeight()};
  if (srcSize.width != dstSize.width || srcSize.height != dstSize.height) {
    return UMC_ERR_INVALID_PARAMS;
  }

  ColorFormat srcFormat = in->GetColorFormat();
  ColorFormat dstFormat = out->GetColorFormat();
  int bSrcSwapUV = 0;
  int bDstSwapUV = 0;

  if (srcFormat == YV12) // process YV12 as YUV420
  {
    bSrcSwapUV = 1;
    srcFormat = YUV420;
  }
  if (dstFormat == YV12) // process YV12 as YUV420
  {
    bDstSwapUV = 1;
    dstFormat = YUV420;
  }

  int flag_OnlyCopy = 0;
  if (srcFormat == dstFormat) flag_OnlyCopy = 1;
  if (YUV_VC1 == srcFormat && YUV420 == dstFormat) flag_OnlyCopy = 2;
  if (YUV420A == srcFormat && YUV420 == dstFormat) flag_OnlyCopy = 3;
  if (GRAYA == srcFormat && GRAY == dstFormat) flag_OnlyCopy = 4;
  if (flag_OnlyCopy) {
      return CopyImage(in, out, flag_OnlyCopy, bSrcSwapUV ^ bDstSwapUV);
  }

  const Ipp8u *(pSrc[3]) = {(Ipp8u*)in->GetPlanePointer(0),
                            (Ipp8u*)in->GetPlanePointer(1),
                            (Ipp8u*)in->GetPlanePointer(2)};
  Ipp32s pSrcStep[3] = {in->GetPlanePitch(0),
                        in->GetPlanePitch(1),
                        in->GetPlanePitch(2)};
  Ipp8u *(pDst[3]) = {(Ipp8u*)out->GetPlanePointer(0),
                      (Ipp8u*)out->GetPlanePointer(1),
                      (Ipp8u*)out->GetPlanePointer(2)};
  Ipp32s pDstStep[3] = {out->GetPlanePitch(0),
                        out->GetPlanePitch(1),
                        out->GetPlanePitch(2)};
  if (bSrcSwapUV) {
    SwapValues(pSrc[1], pSrc[2]);
    SwapValues(pSrcStep[1], pSrcStep[2]);
  }
  if (bDstSwapUV) {
    SwapValues(pDst[1], pDst[2]);
    SwapValues(pDstStep[1], pDstStep[2]);
  }
  if (srcFormat == YUV422 && dstFormat != YUV420) { // 422->X as 420->X
    pSrcStep[1] *= 2;
    pSrcStep[2] *= 2;
    srcFormat = YUV420;
  }
  const Ipp8u *(pYVU[3]) = {pSrc[0], pSrc[2], pSrc[1]};
  Ipp32s pYVUStep[3] = {pSrcStep[0], pSrcStep[2], pSrcStep[1]};
  Ipp8u *(pDstYVU[3]) = {pDst[0], pDst[2], pDst[1]};
  Ipp32s pDstStepYVU[3] = {pDstStep[0], pDstStep[2], pDstStep[1]};
  IppStatus status;

  switch (srcFormat) {
  case YUV411:
    switch (dstFormat) {
    case YUV420:
      //status = ippiYCbCr411ToYCbCr420_8u_P3R(pSrc, pSrcStep, pDst, pDstStep, srcSize);
      status = cc_YUV411_to_YUV420(pSrc, pSrcStep, pDst, pDstStep, srcSize);
      break;
    default:
      return UMC_ERR_NOT_IMPLEMENTED;
    }
    break;
  case YUV420:
    switch (dstFormat) {
    case YUV411:
      status = ippiYCbCr420To411_8u_P3R(pSrc, pSrcStep, pDst, pDstStep, srcSize);
      break;
    case YUV422:
      status = ippiYCbCr420ToYCbCr422_8u_P3R(pSrc, pSrcStep, pDst, pDstStep, srcSize);
      break;
    case Y41P:
      status = cc_I420_to_Y41P(pYVU, pYVUStep, pDst[0], pDstStep[0], srcSize);
      break;
    case NV12:
      status = ippiYCrCb420ToYCbCr420_8u_P3P2R(pYVU, pYVUStep, pDst[0], pDstStep[0], pDst[1], pDstStep[1], srcSize);
      break;
    case YUY2:
      status = ippiYCrCb420ToYCbCr422_8u_P3C2R(pYVU, pYVUStep, pDst[0], pDstStep[0], srcSize);
      break;
    case UYVY:
      status = ippiYCrCb420ToCbYCr422_8u_P3C2R(pYVU, pYVUStep, pDst[0], pDstStep[0], srcSize);
      break;
    case RGB24:
      status = ippiYCbCr420ToBGR_8u_P3C3R(pSrc, pSrcStep, pDst[0], pDstStep[0], srcSize);
      break;
    case RGB32:
      status = ippiYCrCb420ToBGR_Filter_8u_P3C4R(pYVU, pYVUStep, pDst[0], pDstStep[0], srcSize, 0);
      break;
    case RGB565:
      status = ippiYCbCr420ToBGR565_8u16u_P3C3R(pSrc, pSrcStep, (Ipp16u*)pDst[0], pDstStep[0], srcSize);
      break;
    case RGB555:
      status = ippiYCbCr420ToBGR555_8u16u_P3C3R(pSrc, pSrcStep, (Ipp16u*)pDst[0], pDstStep[0], srcSize);
      break;
    case RGB444:
      status = ippiYCbCr420ToBGR444_8u16u_P3C3R(pSrc, pSrcStep, (Ipp16u*)pDst[0], pDstStep[0], srcSize);
      break;
    default:
      return UMC_ERR_NOT_IMPLEMENTED;
    }
    break;
  case YUV422:
  case YUV422A:
    switch (dstFormat) {
    case YUV420:
      status = ippiYCbCr422ToYCbCr420_8u_P3R(pSrc, pSrcStep, pDst, pDstStep, srcSize);
      break;
    case YUY2:
      status = ippiYCbCr422_8u_P3C2R(pSrc, pSrcStep, pDst[0], pDstStep[0], srcSize);
      break;
    default:
      return UMC_ERR_NOT_IMPLEMENTED;
    }
    break;
  case YUY2:
    switch (dstFormat) {
    case YUV420:
      status = ippiYCbCr422ToYCrCb420_8u_C2P3R(pSrc[0], pSrcStep[0], pDstYVU, pDstStepYVU, srcSize);
      break;
    case NV12:
      status = ippiYCbCr422ToYCbCr420_8u_C2P2R(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], pDst[1], pDstStep[1], srcSize);
      break;
    case UYVY:
      status = ippiYCbCr422ToCbYCr422_8u_C2R(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], srcSize);
      break;
    case YUV422:
      status = ippiYCrCb422ToYCbCr422_8u_C2P3R( pSrc[0], pSrcStep[0], pDst, pDstStep, srcSize);
      break;
    case RGB24:
      status = ippiYCbCr422ToBGR_8u_C2C3R(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], srcSize);
      break;
    case RGB32:
      status = ippiYCbCr422ToBGR_8u_C2C4R(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], srcSize, 0);
      break;
    case RGB565:
      status = ippiYCbCr422ToBGR565_8u16u_C2C3R(pSrc[0], pSrcStep[0], (Ipp16u*)pDst[0], pDstStep[0], srcSize);
      break;
    case RGB555:
      status = ippiYCbCr422ToBGR555_8u16u_C2C3R(pSrc[0], pSrcStep[0], (Ipp16u*)pDst[0], pDstStep[0], srcSize);
      break;
    case RGB444:
      status = ippiYCbCr422ToBGR444_8u16u_C2C3R(pSrc[0], pSrcStep[0], (Ipp16u*)pDst[0], pDstStep[0], srcSize);
      break;
    default:
      return UMC_ERR_NOT_IMPLEMENTED;
    }
    break;
  case UYVY:
    switch (dstFormat) {
    case YUV420:
      status = ippiCbYCr422ToYCrCb420_8u_C2P3R(pSrc[0], pSrcStep[0], pDstYVU, pDstStepYVU, srcSize);
      break;
    case NV12:
      status = ippiCbYCr422ToYCbCr420_8u_C2P2R(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], pDst[1], pDstStep[1], srcSize);
      break;
    case YUY2:
      status = ippiCbYCr422ToYCbCr422_8u_C2R(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], srcSize);
      break;
    case RGB32:
      status = ippiCbYCr422ToBGR_8u_C2C4R(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], srcSize, 0);
      break;
    case YUV422:
      status = ippiCbYCr422ToYCbCr422_8u_C2P3R( pSrc[0], pSrcStep[0], pDst, pDstStep, srcSize);
      break;
    default:
      return UMC_ERR_NOT_IMPLEMENTED;
    }
    break;
  case NV12:
    switch (dstFormat) {
    case YUV420:
      status = ippiYCbCr420_8u_P2P3R(pSrc[0], pSrcStep[0], pSrc[1], pSrcStep[1], pDst, pDstStep, srcSize);
      break;
    case UYVY:
      status = ippiYCbCr420ToCbYCr422_8u_P2C2R(pSrc[0], pSrcStep[0], pSrc[1], pSrcStep[1], pDst[0], pDstStep[0], srcSize);
      break;
    case YUY2:
      status = ippiYCbCr420ToYCbCr422_8u_P2C2R(pSrc[0], pSrcStep[0], pSrc[1], pSrcStep[1], pDst[0], pDstStep[0], srcSize);
      break;
    default:
      return UMC_ERR_NOT_IMPLEMENTED;
    }
    break;
  case RGB24:
    switch (dstFormat) {
    case YUV420:
      status = ippiBGRToYCrCb420_8u_C3P3R(pSrc[0], pSrcStep[0], pDstYVU, pDstStepYVU, srcSize);
      break;
    case YUY2:
      status = ippiBGRToYCbCr422_8u_C3C2R(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], srcSize);
      break;
    case RGB32:
      status = cc_BGRToBGRA(pSrc[0], pSrcStep[0], pDst[0], pDstStep[0], srcSize);
      break;
    default:
      return UMC_ERR_NOT_IMPLEMENTED;
    }
    break;
  case RGB32:
    switch (dstFormat) {
    case YUV420:

⌨️ 快捷键说明

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