home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Kasumi / h / uberblit_ycbcr.h < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  17.6 KB  |  585 lines

  1. #ifndef f_VD2_KASUMI_UBERBLIT_YCBCR_H
  2. #define f_VD2_KASUMI_UBERBLIT_YCBCR_H
  3.  
  4. #include <vd2/system/cpuaccel.h>
  5. #include <vd2/system/math.h>
  6. #include <vd2/Kasumi/pixmaputils.h>
  7. #include "uberblit.h"
  8. #include "uberblit_base.h"
  9.  
  10. class VDPixmapGenYCbCrToRGBBase : public VDPixmapGenWindowBased {
  11. public:
  12.     void Init(IVDPixmapGen *srcCr, uint32 srcindexCr, IVDPixmapGen *srcY, uint32 srcindexY, IVDPixmapGen *srcCb, uint32 srcindexCb) {
  13.         mpSrcY = srcY;
  14.         mSrcIndexY = srcindexY;
  15.         mpSrcCb = srcCb;
  16.         mSrcIndexCb = srcindexCb;
  17.         mpSrcCr = srcCr;
  18.         mSrcIndexCr = srcindexCr;
  19.         mWidth = srcY->GetWidth(srcindexY);
  20.         mHeight = srcY->GetHeight(srcindexY);
  21.  
  22.         srcY->AddWindowRequest(0, 0);
  23.         srcCb->AddWindowRequest(0, 0);
  24.         srcCr->AddWindowRequest(0, 0);
  25.     }
  26.  
  27.  
  28. protected:
  29.     IVDPixmapGen *mpSrcY;
  30.     uint32 mSrcIndexY;
  31.     IVDPixmapGen *mpSrcCb;
  32.     uint32 mSrcIndexCb;
  33.     IVDPixmapGen *mpSrcCr;
  34.     uint32 mSrcIndexCr;
  35. };
  36.  
  37. ///////////////////////////////////////////////////////////////////////////////////////////////////
  38. //
  39. //    Rec.601 converters
  40. //
  41. //    -->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 =
  42. //    [112*([1 0 0]-L)/((1-Kr)*S) 128]; M = [Y; U; V; 0 0 0 1]; disp(M); disp(inv(M));
  43. //
  44. //    !   0.2567882    0.5041294    0.0979059    16.  !
  45. //    ! - 0.1482229  - 0.2909928    0.4392157    128. !
  46. //    !   0.4392157  - 0.3677883  - 0.0714274    128. !
  47. //    !   0.           0.           0.           1.   !
  48. //
  49. //    !   1.1643836  - 5.599D-17    1.5960268  - 222.92157 !
  50. //    !   1.1643836  - 0.3917623  - 0.8129676    135.57529 !
  51. //    !   1.1643836    2.0172321  - 1.110D-16  - 276.83585 !
  52. //    !   0.           0.           0.           1.        !
  53. //
  54. ///////////////////////////////////////////////////////////////////////////////////////////////////
  55.  
  56. class VDPixmapGenYCbCr601ToRGB32 : public VDPixmapGenYCbCrToRGBBase {
  57. public:
  58.     void Start() {
  59.         mpSrcY->Start();
  60.         mpSrcCb->Start();
  61.         mpSrcCr->Start();
  62.  
  63.         StartWindow(mWidth * 4);
  64.     }
  65.  
  66.     uint32 GetType(uint32 output) const {
  67.         return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8888 | kVDPixSpace_BGR;
  68.     }
  69.  
  70. protected:
  71.     virtual void Compute(void *dst0, sint32 y) {
  72.         uint8 *dst = (uint8 *)dst0;
  73.         const uint8 *srcY = (const uint8 *)mpSrcY->GetRow(y, mSrcIndexY);
  74.         const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(y, mSrcIndexCb);
  75.         const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(y, mSrcIndexCr);
  76.  
  77.         VDCPUCleanupExtensions();
  78.  
  79.         for(sint32 i=0; i<mWidth; ++i) {
  80.             sint32 y = srcY[i];
  81.             sint32 cb = srcCb[i];
  82.             sint32 cr = srcCr[i];
  83.  
  84.             float yf = (1.164f / 255.0f)*(y - 16);
  85.  
  86.             dst[0] = VDClampedRoundFixedToUint8Fast(yf + (2.018f / 255.0f) * (cb - 128));
  87.             dst[1] = VDClampedRoundFixedToUint8Fast(yf - (0.813f / 255.0f) * (cr - 128) - (0.391f / 255.0f) * (cb - 128));
  88.             dst[2] = VDClampedRoundFixedToUint8Fast(yf + (1.596f / 255.0f) * (cr - 128));
  89.             dst[3] = 0xff;
  90.  
  91.             dst += 4;
  92.         }
  93.     }
  94. };
  95.  
  96. class VDPixmapGenYCbCr601ToRGB32F : public VDPixmapGenYCbCrToRGBBase {
  97. public:
  98.     void Start() {
  99.         mpSrcY->Start();
  100.         mpSrcCb->Start();
  101.         mpSrcCr->Start();
  102.  
  103.         StartWindow(mWidth * 16);
  104.     }
  105.  
  106.     uint32 GetType(uint32 output) const {
  107.         return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32Fx4_LE | kVDPixSpace_BGR;
  108.     }
  109.  
  110. protected:
  111.     void Compute(void *dst0, sint32 y) {
  112.         float *dst = (float *)dst0;
  113.         const float *srcY = (const float *)mpSrcY->GetRow(y, mSrcIndexY);
  114.         const float *srcCb = (const float *)mpSrcCb->GetRow(y, mSrcIndexCb);
  115.         const float *srcCr = (const float *)mpSrcCr->GetRow(y, mSrcIndexCr);
  116.  
  117.         VDCPUCleanupExtensions();
  118.  
  119.         for(sint32 i=0; i<mWidth; ++i) {
  120.             float y = srcY[i];
  121.             float cb = srcCb[i] - (128.0f / 255.0f);
  122.             float cr = srcCr[i] - (128.0f / 255.0f);
  123.  
  124.             float yf = 1.164f * (y - 16.0f / 255.0f);
  125.  
  126.             dst[0] = yf + 1.596f * cr;
  127.             dst[1] = yf - 0.813f * cr - 0.391f * cb;
  128.             dst[2] = yf + 2.018f * cb;
  129.             dst[3] = 1.0f;
  130.             dst += 4;
  131.         }
  132.     }
  133. };
  134.  
  135. class VDPixmapGenRGB32ToYCbCr601 : public VDPixmapGenWindowBasedOneSource {
  136. public:
  137.     void Init(IVDPixmapGen *src, uint32 srcindex) {
  138.         InitSource(src, srcindex);
  139.     }
  140.  
  141.     void Start() {
  142.         StartWindow(mWidth, 3);
  143.     }
  144.  
  145.     const void *GetRow(sint32 y, uint32 index) {
  146.         return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index;
  147.     }
  148.  
  149.     uint32 GetType(uint32 output) const {
  150.         return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_601;
  151.     }
  152.  
  153. protected:
  154.     void Compute(void *dst0, sint32 y) {
  155.         uint8 *dstCb = (uint8 *)dst0;
  156.         uint8 *dstY = dstCb + mWindowPitch;
  157.         uint8 *dstCr = dstY + mWindowPitch;
  158.  
  159.         const uint8 *srcRGB = (const uint8 *)mpSrc->GetRow(y, mSrcIndex);
  160.  
  161.         for(sint32 i=0; i<mWidth; ++i) {
  162.             int r = (int)srcRGB[2];
  163.             int g = (int)srcRGB[1];
  164.             int b = (int)srcRGB[0];
  165.             srcRGB += 4;            
  166.  
  167.  
  168.             // -2->round(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;
  169.             //  0 -0.3917617 2.0172305 0; 0 0 0 1]) .* 65536)
  170.             // ans  =
  171.             // 
  172.             // !   16829.      28784.    - 9714.       0.     !
  173.             // !   33039.    - 24103.    - 19071.      0.     !
  174.             // !   6416.     - 4681.       28784.      0.     !
  175.             // !   1048576.    8388608.    8388608.    65536. !   
  176.  
  177.             *dstCb++ = (28784*r - 24103*g -  4681*b + 8388608 + 32768) >> 16;
  178.             *dstY ++ = (16829*r + 33039*g +  6416*b + 1048576 + 32768) >> 16;
  179.             *dstCr++ = (-9714*r - 19071*g + 28784*b + 8388608 + 32768) >> 16;
  180.         }
  181.     }
  182. };
  183.  
  184. class VDPixmapGenRGB32FToYCbCr601 : public VDPixmapGenWindowBasedOneSource {
  185. public:
  186.     void Init(IVDPixmapGen *src, uint32 srcindex) {
  187.         InitSource(src, srcindex);
  188.     }
  189.  
  190.     void Start() {
  191.         StartWindow(mWidth * sizeof(float), 3);
  192.     }
  193.  
  194.     const void *GetRow(sint32 y, uint32 index) {
  195.         return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index;
  196.     }
  197.  
  198.     uint32 GetType(uint32 output) const {
  199.         return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_709;
  200.     }
  201.  
  202. protected:
  203.     void Compute(void *dst0, sint32 y) {
  204.         float *dstCb = (float *)dst0;
  205.         float *dstY  = dstCb + mWindowPitch;
  206.         float *dstCr = dstY + mWindowPitch;
  207.  
  208.         const float *srcRGB = (const float *)mpSrc->GetRow(y, mSrcIndex);
  209.  
  210.         for(sint32 i=0; i<mWidth; ++i) {
  211.             float r = srcRGB[2];
  212.             float g = srcRGB[1];
  213.             float b = srcRGB[0];
  214.             srcRGB += 4;            
  215.  
  216.             *dstCb++ = -0.1482229f*r - 0.2909928f*g + 0.4392157f*b + (128.0f / 255.0f);
  217.             *dstY++  =  0.2567882f*r + 0.5041294f*g + 0.0979059f*b + ( 16.0f / 255.0f);
  218.             *dstCr++ =  0.4392157f*r - 0.3677883f*g - 0.0714274f*b + (128.0f / 255.0f);
  219.         }
  220.     }
  221. };
  222.  
  223. ///////////////////////////////////////////////////////////////////////////////////////////////////
  224. //
  225. //    Rec.709 converters
  226. //
  227. //
  228. //    -->Kr=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
  229. //    = [112*([1 0 0]-L)/((1-Kr)*S) 128]; M = [Y; U; V; 0 0 0 1]; disp(M); disp(inv(M));
  230. //
  231. //    !   0.1825859    0.6142306    0.0620071    16.  !
  232. //    ! - 0.1006437  - 0.3385720    0.4392157    128. !
  233. //    !   0.4392157  - 0.3989422  - 0.0402735    128. !
  234. //    !   0.           0.           0.           1.   !
  235. //
  236. //    !   1.1643836  - 2.932D-17    1.7927411  - 248.10099 !
  237. //    !   1.1643836  - 0.2132486  - 0.5329093    76.87808  !
  238. //    !   1.1643836    2.1124018  - 5.551D-17  - 289.01757 !
  239. //    !   0.           0.           0.           1.        !                     
  240. //
  241. ///////////////////////////////////////////////////////////////////////////////////////////////////
  242.  
  243. class VDPixmapGenYCbCr709ToRGB32 : public VDPixmapGenYCbCrToRGBBase {
  244. public:
  245.     void Start() {
  246.         mpSrcY->Start();
  247.         mpSrcCb->Start();
  248.         mpSrcCr->Start();
  249.  
  250.         StartWindow(mWidth * 4);
  251.     }
  252.  
  253.     uint32 GetType(uint32 output) const {
  254.         return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8888 | kVDPixSpace_BGR;
  255.     }
  256.  
  257. protected:
  258.     virtual void Compute(void *dst0, sint32 y) {
  259.         uint8 *dst = (uint8 *)dst0;
  260.         const uint8 *srcY = (const uint8 *)mpSrcY->GetRow(y, mSrcIndexY);
  261.         const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(y, mSrcIndexCb);
  262.         const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(y, mSrcIndexCr);
  263.  
  264.         VDCPUCleanupExtensions();
  265.  
  266.         for(sint32 i=0; i<mWidth; ++i) {
  267.             sint32 y = srcY[i];
  268.             sint32 cb = srcCb[i];
  269.             sint32 cr = srcCr[i];
  270.  
  271.             float yf = (1.164f / 255.0f)*(y - 16);
  272.  
  273.             dst[0] = VDClampedRoundFixedToUint8Fast(yf + (2.112f / 255.0f) * (cb - 128));
  274.             dst[1] = VDClampedRoundFixedToUint8Fast(yf - (0.533f / 255.0f) * (cr - 128) - (0.213f / 255.0f) * (cb - 128));
  275.             dst[2] = VDClampedRoundFixedToUint8Fast(yf + (1.793f / 255.0f) * (cr - 128));
  276.             dst[3] = 0xff;
  277.  
  278.             dst += 4;
  279.         }
  280.     }
  281. };
  282.  
  283. class VDPixmapGenYCbCr709ToRGB32F : public VDPixmapGenYCbCrToRGBBase {
  284. public:
  285.     void Start() {
  286.         mpSrcY->Start();
  287.         mpSrcCb->Start();
  288.         mpSrcCr->Start();
  289.  
  290.         StartWindow(mWidth * 16);
  291.     }
  292.  
  293.     uint32 GetType(uint32 output) const {
  294.         return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32Fx4_LE | kVDPixSpace_BGR;
  295.     }
  296.  
  297. protected:
  298.     void Compute(void *dst0, sint32 y) {
  299.         float *dst = (float *)dst0;
  300.         const float *srcY = (const float *)mpSrcY->GetRow(y, mSrcIndexY);
  301.         const float *srcCb = (const float *)mpSrcCb->GetRow(y, mSrcIndexCb);
  302.         const float *srcCr = (const float *)mpSrcCr->GetRow(y, mSrcIndexCr);
  303.  
  304.         VDCPUCleanupExtensions();
  305.  
  306.         for(sint32 i=0; i<mWidth; ++i) {
  307.             float y = srcY[i];
  308.             float cb = srcCb[i] - (128.0f/255.0f);
  309.             float cr = srcCr[i] - (128.0f/255.0f);
  310.  
  311.             float yf = 1.164f * (y - 16.0f / 255.0f);
  312.  
  313.             dst[0] = yf + 1.793f * cr;
  314.             dst[1] = yf - 0.533f * cr - 0.213f * cb;
  315.             dst[2] = yf + 2.112f * cb;
  316.             dst[3] = 1.0f;
  317.             dst += 4;
  318.         }
  319.     }
  320. };
  321.  
  322. class VDPixmapGenRGB32ToYCbCr709 : public VDPixmapGenWindowBasedOneSource {
  323. public:
  324.     void Init(IVDPixmapGen *src, uint32 srcindex) {
  325.         InitSource(src, srcindex);
  326.     }
  327.  
  328.     void Start() {
  329.         StartWindow(mWidth, 3);
  330.     }
  331.  
  332.     const void *GetRow(sint32 y, uint32 index) {
  333.         return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index;
  334.     }
  335.  
  336.     uint32 GetType(uint32 output) const {
  337.         return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_709;
  338.     }
  339.  
  340. protected:
  341.     void Compute(void *dst0, sint32 y) {
  342.         uint8 *dstCb = (uint8 *)dst0;
  343.         uint8 *dstY = dstCb + mWindowPitch;
  344.         uint8 *dstCr = dstY + mWindowPitch;
  345.  
  346.         const uint8 *srcRGB = (const uint8 *)mpSrc->GetRow(y, mSrcIndex);
  347.  
  348.         for(sint32 i=0; i<mWidth; ++i) {
  349.             int r = (int)srcRGB[2];
  350.             int g = (int)srcRGB[1];
  351.             int b = (int)srcRGB[0];
  352.             srcRGB += 4;            
  353.  
  354.             *dstCb++ = (28784*r - 26145*g -  2639*b + 8388608 + 32768) >> 16;
  355.             *dstY ++ = (11966*r + 40254*g +  4064*b + 1048576 + 32768) >> 16;
  356.             *dstCr++ = (-6596*r - 22189*g + 28784*b + 8388608 + 32768) >> 16;
  357.         }
  358.     }
  359. };
  360.  
  361. class VDPixmapGenRGB32FToYCbCr709 : public VDPixmapGenWindowBasedOneSource {
  362. public:
  363.     void Init(IVDPixmapGen *src, uint32 srcindex) {
  364.         InitSource(src, srcindex);
  365.     }
  366.  
  367.     void Start() {
  368.         StartWindow(mWidth * sizeof(float), 3);
  369.     }
  370.  
  371.     const void *GetRow(sint32 y, uint32 index) {
  372.         return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index;
  373.     }
  374.  
  375.     uint32 GetType(uint32 output) const {
  376.         return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_709;
  377.     }
  378.  
  379. protected:
  380.     void Compute(void *dst0, sint32 y) {
  381.         float *dstCb = (float *)dst0;
  382.         float *dstY  = dstCb + mWindowPitch;
  383.         float *dstCr = dstY + mWindowPitch;
  384.  
  385.         const float *srcRGB = (const float *)mpSrc->GetRow(y, mSrcIndex);
  386.  
  387.         VDCPUCleanupExtensions();
  388.  
  389.         for(sint32 i=0; i<mWidth; ++i) {
  390.             float r = srcRGB[2];
  391.             float g = srcRGB[1];
  392.             float b = srcRGB[0];
  393.             srcRGB += 4;            
  394.  
  395.             *dstCb++ = -0.1006437f*r - 0.3385720f*g + 0.4392157f*b + (128.0f / 255.0f);
  396.             *dstY++  =  0.1825859f*r + 0.6142306f*g + 0.0620071f*b + ( 16.0f / 255.0f);
  397.             *dstCr++ =  0.4392157f*r - 0.3989422f*g - 0.0402735f*b + (128.0f / 255.0f);
  398.         }
  399.     }
  400. };
  401.  
  402. ///////////////////////////////////////////////////////////////////////////////////////////////////
  403. //
  404. //    Rec.601 <-> Rec.709 converters
  405. //
  406. //    Rec.601 to Rec.709:
  407. //
  408. //    1.  - 0.1155497  - 0.2079376    41.406386
  409. //    0     1.0186397    0.1146180  - 17.056983
  410. //    0     0.0750494    1.0253271  - 12.848195
  411. //
  412. //    Rec.709 to Rec.601:
  413. //
  414. //    1.    0.0993117    0.1916995  - 37.249435
  415. //    0     0.9898538  - 0.1106525    15.462234
  416. //    0   - 0.0724530    0.9833978    11.399058
  417. //
  418. ///////////////////////////////////////////////////////////////////////////////////////////////////
  419.  
  420. class VDPixmapGenYCbCr601ToYCbCr709 : public VDPixmapGenYCbCrToRGBBase {
  421. public:
  422.     void Start() {
  423.         mpSrcY->Start();
  424.         mpSrcCb->Start();
  425.         mpSrcCr->Start();
  426.  
  427.         StartWindow(mWidth, 3);
  428.     }
  429.  
  430.     const void *GetRow(sint32 y, uint32 index) {
  431.         return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index;
  432.     }
  433.  
  434.     uint32 GetType(uint32 output) const {
  435.         return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_709;
  436.     }
  437.  
  438. protected:
  439.     void Compute(void *dst0, sint32 ypos) {
  440.         uint8 *dstCr = (uint8 *)dst0;
  441.         uint8 *dstY  = dstCr + mWindowPitch;
  442.         uint8 *dstCb = dstY + mWindowPitch;
  443.  
  444.         const uint8 *srcY  = (const uint8 *)mpSrcY->GetRow(ypos, mSrcIndexY);
  445.         const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(ypos, mSrcIndexCb);
  446.         const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(ypos, mSrcIndexCr);
  447.  
  448.         for(sint32 i=0; i<mWidth; ++i) {
  449.             sint32 y = srcY[i];
  450.             sint32 cb = srcCb[i];
  451.             sint32 cr = srcCr[i];
  452.  
  453.             *dstY++  = y + ((-7573*cb - 13627*cr + 2713609 + 32768) >> 16);
  454.             *dstCb++ = (66758*cb + 7512*cr - 1117846 + 32768) >> 16;
  455.             *dstCr++ = (4918*cb + 67196*cr - 842019 + 32768) >> 16;
  456.         }
  457.     }
  458. };
  459.  
  460. class VDPixmapGenYCbCr709ToYCbCr601 : public VDPixmapGenYCbCrToRGBBase {
  461. public:
  462.     void Start() {
  463.         mpSrcY->Start();
  464.         mpSrcCb->Start();
  465.         mpSrcCr->Start();
  466.  
  467.         StartWindow(mWidth, 3);
  468.     }
  469.  
  470.     const void *GetRow(sint32 y, uint32 index) {
  471.         return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index;
  472.     }
  473.  
  474.     uint32 GetType(uint32 output) const {
  475.         return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_709;
  476.     }
  477.  
  478. protected:
  479.     void Compute(void *dst0, sint32 ypos) {
  480.         uint8 *dstCr = (uint8 *)dst0;
  481.         uint8 *dstY  = dstCr + mWindowPitch;
  482.         uint8 *dstCb = dstY + mWindowPitch;
  483.  
  484.         const uint8 *srcY  = (const uint8 *)mpSrcY->GetRow(ypos, mSrcIndexY);
  485.         const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(ypos, mSrcIndexCb);
  486.         const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(ypos, mSrcIndexCr);
  487.  
  488.         for(sint32 i=0; i<mWidth; ++i) {
  489.             sint32 y = srcY[i];
  490.             sint32 cb = srcCb[i];
  491.             sint32 cr = srcCr[i];
  492.  
  493.             *dstY++  = y + ((6508*cb + 12563*cr - 2441088 + 32768) >> 16);
  494.             *dstCb++ = (64871*cb - 7252*cr + 1013376 + 32768) >> 16;
  495.             *dstCr++ = (-4748*cb + 64448*cr + 747008 + 32768) >> 16;
  496.         }
  497.     }
  498. };
  499.  
  500. class VDPixmapGenYCbCr601ToYCbCr709_32F : public VDPixmapGenYCbCrToRGBBase {
  501. public:
  502.     void Start() {
  503.         mpSrcY->Start();
  504.         mpSrcCb->Start();
  505.         mpSrcCr->Start();
  506.  
  507.         StartWindow(mWidth * sizeof(float), 3);
  508.     }
  509.  
  510.     const void *GetRow(sint32 y, uint32 index) {
  511.         return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index;
  512.     }
  513.  
  514.     uint32 GetType(uint32 output) const {
  515.         return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_709;
  516.     }
  517.  
  518. protected:
  519.     void Compute(void *dst0, sint32 ypos) {
  520.         float *dstCr = (float *)dst0;
  521.         float *dstY  = vdptroffset(dstCr, mWindowPitch);
  522.         float *dstCb = vdptroffset(dstY, mWindowPitch);
  523.  
  524.         const float *srcY  = (const float *)mpSrcY->GetRow(ypos, mSrcIndexY);
  525.         const float *srcCb = (const float *)mpSrcCb->GetRow(ypos, mSrcIndexCb);
  526.         const float *srcCr = (const float *)mpSrcCr->GetRow(ypos, mSrcIndexCr);
  527.  
  528.         VDCPUCleanupExtensions();
  529.  
  530.         for(sint32 i=0; i<mWidth; ++i) {
  531.             float y = srcY[i];
  532.             float cb = srcCb[i] - (128.0f / 255.0f);
  533.             float cr = srcCr[i] - (128.0f / 255.0f);
  534.  
  535.             *dstY++ = y - 0.1155497f*cb - 0.2079376f*cr;
  536.             *dstCb++ = 1.0186397f*cb + 0.1146180f*cr + (128.0f / 255.0f);
  537.             *dstCr++ = 0.0750494f*cb + 1.0253271f*cr + (128.0f / 255.0f);
  538.         }
  539.     }
  540. };
  541.  
  542. class VDPixmapGenYCbCr709ToYCbCr601_32F : public VDPixmapGenYCbCrToRGBBase {
  543. public:
  544.     void Start() {
  545.         mpSrcY->Start();
  546.         mpSrcCb->Start();
  547.         mpSrcCr->Start();
  548.  
  549.         StartWindow(mWidth * sizeof(float), 3);
  550.     }
  551.  
  552.     const void *GetRow(sint32 y, uint32 index) {
  553.         return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index;
  554.     }
  555.  
  556.     uint32 GetType(uint32 output) const {
  557.         return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_709;
  558.     }
  559.  
  560. protected:
  561.     void Compute(void *dst0, sint32 ypos) {
  562.         float *dstCr = (float *)dst0;
  563.         float *dstY  = vdptroffset(dstCr, mWindowPitch);
  564.         float *dstCb = vdptroffset(dstY, mWindowPitch);
  565.  
  566.         const float *srcY  = (const float *)mpSrcY->GetRow(ypos, mSrcIndexY);
  567.         const float *srcCb = (const float *)mpSrcCb->GetRow(ypos, mSrcIndexCb);
  568.         const float *srcCr = (const float *)mpSrcCr->GetRow(ypos, mSrcIndexCr);
  569.  
  570.         VDCPUCleanupExtensions();
  571.  
  572.         for(sint32 i=0; i<mWidth; ++i) {
  573.             float y = srcY[i];
  574.             float cb = srcCb[i] - (128.0f / 255.0f);
  575.             float cr = srcCr[i] - (128.0f / 255.0f);
  576.  
  577.             *dstY++  = y - 0.1155497f*cb - 0.2079376f*cr;
  578.             *dstCb++ =     0.9898538f*cb - 0.1106525f*cr + (128.0f / 255.0f);
  579.             *dstCr++ =   - 0.0724530f*cb + 0.9833978f*cr + (128.0f / 255.0f);
  580.         }
  581.     }
  582. };
  583.  
  584. #endif
  585.