📄 umc_color_space_conversion.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_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 + -