#ifndef f_VD2_KASUMI_UBERBLIT_YCBCR_H #define f_VD2_KASUMI_UBERBLIT_YCBCR_H #include #include #include #include "uberblit.h" #include "uberblit_base.h" class VDPixmapGenYCbCrToRGBBase : public VDPixmapGenWindowBased { public: void Init(IVDPixmapGen *srcCr, uint32 srcindexCr, IVDPixmapGen *srcY, uint32 srcindexY, IVDPixmapGen *srcCb, uint32 srcindexCb) { mpSrcY = srcY; mSrcIndexY = srcindexY; mpSrcCb = srcCb; mSrcIndexCb = srcindexCb; mpSrcCr = srcCr; mSrcIndexCr = srcindexCr; mWidth = srcY->GetWidth(srcindexY); mHeight = srcY->GetHeight(srcindexY); srcY->AddWindowRequest(0, 0); srcCb->AddWindowRequest(0, 0); srcCr->AddWindowRequest(0, 0); } protected: IVDPixmapGen *mpSrcY; uint32 mSrcIndexY; IVDPixmapGen *mpSrcCb; uint32 mSrcIndexCb; IVDPixmapGen *mpSrcCr; uint32 mSrcIndexCr; }; class VDPixmapGenYCbCrToRGB32Base : public VDPixmapGenYCbCrToRGBBase { public: void Start() { mpSrcY->Start(); mpSrcCb->Start(); mpSrcCr->Start(); StartWindow(mWidth * 4); } }; class VDPixmapGenYCbCrToRGB32FBase : public VDPixmapGenYCbCrToRGBBase { public: void Start() { mpSrcY->Start(); mpSrcCb->Start(); mpSrcCr->Start(); StartWindow(mWidth * 16); } }; class VDPixmapGenRGB32ToYCbCrBase : public VDPixmapGenWindowBasedOneSource { public: void Init(IVDPixmapGen *src, uint32 srcindex) { InitSource(src, srcindex); } void Start() { StartWindow(mWidth, 3); } const void *GetRow(sint32 y, uint32 index) { return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index; } }; class VDPixmapGenRGB32FToYCbCrBase : public VDPixmapGenWindowBasedOneSource { public: void Init(IVDPixmapGen *src, uint32 srcindex) { InitSource(src, srcindex); } void Start() { StartWindow(mWidth * sizeof(float), 3); } const void *GetRow(sint32 y, uint32 index) { return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index; } }; /////////////////////////////////////////////////////////////////////////////////////////////////// // // Rec.601 converters // // -->Kr=0.299; Kb=0.114; Z=0; S=255; L = [Kr 1-Kr-Kb Kb]; Y = [219*(L-Z)/S 16]; U = [112*([0 0 1]-L)/((1-Kb)*S) 128]; V = // [112*([1 0 0]-L)/((1-Kr)*S) 128]; M = [Y; U; V; 0 0 0 1]; disp(M); disp(inv(M)); // // ! 0.2567882 0.5041294 0.0979059 16. ! // ! - 0.1482229 - 0.2909928 0.4392157 128. ! // ! 0.4392157 - 0.3677883 - 0.0714274 128. ! // ! 0. 0. 0. 1. ! // // ! 1.1643836 - 5.599D-17 1.5960268 - 222.92157 ! // ! 1.1643836 - 0.3917623 - 0.8129676 135.57529 ! // ! 1.1643836 2.0172321 - 1.110D-16 - 276.83585 ! // ! 0. 0. 0. 1. ! // /////////////////////////////////////////////////////////////////////////////////////////////////// class VDPixmapGenYCbCr601ToRGB32 : public VDPixmapGenYCbCrToRGB32Base { public: uint32 GetType(uint32 output) const { return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8888 | kVDPixSpace_BGR; } protected: virtual void Compute(void *dst0, sint32 y) { uint8 *dst = (uint8 *)dst0; const uint8 *srcY = (const uint8 *)mpSrcY->GetRow(y, mSrcIndexY); const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(y, mSrcIndexCb); const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(y, mSrcIndexCr); VDCPUCleanupExtensions(); for(sint32 i=0; iGetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32Fx4_LE | kVDPixSpace_BGR; } protected: void Compute(void *dst0, sint32 y) { float *dst = (float *)dst0; const float *srcY = (const float *)mpSrcY->GetRow(y, mSrcIndexY); const float *srcCb = (const float *)mpSrcCb->GetRow(y, mSrcIndexCb); const float *srcCr = (const float *)mpSrcCr->GetRow(y, mSrcIndexCr); VDCPUCleanupExtensions(); for(sint32 i=0; iGetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_601; } protected: void Compute(void *dst0, sint32 y) { uint8 *dstCr = (uint8 *)dst0; uint8 *dstY = dstCr + mWindowPitch; uint8 *dstCb = dstY + mWindowPitch; const uint8 *srcRGB = (const uint8 *)mpSrc->GetRow(y, mSrcIndex); for(sint32 i=0; iround(inv([1 0 0 0; 0 1 0 0; 0 0 1 0; -16 -128 -128 1] * [1.1643828 1.1643828 1.1643828 0; 1.5960273 -0.8129688 0 0; // 0 -0.3917617 2.0172305 0; 0 0 0 1]) .* 65536) // ans = // // ! 16829. 28784. - 9714. 0. ! // ! 33039. - 24103. - 19071. 0. ! // ! 6416. - 4681. 28784. 0. ! // ! 1048576. 8388608. 8388608. 65536. ! *dstCr++ = (28784*r - 24103*g - 4681*b + 8388608 + 32768) >> 16; *dstY ++ = (16829*r + 33039*g + 6416*b + 1048576 + 32768) >> 16; *dstCb++ = (-9714*r - 19071*g + 28784*b + 8388608 + 32768) >> 16; } } }; class VDPixmapGenRGB32FToYCbCr601 : public VDPixmapGenRGB32FToYCbCrBase { public: uint32 GetType(uint32 output) const { return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_601; } protected: void Compute(void *dst0, sint32 y) { float *dstCb = (float *)dst0; float *dstY = dstCb + mWindowPitch; float *dstCr = dstY + mWindowPitch; const float *srcRGB = (const float *)mpSrc->GetRow(y, mSrcIndex); VDCPUCleanupExtensions(); for(sint32 i=0; iKr=0.2126; Kb=0.0722; Z=0; S=255; L = [Kr 1-Kr-Kb Kb]; Y = [219*(L-Z)/S 16]; U = [112*([0 0 1]-L)/((1-Kb)*S) 128]; V // = [112*([1 0 0]-L)/((1-Kr)*S) 128]; M = [Y; U; V; 0 0 0 1]; disp(M); disp(inv(M)); // // ! 0.1825859 0.6142306 0.0620071 16. ! // ! - 0.1006437 - 0.3385720 0.4392157 128. ! // ! 0.4392157 - 0.3989422 - 0.0402735 128. ! // ! 0. 0. 0. 1. ! // // ! 1.1643836 - 2.932D-17 1.7927411 - 248.10099 ! // ! 1.1643836 - 0.2132486 - 0.5329093 76.87808 ! // ! 1.1643836 2.1124018 - 5.551D-17 - 289.01757 ! // ! 0. 0. 0. 1. ! // /////////////////////////////////////////////////////////////////////////////////////////////////// class VDPixmapGenYCbCr709ToRGB32 : public VDPixmapGenYCbCrToRGBBase { public: void Start() { mpSrcY->Start(); mpSrcCb->Start(); mpSrcCr->Start(); StartWindow(mWidth * 4); } uint32 GetType(uint32 output) const { return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8888 | kVDPixSpace_BGR; } protected: virtual void Compute(void *dst0, sint32 y) { uint8 *dst = (uint8 *)dst0; const uint8 *srcY = (const uint8 *)mpSrcY->GetRow(y, mSrcIndexY); const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(y, mSrcIndexCb); const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(y, mSrcIndexCr); VDCPUCleanupExtensions(); for(sint32 i=0; iStart(); mpSrcCb->Start(); mpSrcCr->Start(); StartWindow(mWidth * 16); } uint32 GetType(uint32 output) const { return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32Fx4_LE | kVDPixSpace_BGR; } protected: void Compute(void *dst0, sint32 y) { float *dst = (float *)dst0; const float *srcY = (const float *)mpSrcY->GetRow(y, mSrcIndexY); const float *srcCb = (const float *)mpSrcCb->GetRow(y, mSrcIndexCb); const float *srcCr = (const float *)mpSrcCr->GetRow(y, mSrcIndexCr); VDCPUCleanupExtensions(); for(sint32 i=0; iGetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_709; } protected: void Compute(void *dst0, sint32 y) { uint8 *dstCr = (uint8 *)dst0; uint8 *dstY = dstCr + mWindowPitch; uint8 *dstCb = dstY + mWindowPitch; const uint8 *srcRGB = (const uint8 *)mpSrc->GetRow(y, mSrcIndex); for(sint32 i=0; i> 16; *dstY ++ = (11966*r + 40254*g + 4064*b + 1048576 + 32768) >> 16; *dstCb++ = (-6596*r - 22189*g + 28784*b + 8388608 + 32768) >> 16; } } }; class VDPixmapGenRGB32FToYCbCr709 : public VDPixmapGenWindowBasedOneSource { public: void Init(IVDPixmapGen *src, uint32 srcindex) { InitSource(src, srcindex); } void Start() { StartWindow(mWidth * sizeof(float), 3); } const void *GetRow(sint32 y, uint32 index) { return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index; } uint32 GetType(uint32 output) const { return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_709; } protected: void Compute(void *dst0, sint32 y) { float *dstCr = (float *)dst0; float *dstY = dstCr + mWindowPitch; float *dstCb = dstY + mWindowPitch; const float *srcRGB = (const float *)mpSrc->GetRow(y, mSrcIndex); VDCPUCleanupExtensions(); for(sint32 i=0; i Rec.709 converters // // Rec.601 to Rec.709: // // 1. - 0.1155497 - 0.2079376 41.406386 // 0 1.0186397 0.1146180 - 17.056983 // 0 0.0750494 1.0253271 - 12.848195 // // Rec.709 to Rec.601: // // 1. 0.0993117 0.1916995 - 37.249435 // 0 0.9898538 - 0.1106525 15.462234 // 0 - 0.0724530 0.9833978 11.399058 // /////////////////////////////////////////////////////////////////////////////////////////////////// class VDPixmapGenYCbCr601ToYCbCr709 : public VDPixmapGenYCbCrToRGBBase { public: void Start() { mpSrcY->Start(); mpSrcCb->Start(); mpSrcCr->Start(); StartWindow(mWidth, 3); } const void *GetRow(sint32 y, uint32 index) { return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index; } uint32 GetType(uint32 output) const { return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_709; } protected: void Compute(void *dst0, sint32 ypos) { uint8 *dstCr = (uint8 *)dst0; uint8 *dstY = dstCr + mWindowPitch; uint8 *dstCb = dstY + mWindowPitch; const uint8 *srcY = (const uint8 *)mpSrcY->GetRow(ypos, mSrcIndexY); const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(ypos, mSrcIndexCb); const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(ypos, mSrcIndexCr); for(sint32 i=0; i> 16); *dstCb++ = (66758*cb + 7512*cr - 1117846 + 32768) >> 16; *dstCr++ = (4918*cb + 67196*cr - 842019 + 32768) >> 16; } } }; class VDPixmapGenYCbCr709ToYCbCr601 : public VDPixmapGenYCbCrToRGBBase { public: void Start() { mpSrcY->Start(); mpSrcCb->Start(); mpSrcCr->Start(); StartWindow(mWidth, 3); } const void *GetRow(sint32 y, uint32 index) { return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index; } uint32 GetType(uint32 output) const { return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_709; } protected: void Compute(void *dst0, sint32 ypos) { uint8 *dstCr = (uint8 *)dst0; uint8 *dstY = dstCr + mWindowPitch; uint8 *dstCb = dstY + mWindowPitch; const uint8 *srcY = (const uint8 *)mpSrcY->GetRow(ypos, mSrcIndexY); const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(ypos, mSrcIndexCb); const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(ypos, mSrcIndexCr); for(sint32 i=0; i> 16); *dstCb++ = (64871*cb - 7252*cr + 1013376 + 32768) >> 16; *dstCr++ = (-4748*cb + 64448*cr + 747008 + 32768) >> 16; } } }; class VDPixmapGenYCbCr601ToYCbCr709_32F : public VDPixmapGenYCbCrToRGBBase { public: void Start() { mpSrcY->Start(); mpSrcCb->Start(); mpSrcCr->Start(); StartWindow(mWidth * sizeof(float), 3); } const void *GetRow(sint32 y, uint32 index) { return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index; } uint32 GetType(uint32 output) const { return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_709; } protected: void Compute(void *dst0, sint32 ypos) { float *dstCr = (float *)dst0; float *dstY = vdptroffset(dstCr, mWindowPitch); float *dstCb = vdptroffset(dstY, mWindowPitch); const float *srcY = (const float *)mpSrcY->GetRow(ypos, mSrcIndexY); const float *srcCb = (const float *)mpSrcCb->GetRow(ypos, mSrcIndexCb); const float *srcCr = (const float *)mpSrcCr->GetRow(ypos, mSrcIndexCr); VDCPUCleanupExtensions(); for(sint32 i=0; iStart(); mpSrcCb->Start(); mpSrcCr->Start(); StartWindow(mWidth * sizeof(float), 3); } const void *GetRow(sint32 y, uint32 index) { return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index; } uint32 GetType(uint32 output) const { return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_709; } protected: void Compute(void *dst0, sint32 ypos) { float *dstCr = (float *)dst0; float *dstY = vdptroffset(dstCr, mWindowPitch); float *dstCb = vdptroffset(dstY, mWindowPitch); const float *srcY = (const float *)mpSrcY->GetRow(ypos, mSrcIndexY); const float *srcCb = (const float *)mpSrcCb->GetRow(ypos, mSrcIndexCb); const float *srcCr = (const float *)mpSrcCr->GetRow(ypos, mSrcIndexCr); VDCPUCleanupExtensions(); for(sint32 i=0; i