home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2004 March / PCWELT_3_2004.ISO / pcwsoft / flaskmpeg_078_39_src.z.exe / flaskmpeg / FrameSource.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-28  |  46.5 KB  |  1,560 lines

  1. /* 
  2.  *  FrameSource.cpp
  3.  *
  4.  *    Copyright (C) Alberto Vigata - July 2000 - ultraflask@yahoo.com
  5.  *
  6.  *  This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
  7.  *    
  8.  *  FlasKMPEG is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2, or (at your option)
  11.  *  any later version.
  12.  *   
  13.  *  FlasKMPEG is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *   
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with GNU Make; see the file COPYING.  If not, write to
  20.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  21.  *
  22.  */
  23.  
  24. #include <emmintrin.h>
  25. #include "FrameSource.h"
  26. #include "flmemcpy.h"
  27. #include "debug.h"
  28.  
  29. // SSE2 Global consts
  30. static _MM_ALIGN16 const __int64 xmmmask_0001[2] = {  0x0001000100010001,  0x0001000100010001 };
  31. static _MM_ALIGN16 const __int64 xmmmask_0002[2] = {  0x0002000200020002,  0x0002000200020002 };
  32. static _MM_ALIGN16 const __int64 xmmmask_0003[2] = {  0x0003000300030003,  0x0003000300030003 };
  33. static _MM_ALIGN16 const __int64 xmmmask_0004[2] = {  0x0004000400040004,  0x0004000400040004 };
  34. static _MM_ALIGN16 const __int64 xmmmask_0005[2] = {  0x0005000500050005,  0x0005000500050005 };
  35. static _MM_ALIGN16 const __int64 xmmmask_0007[2] = {  0x0007000700070007,  0x0007000700070007 };
  36. static _MM_ALIGN16 const __int64 xmmmask_0016[2] = {  0x0010001000100010,  0x0010001000100010 };
  37. static _MM_ALIGN16 const __int64 xmmmask_0040[2] = {  0x0040004000400040,  0x0040004000400040 };
  38. static _MM_ALIGN16 const __int64 xmmmask_0128[2] = {  0x0080008000800080,  0x0080008000800080 };
  39. static _MM_ALIGN16 const __int64 xmmmask_cbu[2] = {  0x0000408D0000408D,  0x0000408D0000408D };
  40. static _MM_ALIGN16 const __int64 xmmmask_cgu_cgv[2] = {  0xF377E5FCF377E5FC,  0xF377E5FCF377E5FC };
  41. static _MM_ALIGN16 const __int64 xmmmask_crv[2] = {  0x0000331300003313,  0x0000331300003313 };
  42. static _MM_ALIGN16 const __int64 xYUVRGB_Scale[2] = {  0x1000254310002543,  0x1000254310002543 };
  43.  
  44. // MMX Global consts
  45. static _MM_ALIGN16 const __int64 mmmask_0001 = 0x0001000100010001;
  46. static _MM_ALIGN16 const __int64 mmmask_0002 = 0x0002000200020002;
  47. static _MM_ALIGN16 const __int64 mmmask_0003 = 0x0003000300030003;
  48. static _MM_ALIGN16 const __int64 mmmask_0004 = 0x0004000400040004;
  49. static _MM_ALIGN16 const __int64 mmmask_0005 = 0x0005000500050005;
  50. static _MM_ALIGN16 const __int64 mmmask_0007 = 0x0007000700070007;
  51. static _MM_ALIGN16 const __int64 mmmask_0016 = 0x0010001000100010;
  52. static _MM_ALIGN16 const __int64 mmmask_0040 = 0x0040004000400040;
  53. static _MM_ALIGN16 const __int64 mmmask_0128 = 0x0080008000800080;
  54. static _MM_ALIGN16 const __int64 mmmask_cbu = 0x0000408D0000408D;
  55. static _MM_ALIGN16 const __int64 mmmask_cgu_cgv = 0xF377E5FCF377E5FC;
  56. static _MM_ALIGN16 const __int64 mmmask_crv = 0x0000331300003313;
  57. static _MM_ALIGN16 const __int64 YUVRGB_Scale = 0x1000254310002543;
  58.  
  59.  
  60. void From420to422(unsigned char *src, unsigned char *dst, int width, int height, int frame_type)
  61. {
  62.  
  63.     int hwidth    = width / 2;
  64.     int dwidth    = width * 2;
  65.     int hheightd2 = height / 2 - 2;
  66.     int qheightd2 = height / 4 - 2;
  67.     
  68.     if (frame_type)
  69.     {
  70.       __asm
  71.       {
  72.         mov            eax, [src]
  73.           mov            ebx, [dst]
  74.           mov            ecx, ebx
  75.           add            ecx, [hwidth]
  76.           mov            esi, 0x00
  77.           movq        mm3, [mmmask_0003]
  78.           pxor        mm0, mm0
  79.           movq        mm4, [mmmask_0002]
  80.           
  81.           mov            edx, eax
  82.           add            edx, [hwidth]
  83. convyuv422topp:
  84.            movd        mm1, [eax+esi]
  85.           movd        mm2, [edx+esi]
  86.           movd        [ebx+esi], mm1
  87.           punpcklbw    mm1, mm0
  88.           pmullw        mm1, mm3
  89.           paddusw        mm1, mm4
  90.           punpcklbw    mm2, mm0
  91.           paddusw        mm2, mm1
  92.           psrlw        mm2, 0x02
  93.           packuswb    mm2, mm0
  94.           
  95.           add            esi, 0x04
  96.           cmp            esi, [hwidth]
  97.           movd        [ecx+esi-4], mm2
  98.           jl            convyuv422topp
  99.           
  100.           add            eax, [hwidth]
  101.           add            ebx, [width]
  102.           add            ecx, [width]
  103.           mov            esi, 0x00
  104.           
  105.           mov            edi, [hheightd2]
  106. convyuv422p:
  107.           movd        mm1, [eax+esi]
  108.           
  109.           punpcklbw    mm1, mm0
  110.           mov            edx, eax
  111.           
  112.           pmullw        mm1, mm3
  113.           sub            edx, [hwidth]
  114.           
  115.           movd        mm5, [edx+esi]
  116.           movd        mm2, [edx+esi]
  117.           
  118.           punpcklbw    mm5, mm0
  119.           punpcklbw    mm2, mm0
  120.           paddusw        mm5, mm1
  121.           paddusw        mm2, mm1
  122.           paddusw        mm5, mm4
  123.           paddusw        mm2, mm4
  124.           psrlw        mm5, 0x02
  125.           psrlw        mm2, 0x02
  126.           packuswb    mm5, mm0
  127.           packuswb    mm2, mm0
  128.           
  129.           mov            edx, eax
  130.           add            edx, [hwidth]
  131.           add            esi, 0x04
  132.           cmp            esi, [hwidth]
  133.           movd        [ebx+esi-4], mm5
  134.           movd        [ecx+esi-4], mm2
  135.           
  136.           jl            convyuv422p
  137.           
  138.           add            eax, [hwidth]
  139.           add            ebx, [width]
  140.           add            ecx, [width]
  141.           mov            esi, 0x00
  142.           sub            edi, 0x01
  143.           cmp            edi, 0x00
  144.           jg            convyuv422p
  145.           
  146.           mov            edx, eax
  147.           sub            edx, [hwidth]
  148. convyuv422bottomp:
  149.         movd        mm1, [eax+esi]
  150.           movd        mm5, [edx+esi]
  151.           punpcklbw    mm5, mm0
  152.           movd        [ecx+esi], mm1
  153.           
  154.           punpcklbw    mm1, mm0
  155.           pmullw        mm1, mm3
  156.           paddusw        mm5, mm1
  157.           paddusw        mm5, mm4
  158.           psrlw        mm5, 0x02
  159.           packuswb    mm5, mm0
  160.           
  161.           add            esi, 0x04
  162.           cmp            esi, [hwidth]
  163.           movd        [ebx+esi-4], mm5
  164.           jl            convyuv422bottomp
  165.           
  166.           emms
  167.       }
  168.     }
  169.     else
  170.     {
  171.       __asm
  172.       {
  173.         mov            eax, [src]
  174.           mov            ecx, [dst]
  175.           mov            esi, 0x00
  176.           pxor        mm0, mm0
  177.           movq        mm3, [mmmask_0003]
  178.           movq        mm4, [mmmask_0004]
  179.           movq        mm5, [mmmask_0005]
  180.           
  181. convyuv422topi:
  182.         movd        mm1, [eax+esi]
  183.           mov            ebx, eax
  184.           add            ebx, [hwidth]
  185.           movd        mm2, [ebx+esi]
  186.           movd        [ecx+esi], mm1
  187.           punpcklbw    mm1, mm0
  188.           movq        mm6, mm1
  189.           pmullw        mm1, mm3
  190.           
  191.           punpcklbw    mm2, mm0
  192.           movq        mm7, mm2
  193.           pmullw        mm2, mm5
  194.           paddusw        mm2, mm1
  195.           paddusw        mm2, mm4
  196.           psrlw        mm2, 0x03
  197.           packuswb    mm2, mm0
  198.           
  199.           mov            edx, ecx
  200.           add            edx, [hwidth]
  201.           pmullw        mm6, mm5
  202.           movd        [edx+esi], mm2
  203.           
  204.           add            ebx, [hwidth]
  205.           movd        mm2, [ebx+esi]
  206.           punpcklbw    mm2, mm0
  207.           pmullw        mm2, mm3
  208.           paddusw        mm2, mm6
  209.           paddusw        mm2, mm4
  210.           psrlw        mm2, 0x03
  211.           packuswb    mm2, mm0
  212.           
  213.           add            edx, [hwidth]
  214.           add            ebx, [hwidth]
  215.           pmullw        mm7, [mmmask_0007]
  216.           movd        [edx+esi], mm2
  217.           
  218.           movd        mm2, [ebx+esi]
  219.           punpcklbw    mm2, mm0
  220.           paddusw        mm2, mm7
  221.           paddusw        mm2, mm4
  222.           psrlw        mm2, 0x03
  223.           packuswb    mm2, mm0
  224.           
  225.           add            edx, [hwidth]
  226.           add            esi, 0x04
  227.           cmp            esi, [hwidth]
  228.           movd        [edx+esi-4], mm2
  229.           
  230.           jl            convyuv422topi
  231.           
  232.           add            eax, [width]
  233.           add            ecx, [dwidth]
  234.           mov            esi, 0x00
  235.           
  236.           mov            edi, [qheightd2]
  237. convyuv422i:
  238.         movd        mm1, [eax+esi]
  239.           punpcklbw    mm1, mm0
  240.           movq        mm6, mm1
  241.           mov            ebx, eax
  242.           sub            ebx, [width]
  243.           movd        mm3, [ebx+esi]
  244.           pmullw        mm1, [mmmask_0007]
  245.           punpcklbw    mm3, mm0
  246.           paddusw        mm3, mm1
  247.           paddusw        mm3, mm4
  248.           psrlw        mm3, 0x03
  249.           packuswb    mm3, mm0
  250.           
  251.           add            ebx, [hwidth]
  252.           movq        mm1, [ebx+esi]
  253.           add            ebx, [width]
  254.           movd        [ecx+esi], mm3
  255.           
  256.           movq        mm3, [mmmask_0003]
  257.           movd        mm2, [ebx+esi]
  258.           
  259.           punpcklbw    mm1, mm0
  260.           pmullw        mm1, mm3
  261.           punpcklbw    mm2, mm0
  262.           movq        mm7, mm2
  263.           pmullw        mm2, mm5
  264.           paddusw        mm2, mm1
  265.           paddusw        mm2, mm4
  266.           psrlw        mm2, 0x03
  267.           packuswb    mm2, mm0
  268.           
  269.           pmullw        mm6, mm5
  270.           mov            edx, ecx
  271.           add            edx, [hwidth]
  272.           movd        [edx+esi], mm2
  273.           
  274.           add            ebx, [hwidth]
  275.           movd        mm2, [ebx+esi]
  276.           punpcklbw    mm2, mm0
  277.           pmullw        mm2, mm3
  278.           paddusw        mm2, mm6
  279.           paddusw        mm2, mm4
  280.           psrlw        mm2, 0x03
  281.           packuswb    mm2, mm0
  282.           
  283.           pmullw        mm7, [mmmask_0007]
  284.           add            edx, [hwidth]
  285.           add            ebx, [hwidth]
  286.           movd        [edx+esi], mm2
  287.           
  288.           movd        mm2, [ebx+esi]
  289.           punpcklbw    mm2, mm0
  290.           paddusw        mm2, mm7
  291.           paddusw        mm2, mm4
  292.           psrlw        mm2, 0x03
  293.           packuswb    mm2, mm0
  294.           
  295.           add            edx, [hwidth]
  296.           add            esi, 0x04
  297.           cmp            esi, [hwidth]
  298.           movd        [edx+esi-4], mm2
  299.           
  300.           jl            convyuv422i
  301.           add            eax, [width]
  302.           add            ecx, [dwidth]
  303.           mov            esi, 0x00
  304.           sub            edi, 0x01
  305.           cmp            edi, 0x00
  306.           jg            convyuv422i
  307.           
  308. convyuv422bottomi:
  309.         movd        mm1, [eax+esi]
  310.           movq        mm6, mm1
  311.           punpcklbw    mm1, mm0
  312.           mov            ebx, eax
  313.           sub            ebx, [width]
  314.           movd        mm3, [ebx+esi]
  315.           punpcklbw    mm3, mm0
  316.           pmullw        mm1, [mmmask_0007]
  317.           paddusw        mm3, mm1
  318.           paddusw        mm3, mm4
  319.           psrlw        mm3, 0x03
  320.           packuswb    mm3, mm0
  321.           
  322.           add            ebx, [hwidth]
  323.           movq        mm1, [ebx+esi]
  324.           punpcklbw    mm1, mm0
  325.           movd        [ecx+esi], mm3
  326.           
  327.           pmullw        mm1, [mmmask_0003]
  328.           add            ebx, [width]
  329.           movd        mm2, [ebx+esi]
  330.           punpcklbw    mm2, mm0
  331.           movq        mm7, mm2
  332.           pmullw        mm2, mm5
  333.           paddusw        mm2, mm1
  334.           paddusw        mm2, mm4
  335.           psrlw        mm2, 0x03
  336.           packuswb    mm2, mm0
  337.           
  338.           mov            edx, ecx
  339.           add            edx, [hwidth]
  340.           pmullw        mm7, [mmmask_0007]
  341.           movd        [edx+esi], mm2
  342.           
  343.           add            edx, [hwidth]
  344.           movd        [edx+esi], mm6
  345.           
  346.           punpcklbw    mm6, mm0
  347.           paddusw        mm6, mm7
  348.           paddusw        mm6, mm4
  349.           psrlw        mm6, 0x03
  350.           packuswb    mm6, mm0
  351.           
  352.           add            edx, [hwidth]
  353.           add            esi, 0x04
  354.           cmp            esi, [hwidth]
  355.           movd        [edx+esi-4], mm6
  356.           
  357.           jl            convyuv422bottomi
  358.           
  359.           emms
  360.       }
  361.     }
  362.   }
  363.  
  364. void From422to444(unsigned char *src, unsigned char *dst, int width, int height)
  365. {
  366.     int hwidthd8 = width / 2 - 8;
  367.     int hwidth    = width / 2;
  368.  
  369.     __asm
  370.     {
  371.       mov            eax, [src]
  372.         mov            ebx, [dst]
  373.         mov            edi, [height]
  374.         
  375.         movq        mm1, [mmmask_0001]
  376.         pxor        mm0, mm0
  377.         
  378. convyuv444init:
  379.       movq        mm7, [eax]
  380.         mov            esi, 0x00
  381.         
  382. convyuv444:
  383.       movq        mm2, mm7
  384.         movq        mm7, [eax+esi+8]
  385.         movq        mm3, mm2
  386.         movq        mm4, mm7
  387.         
  388.         psrlq        mm3, 8
  389.         psllq        mm4, 56
  390.         por            mm3, mm4
  391.         
  392.         movq        mm4, mm2
  393.         movq        mm5, mm3
  394.         
  395.         punpcklbw    mm4, mm0
  396.         punpcklbw    mm5, mm0
  397.         
  398.         movq        mm6, mm4
  399.         paddusw        mm4, mm1
  400.         paddusw        mm4, mm5
  401.         psrlw        mm4, 1
  402.         psllq        mm4, 8
  403.         por            mm4, mm6
  404.         
  405.         punpckhbw    mm2, mm0
  406.         punpckhbw    mm3, mm0
  407.         
  408.         movq        mm6, mm2
  409.         paddusw        mm2, mm1
  410.         paddusw        mm2, mm3
  411.         
  412.         movq        [ebx+esi*2], mm4
  413.         
  414.         psrlw        mm2, 1
  415.         psllq        mm2, 8
  416.         por            mm2, mm6
  417.         
  418.         add            esi, 0x08
  419.         cmp            esi, [hwidthd8]
  420.         movq        [ebx+esi*2-8], mm2
  421.         jl            convyuv444
  422.         
  423.         movq        mm2, mm7
  424.         punpcklbw    mm2, mm0
  425.         movq        mm3, mm2
  426.         
  427.         psllq        mm2, 8
  428.         por            mm2, mm3
  429.         
  430.         movq        [ebx+esi*2], mm2
  431.         
  432.         punpckhbw    mm7, mm0
  433.         movq        mm6, mm7
  434.         
  435.         psllq        mm6, 8
  436.         por            mm6, mm7
  437.         
  438.         movq        [ebx+esi*2+8], mm6
  439.         
  440.         add            eax, [hwidth]        
  441.         add            ebx, [width]
  442.         sub            edi, 0x01
  443.         cmp            edi, 0x00
  444.         jg            convyuv444init
  445.         
  446.         emms
  447.     }
  448.   }
  449.  
  450. static inline void From422toYUY2odd(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst, int width, int height)
  451. {
  452.     int dwidth    = width * 2;
  453.     int qwidth    = width * 4;
  454.     int hwidth    = width / 2;
  455.     __asm
  456.     {
  457.       mov            eax, [py]
  458.         mov            ebx, [pu]
  459.         mov            ecx, [pv]
  460.         mov            edx, [dst]
  461.         mov            esi, 0x00
  462.         mov            edi, [height]
  463.         
  464. yuy2conv:
  465.       movd        mm2, [ebx+esi]
  466.         movd        mm3, [ecx+esi]
  467.         punpcklbw    mm2, mm3
  468.         movq        mm1, [eax+esi*2]
  469.         movq        mm4, mm1
  470.         punpcklbw    mm1, mm2
  471.         punpckhbw    mm4, mm2
  472.         
  473.         add            esi, 0x04
  474.         cmp            esi, [hwidth]
  475.         movq        [edx+esi*4-16], mm1
  476.         movq        [edx+esi*4-8], mm4
  477.         jl            yuy2conv
  478.         
  479.         add            eax, [dwidth]
  480.         add            ebx, [width]
  481.         add            ecx, [width]
  482.         add            edx, [qwidth]
  483.         sub            edi, 0x02
  484.         mov            esi, 0x00
  485.         cmp            edi, 0x00
  486.         jg            yuy2conv
  487.         
  488.         emms
  489.     }    
  490.   }
  491.   
  492. static inline void From422toYUY2even(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst, int width, int height)
  493. {
  494.     int hwidth    = width / 2;
  495.     int dwidth    = width * 2;
  496.     int qwidth    = width * 4;
  497.     py += width; pu += hwidth; pv += hwidth; dst += dwidth;
  498.     
  499.     __asm
  500.     {
  501.       mov            eax, [py]
  502.         mov            ebx, [pu]
  503.         mov            ecx, [pv]
  504.         mov            edx, [dst]
  505.         mov            esi, 0x00
  506.         mov            edi, [height]
  507.         
  508. yuy2conv:
  509.       movd        mm2, [ebx+esi]
  510.         movd        mm3, [ecx+esi]
  511.         punpcklbw    mm2, mm3
  512.         movq        mm1, [eax+esi*2]
  513.         movq        mm4, mm1
  514.         punpcklbw    mm1, mm2
  515.         punpckhbw    mm4, mm2
  516.         
  517.         add            esi, 0x04
  518.         cmp            esi, [hwidth]
  519.         movq        [edx+esi*4-16], mm1
  520.         movq        [edx+esi*4-8], mm4
  521.         jl            yuy2conv
  522.         
  523.         add            eax, [dwidth]
  524.         add            ebx, [width]
  525.         add            ecx, [width]
  526.         add            edx, [qwidth]
  527.         sub            edi, 0x02
  528.         mov            esi, 0x00
  529.         cmp            edi, 0x00
  530.         jg            yuy2conv
  531.         
  532.         emms
  533.     }
  534.   }
  535.  
  536. #if 1
  537. //-----------------------------------------------------------------------------
  538. // From RGB32
  539. //-----------------------------------------------------------------------------
  540. // YUV impacts from RGB
  541. #define Y(x) (  (66*((x)>>16)  +  129*(((x)&0xFF00)>>8)  +  25*((x)&0xFF))/256 + 16 )
  542. #define U(x) ( (112*((x)>>16)  -   94*(((x)&0xFF00)>>8)  -  18*((x)&0xFF))/256 + 128 )
  543. #define V(x) ( (-38*((x)>>16)  -   75*(((x)&0xFF00)>>8)  + 112*((x)&0xFF))/256 + 128 )
  544. static inline void FromRGB32toYV12(Pixel32* src, Pixel8 *dst, int w, int h)
  545. {
  546.   int row, col, a, b, c, d;
  547.   int srcpitch = w * 4;
  548.   int dstpitch = w;
  549.   int hw = w>>1;
  550.   int hh = h>>1;
  551.   
  552.   int cralign = 0;
  553.  
  554.   Pixel8 *YPtr1, *YPtr2, *UPtr, *VPtr;
  555.  
  556.  
  557.   YPtr1 = dst;
  558.   YPtr2 = YPtr1 + dstpitch;
  559.  
  560.   UPtr = dst + w * h;
  561.   VPtr = dst + w * h + hw * hh;
  562.  
  563.   // The routines computes
  564.   // the chroma values by averaging
  565.   // the 4 neibours
  566.  
  567.   for(row = 0; row<hh; row++ )
  568.   {
  569.     for(col=0; col<hw; col++)
  570.     {
  571.       a = *src;
  572.       *YPtr1++ = Y(a);
  573.  
  574.       b = *(src+1);
  575.       *YPtr1++ = Y(b);
  576.  
  577.       c = *(src + w);
  578.       *YPtr2++ = Y(c);
  579.  
  580.       d = *(src + w + 1);
  581.  
  582.       src+= 2;
  583.  
  584.       *YPtr2++ = Y(d);
  585.  
  586.       *UPtr++ = (U(a) + U(b) + U(c) + U(d))>>2;
  587.       *VPtr++ = (V(a) + V(b) + V(c) + V(d))>>2;
  588.     }
  589.     src += w;
  590.     UPtr += cralign;
  591.     VPtr += cralign;
  592.     YPtr1 += dstpitch;
  593.     YPtr2 += dstpitch;
  594.   }
  595. }
  596. #endif 
  597.  
  598. static inline void From420toYV12(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst, int width, int height)
  599. {
  600.   int hwidth    = width >>1;
  601.   int hlfheight    = height >>1;
  602.   int dest_addr = 0, src_addr = 0;
  603.   int size = height * width;
  604.   int hsize = hlfheight * hwidth;
  605.   
  606.   // Y plane
  607.   flmemcpy( dst, py, size );
  608.     
  609.   // U & V planes
  610.   for ( int j=0; j< hlfheight; j++ ) // convert U & V planes
  611.   {
  612.       src_addr = j * hwidth;
  613.       dest_addr = size + src_addr;
  614.       
  615.       flmemcpy(  dst + dest_addr, pv + src_addr, hwidth);
  616.       
  617.       dest_addr += hsize;
  618.       
  619.       flmemcpy(  dst + dest_addr, pu + src_addr, hwidth );
  620.       
  621.     } // endfor j
  622. }
  623.  
  624.  
  625. static inline void FromYV12toYV12int(int top, unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst, int width, int height)
  626. {
  627.   int hwidth    = width >>1;
  628.   int hlfheight    = height >>1;
  629.   int dest_addr = 0, src_addr = 0;
  630.   int size = height * width;
  631.   int hsize = hlfheight * hwidth;
  632.   int start_row = top ? 0 : 1;
  633.  
  634.         for (int j=start_row; j<height ; j+=2 )  // convert y-plane
  635.       flmemcpy( dst + j*width, py + j*width, width);
  636.     
  637.     for ( j=start_row; j< hlfheight; j+=2 ) // convert U & V planes
  638.     {
  639.       src_addr = j * hwidth;
  640.       dest_addr = size + src_addr;
  641.       
  642.       flmemcpy(  dst + dest_addr, pv + src_addr, hwidth);
  643.       
  644.       dest_addr += hsize;
  645.       
  646.       flmemcpy(  dst + dest_addr, pu + src_addr, hwidth );
  647.       
  648.     } // endfor j
  649. }
  650.  
  651.  
  652. static inline void From444toRGB32odd(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst,int width, int height)
  653. {
  654.     dst += width * (height-2) * 4;
  655.     py += width; pu += width; pv += width;
  656.   int nwidth = width * 12;
  657.   int dwidth    = width * 2;
  658.  
  659.     __asm
  660.     {
  661.         mov            eax, [py]
  662.         mov            ebx, [pu]
  663.         mov            ecx, [pv]
  664.         mov            edx, [dst]
  665.         mov            edi, [height]
  666.         mov            esi, 0x00
  667.         pxor        mm0, mm0
  668.  
  669. convRGB24:
  670.         movd        mm1, [eax+esi]       ;mm1: [00][00][00][00][ y][ y][ y][ y]
  671.         movd        mm3, [ebx+esi]       ;mm3: [00][00][00][00][ u][ u][ u][ u]
  672.     punpcklbw    mm1, mm0           ;mm1: [00][ y][00][ y][00][ y][00][ y]
  673.     punpcklbw    mm3, mm0           ;mm3: [00][ u][00][ u][00][ u][00][ u]
  674.     movd        mm5, [ecx+esi]       ;mm5: [00][00][00][00][ v][ v][ v][ v]
  675.         punpcklbw    mm5, mm0           ;mm5: [00][ v][00][ v][00][ v][00][ v]
  676.     movq        mm7, [mmmask_0128]   ;mm7: [  -128][  -128][  -128][  -128]
  677.     psubw        mm3, mm7             ;mm3: [ u-128][ u-128][ u-128][ u-128]
  678.     psubw        mm5, mm7             ;mm5: [ v-128][ v-128][ v-128][ v-128]
  679.  
  680.     psubw        mm1, [mmmask_0016]   ;mm1: [ y-16 ][ y-16 ][ y-16 ][ y-16 ]
  681.     movq        mm2, mm1             ;mm2: [ y-16 ][ y-16 ][ y-16 ][ y-16 ]
  682.     movq        mm7, [mmmask_0001]   ;mm7: [0001][0001][0001][0001]
  683.     punpcklwd    mm1, mm7           ;mm1: [0001][ y-16 ][0001][ y-16 ]
  684.     punpckhwd    mm2, mm7           ;mm2: [0001][ y-16 ][0001][ y-16 ]
  685.     movq        mm7, [YUVRGB_Scale]  ;mm7: [1000][2000][1000][2000]
  686.     pmaddwd        mm1, mm7           ;mm1: [         y][         y]
  687.         pmaddwd        mm2, mm7           ;mm2: [         y][         y]
  688.  
  689.     movq        mm4, mm3             ;mm4: [ u-128][ u-128][ u-128][ u-128]
  690.     punpcklwd    mm3, mm0           ;mm3: [ 0000 ][ u-128][ 0000 ][ u-128]
  691.     punpckhwd    mm4, mm0           ;mm4: [ 0000 ][ u-128][ 0000 ][ u-128]
  692.     movq        mm7, [mmmask_cbu]    ;mm7: [0000][408D][0000][408D]
  693.     pmaddwd        mm3, mm7           ;mm3: [ mult u       ][ mult u       ]
  694.         pmaddwd        mm4, mm7           ;mm4: [ mult u       ][ mult u       ]
  695.     paddd        mm3, mm1             ;mm3: [ mult u +y    ][ mult u +y    ]
  696.     paddd        mm4, mm2             ;mm4: [ mult u +y    ][ mult u +y    ]
  697.         psrld        mm3, 13
  698.         psrld        mm4, 13
  699.     packuswb    mm3, mm0           ;mm3: [00][00][00][00][00][ b][00][ b]
  700.     packuswb    mm4, mm0           ;mm4: [00][00][00][00][00][ b][00][ b]
  701.  
  702.     movq        mm6, mm5             ;mm6: [ v-128][ v-128][ v-128][ v-128]
  703.         punpcklwd    mm5, mm0
  704.         punpckhwd    mm6, mm0
  705.         movq        mm7, [mmmask_crv]
  706.         pmaddwd        mm5, mm7
  707.         pmaddwd        mm6, mm7
  708.         paddd        mm5, mm1
  709.         paddd        mm6, mm2
  710.         psrld        mm5, 13
  711.         psrld        mm6, 13
  712.         packuswb    mm5, mm0         ; mm5: [00][00][00][00][00][ r][00][ r]
  713.         packuswb    mm6, mm0         ; mm6: [00][00][00][00][00][ r][00][ r]
  714.  
  715.         punpcklbw    mm3, mm5         ; mm3: [00][00][ r][ b][ 0][ 0][ r][ b]
  716.         punpcklbw    mm4, mm6         ; mm4: [00][00][ r][ b][ 0][ 0][ r][ b]
  717.     movq        mm5, mm3           ; mm5: [00][00][ r][ b][ 0][ 0][ r][ b]
  718.     movq        mm6, mm4           ; mm6: [00][00][ r][ b][ 0][ 0][ r][ b]
  719.     psrlq        mm5, 16            ; mm5: [ r][ b][ 0][ 0][ r][ b][ 0][ 0]
  720.         psrlq        mm6, 16            ; mm6: [ r][ b][ 0][ 0][ r][ b][ 0][ 0]
  721.         por            mm3, mm5           ; mm3: [ r][ b][ r][ b][ r][ b][ r][ b]
  722.         por            mm4, mm6           ; mm4: [ r][ b][ r][ b][ r][ b][ r][ b]
  723.  
  724.     movd        mm5, [ebx+esi]     ; mm5: [00][00][00][00][ u][ u][ u][ u]
  725.         movd        mm6, [ecx+esi]     ; mm6: [00][00][00][00][ v][ v][ v][ v]
  726.     punpcklbw    mm5, mm0         ; mm5: [00][ u][00][ u][00][ u][00][ u]
  727.         punpcklbw    mm6, mm0         ; mm6: [00][ v][00][ v][00][ v][00][ v]
  728.     movq        mm7, [mmmask_0128] ; mm7: [00  80][00  80][00  80][00  80]
  729.     psubw        mm5, mm7           ; mm5: [u - 80][u - 80][u - 80][u - 80]
  730.     psubw        mm6, mm7           ; mm6: [v - 80][v - 80][v - 80][v - 80]
  731.  
  732.     movq        mm7, mm6           ; mm7: [v - 80][v - 80][v - 80][v - 80]
  733.     punpcklwd    mm6, mm5         ; mm6: [u - 80][v - 80][u - 80][v - 80]
  734.     punpckhwd    mm7, mm5             ; mm7: [u - 80][v - 80][u - 80][v - 80]
  735.     movq        mm5, [mmmask_cgu_cgv] ;mm5: [F377][E5FC][F377][E5FC]
  736.     pmaddwd        mm6, mm5         ; mm6: [ madd uv      ][  madd uv     ]
  737.         pmaddwd        mm7, mm5         ; mm7: [ madd uv      ][  madd uv     ]
  738.     paddd        mm6, mm1           ; mm6: [ madd uv+y    ][ madd uv+y    ]
  739.         paddd        mm7, mm2           ; mm6: [ madd uv+y    ][ madd uv+y    ]
  740.  
  741.         psrld        mm6, 13            ; mm6: [0000][   g][0000][   g]
  742.         psrld        mm7, 13            ; mm7: [0000][   g][0000][   g]
  743.     packuswb    mm6, mm0         ; mm6: [00][00][00][00][ g][ 0][ g]
  744.         packuswb    mm7, mm0         ; mm7: [00][00][00][00][ g][ 0][ g]
  745.  
  746.     punpcklbw    mm3, mm6         ; mm3: [ 0][ r][ g][ b][ 0][ r][ g][ b]
  747.         punpcklbw    mm4, mm7         ; mm4: [ 0][ r][ g][ b][ 0][ r][ g][ b]
  748.  
  749.     movq [edx],   mm3
  750.     movq [edx+8], mm4
  751.  
  752.         add            edx, 0x10
  753.         add            esi, 0x04
  754.         cmp            esi, [width]
  755.  
  756.         jl            convRGB24
  757.  
  758.         add            eax, [dwidth]
  759.         add            ebx, [dwidth]
  760.         add            ecx, [dwidth]
  761.         sub            edx, [nwidth]
  762.         mov            esi, 0x00
  763.         sub            edi, 0x02
  764.         cmp            edi, 0x00
  765.         jg            convRGB24
  766.  
  767.         emms
  768.     }
  769. }
  770.  
  771. static inline void From444toRGB32even(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst, int width, int height)
  772. {
  773.     dst += width * (height-1) * 4;
  774.   int nwidth  = width * 12;
  775.   int dwidth  = width * 2;
  776.     __asm
  777.     {
  778.         mov            eax, [py]
  779.         mov            ebx, [pu]
  780.         mov            ecx, [pv]
  781.         mov            edx, [dst]
  782.         mov            edi, [height]
  783.         mov            esi, 0x00
  784.         pxor        mm0, mm0
  785.  
  786. convRGB24:
  787.         movd        mm1, [eax+esi]
  788.         movd        mm3, [ebx+esi]
  789.         punpcklbw    mm1, mm0
  790.         punpcklbw    mm3, mm0
  791.         movd        mm5, [ecx+esi]
  792.         punpcklbw    mm5, mm0
  793.         movq        mm7, [mmmask_0128]
  794.         psubw        mm3, mm7
  795.         psubw        mm5, mm7
  796.  
  797.         psubw        mm1, [mmmask_0016]
  798.         movq        mm2, mm1
  799.         movq        mm7, [mmmask_0001]
  800.         punpcklwd    mm1, mm7
  801.         punpckhwd    mm2, mm7
  802.         movq        mm7, [YUVRGB_Scale]
  803.         pmaddwd        mm1, mm7
  804.         pmaddwd        mm2, mm7
  805.  
  806.         movq        mm4, mm3
  807.         punpcklwd    mm3, mm0
  808.         punpckhwd    mm4, mm0
  809.         movq        mm7, [mmmask_cbu]
  810.         pmaddwd        mm3, mm7
  811.         pmaddwd        mm4, mm7
  812.         paddd        mm3, mm1
  813.         paddd        mm4, mm2
  814.         psrld        mm3, 13
  815.         psrld        mm4, 13
  816.         packuswb    mm3, mm0
  817.         packuswb    mm4, mm0
  818.  
  819.         movq        mm6, mm5
  820.         punpcklwd    mm5, mm0
  821.         punpckhwd    mm6, mm0
  822.         movq        mm7, [mmmask_crv]
  823.         pmaddwd        mm5, mm7
  824.         pmaddwd        mm6, mm7
  825.         paddd        mm5, mm1
  826.         paddd        mm6, mm2
  827.  
  828.         psrld        mm5, 13
  829.         psrld        mm6, 13
  830.         packuswb    mm5, mm0
  831.         packuswb    mm6, mm0
  832.  
  833.         punpcklbw    mm3, mm5
  834.         punpcklbw    mm4, mm6
  835.         movq        mm5, mm3
  836.         movq        mm6, mm4
  837.         psrlq        mm5, 16
  838.         psrlq        mm6, 16
  839.         por            mm3, mm5
  840.         por            mm4, mm6
  841.  
  842.         movd        mm5, [ebx+esi]
  843.         movd        mm6, [ecx+esi]
  844.         punpcklbw    mm5, mm0
  845.         punpcklbw    mm6, mm0
  846.         movq        mm7, [mmmask_0128]
  847.         psubw        mm5, mm7
  848.         psubw        mm6, mm7
  849.  
  850.         movq        mm7, mm6
  851.         punpcklwd    mm6, mm5
  852.         punpckhwd    mm7, mm5        
  853.         movq        mm5, [mmmask_cgu_cgv]
  854.         pmaddwd        mm6, mm5
  855.         pmaddwd        mm7, mm5
  856.         paddd        mm6, mm1
  857.         paddd        mm7, mm2
  858.  
  859.         psrld        mm6, 13
  860.         psrld        mm7, 13
  861.         packuswb    mm6, mm0
  862.         packuswb    mm7, mm0
  863.  
  864.         punpcklbw    mm3, mm6
  865.         punpcklbw    mm4, mm7
  866.  
  867.     movq [edx],   mm3
  868.     movq [edx+8], mm4
  869.  
  870.         add            edx, 0x10
  871.         add            esi, 0x04
  872.         cmp            esi, [width]
  873.  
  874.         jl            convRGB24
  875.  
  876.         add            eax, [dwidth]
  877.         add            ebx, [dwidth]
  878.         add            ecx, [dwidth]
  879.         sub            edx, [nwidth]
  880.         mov            esi, 0x00
  881.         sub            edi, 0x02
  882.         cmp            edi, 0x00
  883.         jg            convRGB24
  884.  
  885.         emms
  886.     }
  887. }
  888.  
  889. #if 0
  890. // SSE2 full frame version
  891. static inline void From444toRGB32_SSE2(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst,int width, int height)
  892. {
  893.     dst += width * (height-1) * 4;
  894.   int nwidth  = width * 2 * 4;
  895.  
  896.   int wcorr0x10 = (width & 0x7)? 0x10 : 0x00;
  897.  
  898.     __asm
  899.     {
  900.         mov            eax, [py]
  901.         mov            ebx, [pu]
  902.         mov            ecx, [pv]
  903.         mov            edx, [dst]
  904. //        mov            edi, [height]
  905.         xor            esi, esi
  906.         pxor        xmm0, xmm0
  907.  
  908.         lea            edi, [esp - 32]
  909.         and            edi, ~0xf
  910.  
  911. convRGB24:
  912.         movq        xmm1, [eax+esi]       ;xmm1: [00][00][00][00][00][00][00][00][ y][ y][ y][ y][ y][ y][ y][ y]
  913.         movq        xmm3, [ebx+esi]       ;xmm3: [00][00][00][00][00][00][00][00][ u][ u][ u][ u][ u][ u][ u][ u]
  914.     punpcklbw    xmm1, xmm0           ;xmm1: [00][ y][00][ y][00][ y][00][ y][00][ y][00][ y][00][ y][00][ y]
  915.     punpcklbw    xmm3, xmm0           ;xmm3: [00][ u][00][ u][00][ u][00][ u][00][ u][00][ u][00][ u][00][ u]
  916.     movq        xmm5, [ecx+esi]       ;xmm5: [00][00][00][00][00][00][00][00][ v][ v][ v][ v][ v][ v][ v][ v]
  917.         punpcklbw    xmm5, xmm0           ;xmm5: [00][ v][00][ v][00][ v][00][ v][00][ v][00][ v][00][ v][00][ v]
  918.     movdqa        xmm7, [xmmmask_0128]   ;xmm7: [  +128][  +128][  +128][  +128][  +128][  +128][  +128][  +128]
  919.     psubw        xmm3, xmm7             ;xmm3: [ u-128][ u-128][ u-128][ u-128][ u-128][ u-128][ u-128][ u-128]
  920.     psubw        xmm5, xmm7             ;xmm5: [ v-128][ v-128][ v-128][ v-128][ v-128][ v-128][ v-128][ v-128]
  921.     movdqa        [edi], xmm3
  922.     movdqa        [edi + 16], xmm5
  923.  
  924.     psubw        xmm1, [xmmmask_0016]   ;xmm1: [ y-16 ][ y-16 ][ y-16 ][ y-16 ][ y-16 ][ y-16 ][ y-16 ][ y-16 ]
  925.     movq        xmm2, xmm1             ;xmm2: [ y-16 ][ y-16 ][ y-16 ][ y-16 ][ y-16 ][ y-16 ][ y-16 ][ y-16 ]
  926.     movdqa        xmm7, [xmmmask_0001]   ;xmm7: [0001][0001][0001][0001][0001][0001][0001][0001]
  927.     punpcklwd    xmm2, xmm7           ;xmm1: [0001][ y-16 ][0001][ y-16 ][0001][ y-16 ][0001][ y-16 ]
  928.     punpckhwd    xmm1, xmm7           ;xmm2: [0001][ y-16 ][0001][ y-16 ][0001][ y-16 ][0001][ y-16 ]
  929.     movdqa        xmm7, [xYUVRGB_Scale]  ;xmm7: [1000][2000][1000][2000][1000][2000][1000][2000]
  930.     pmaddwd        xmm2, xmm7           ;xmm2: [         y][         y][         y][         y]
  931.         pmaddwd        xmm1, xmm7           ;xmm1: [         y][         y][         y][         y]
  932.  
  933.     movq        xmm4, xmm3             ;xmm4: [ u-128][ u-128][ u-128][ u-128][ u-128][ u-128][ u-128][ u-128]
  934.     punpckhwd    xmm3, xmm0           ;xmm3: [ 0000 ][ u-128][ 0000 ][ u-128][ 0000 ][ u-128][ 0000 ][ u-128]
  935.     punpcklwd    xmm4, xmm0           ;xmm4: [ 0000 ][ u-128][ 0000 ][ u-128][ 0000 ][ u-128][ 0000 ][ u-128]
  936.     movdqa        xmm7, [xmmmask_cbu]    ;xmm7: [0000][408D][0000][408D][0000][408D][0000][408D]
  937.     pmaddwd        xmm4, xmm7           ;xmm4: [ mult u       ][ mult u       ][ mult u       ][ mult u       ]
  938.         pmaddwd        xmm3, xmm7           ;xmm3: [ mult u       ][ mult u       ][ mult u       ][ mult u       ]
  939.     paddd        xmm4, xmm2             ;xmm4: [ mult u +y    ][ mult u +y    ][ mult u +y    ][ mult u +y    ]
  940.     paddd        xmm3, xmm1             ;xmm3: [ mult u +y    ][ mult u +y    ][ mult u +y    ][ mult u +y    ]
  941.         psrld        xmm4, 13
  942.         psrld        xmm3, 13
  943.     packuswb    xmm4, xmm3           ;xmm4: [00][ b][00][ b][00][ b][00][ b][00][ b][00][ b][00][ b][00][ b]
  944.  
  945.     movq        xmm6, xmm5             ;xmm6: [ v-128][ v-128][ v-128][ v-128][ v-128][ v-128][ v-128][ v-128]
  946.         punpckhwd    xmm5, xmm0
  947.         punpcklwd    xmm6, xmm0
  948.         movdqa        xmm7, [xmmmask_crv]
  949.         pmaddwd        xmm6, xmm7
  950.         pmaddwd        xmm5, xmm7
  951.         paddd        xmm6, xmm2
  952.         paddd        xmm5, xmm1
  953.         psrld        xmm6, 13
  954.         psrld        xmm5, 13
  955.         packuswb    xmm6, xmm5         ; xmm6: [00][ r][00][ r][00][ r][00][ r][00][ r][00][ r][00][ r][00][ r]
  956.  
  957.     movdqa        xmm7, [edi + 16] // v...
  958.     movdqa        xmm3, [edi] // u...
  959.     movq        xmm5, xmm7
  960.     punpckhwd    xmm7, xmm3             ; xmm7: [u - 80][v - 80][u - 80][v - 80][u - 80][v - 80][u - 80][v - 80]
  961.     punpcklwd    xmm5, xmm3         ; xmm5: [u - 80][v - 80][u - 80][v - 80][u - 80][v - 80][u - 80][v - 80]
  962.  
  963.     movdqa        xmm3, [xmmmask_cgu_cgv] ;xmm6: [F377][E5FC][F377][E5FC][F377][E5FC][F377][E5FC]
  964.     pmaddwd        xmm5, xmm3         ; xmm5: [ madd uv      ][  madd uv     ][ madd uv      ][  madd uv     ]
  965.         pmaddwd        xmm7, xmm3         ; xmm7: [ madd uv      ][  madd uv     ][ madd uv      ][  madd uv     ]
  966.     paddd        xmm5, xmm2           ; xmm5: [ madd uv+y    ][ madd uv+y    ][ madd uv+y    ][ madd uv+y    ]
  967.         paddd        xmm7, xmm1           ; xmm5: [ madd uv+y    ][ madd uv+y    ][ madd uv+y    ][ madd uv+y    ]
  968.  
  969.         psrld        xmm5, 13            ; xmm5: [0000][   g][0000][   g][0000][   g][0000][   g]
  970.         psrld        xmm7, 13            ; xmm7: [0000][   g][0000][   g][0000][   g][0000][   g]
  971.     packuswb    xmm5, xmm7         ; xmm5: [00][ g][00][ g][00][ g][00][ g][00][ g][00][ g][00][ g][00][ g]
  972.  
  973.     // xmm6: [00][ r][00][ r][00][ r][00][ r][00][ r][00][ r][00][ r][00][ r]
  974.     // xmm5: [00][ g][00][ g][00][ g][00][ g][00][ g][00][ g][00][ g][00][ g]
  975.     // xmm4: [00][ b][00][ b][00][ b][00][ b][00][ b][00][ b][00][ b][00][ b]
  976.  
  977.     movq        xmm3, xmm4
  978.     pxor        xmm7, xmm7
  979.     punpckhbw    xmm4, xmm5 // [00][00][ g][ b][00][00][ g][ b][00][00][ g][ b][00][00][ g][ b]
  980.     pxor        xmm1, xmm1
  981.     punpckhwd    xmm7, xmm6 // [00][ r][00][00][00][ r][00][00][00][ r][00][00][00][ r][00][00]
  982.     punpcklbw    xmm3, xmm5 // [00][00][ g][ b][00][00][ g][ b][00][00][ g][ b][00][00][ g][ b]
  983.     punpcklwd    xmm1, xmm6 // [00][ r][00][00][00][ r][00][00][00][ r][00][00][00][ r][00][00]
  984.     por            xmm4, xmm7
  985.     por            xmm3, xmm1
  986.  
  987.     // xmm4: [ 0][ r][ g][ b][ 0][ r][ g][ b][ 0][ r][ g][ b][ 0][ r][ g][ b]
  988.     // xmm3: [ 0][ r][ g][ b][ 0][ r][ g][ b][ 0][ r][ g][ b][ 0][ r][ g][ b]
  989.  
  990.     movntdq [edx],   xmm3
  991.     movntdq [edx+16], xmm4
  992.  
  993.         add            edx, 0x10*2
  994.         add            esi, 0x04*2
  995.         cmp            esi, [width]
  996.  
  997.         jb            convRGB24
  998.  
  999.         sub            edx, wcorr0x10
  1000.  
  1001.         mov            esi, height
  1002.         add            eax, [width]
  1003.         add            ebx, [width]
  1004.         add            ecx, [width]
  1005.         sub            edx, [nwidth]
  1006.  
  1007.         sub            esi, 0x01 //0x02
  1008.         //cmp            esi, 0x00
  1009.         mov            height, esi
  1010.         mov            esi, 0 // do not xor here!!
  1011.         jg            convRGB24
  1012.  
  1013. //        emms
  1014.     }
  1015. }
  1016.  
  1017. #endif
  1018.  
  1019. // horizontal filter and 2:1 subsampling 
  1020. // handle, half sample shifts for MPEG1 sampling grid
  1021. static void conv444to422(ui8 *src, ui8 *dst, int width, int height, int halfsample_shift, ui8 *clp )
  1022. {
  1023.   int i, j, im5, im4, im3, im2, im1, ip1, ip2, ip3, ip4, ip5, ip6;
  1024.  
  1025.   if (halfsample_shift)
  1026.   {
  1027.     for (j=0; j<height; j++)
  1028.     {
  1029.       for (i=0; i<width; i+=2)
  1030.       {
  1031.         im5 = (i<5) ? 0 : i-5;
  1032.         im4 = (i<4) ? 0 : i-4;
  1033.         im3 = (i<3) ? 0 : i-3;
  1034.         im2 = (i<2) ? 0 : i-2;
  1035.         im1 = (i<1) ? 0 : i-1;
  1036.         ip1 = (i<width-1) ? i+1 : width-1;
  1037.         ip2 = (i<width-2) ? i+2 : width-1;
  1038.         ip3 = (i<width-3) ? i+3 : width-1;
  1039.         ip4 = (i<width-4) ? i+4 : width-1;
  1040.         ip5 = (i<width-5) ? i+5 : width-1;
  1041.         ip6 = (i<width-5) ? i+6 : width-1;
  1042.  
  1043.         /* FIR filter with 0.5 sample interval phase shift */
  1044.         dst[i>>1] = clp[(int)(228*(src[i]+src[ip1])
  1045.                          +70*(src[im1]+src[ip2])
  1046.                          -37*(src[im2]+src[ip3])
  1047.                          -21*(src[im3]+src[ip4])
  1048.                          +11*(src[im4]+src[ip5])
  1049.                          + 5*(src[im5]+src[ip6])+256)>>9];
  1050.       }
  1051.       src+= width;
  1052.       dst+= width>>1;
  1053.     }
  1054.   }
  1055.   else
  1056.   {
  1057.     for (j=0; j<height; j++)
  1058.     {
  1059.       for (i=0; i<width; i+=2)
  1060.       {
  1061.         im5 = (i<5) ? 0 : i-5;
  1062.         im3 = (i<3) ? 0 : i-3;
  1063.         im1 = (i<1) ? 0 : i-1;
  1064.         ip1 = (i<width-1) ? i+1 : width-1;
  1065.         ip3 = (i<width-3) ? i+3 : width-1;
  1066.         ip5 = (i<width-5) ? i+5 : width-1;
  1067.  
  1068.         /* FIR filter coefficients (*512): 22 0 -52 0 159 256 159 0 -52 0 22 */
  1069.         dst[i>>1] = clp[(int)(  22*(src[im5]+src[ip5])-52*(src[im3]+src[ip3])
  1070.                          +159*(src[im1]+src[ip1])+256*src[i]+256)>>9];
  1071.       }
  1072.       src+= width;
  1073.       dst+= width>>1;
  1074.     }
  1075.   }
  1076. }
  1077.  
  1078. /* vertical filter and 2:1 subsampling */
  1079. static void conv422to420(ui8 *src, ui8 *dst, int width, int height, ui8 *clp, int prog_frame )
  1080. {
  1081.   int w, i, j, jm6, jm5, jm4, jm3, jm2, jm1;
  1082.   int jp1, jp2, jp3, jp4, jp5, jp6;
  1083.  
  1084.   w = width>>1;
  1085.   height = (height>>1)<<1;
  1086.  
  1087.   if (prog_frame)
  1088.   {
  1089.     /* intra frame */
  1090.     for (i=0; i<w; i++)
  1091.     {
  1092.       for (j=0; j<height; j+=2)
  1093.       {
  1094.         jm5 = (j<5) ? 0 : j-5;
  1095.         jm4 = (j<4) ? 0 : j-4;
  1096.         jm3 = (j<3) ? 0 : j-3;
  1097.         jm2 = (j<2) ? 0 : j-2;
  1098.         jm1 = (j<1) ? 0 : j-1;
  1099.         jp1 = (j<height-1) ? j+1 : height-1;
  1100.         jp2 = (j<height-2) ? j+2 : height-1;
  1101.         jp3 = (j<height-3) ? j+3 : height-1;
  1102.         jp4 = (j<height-4) ? j+4 : height-1;
  1103.         jp5 = (j<height-5) ? j+5 : height-1;
  1104.         jp6 = (j<height-6) ? j+6 : height-1;
  1105.  
  1106.         /* FIR filter with 0.5 sample interval phase shift */
  1107.         dst[w*(j>>1)] = clp[(int)(228*(src[w*j]+src[w*jp1])
  1108.                              +70*(src[w*jm1]+src[w*jp2])
  1109.                              -37*(src[w*jm2]+src[w*jp3])
  1110.                              -21*(src[w*jm3]+src[w*jp4])
  1111.                              +11*(src[w*jm4]+src[w*jp5])
  1112.                              + 5*(src[w*jm5]+src[w*jp6])+256)>>9];
  1113.       }
  1114.       src++;
  1115.       dst++;
  1116.     }
  1117.   }
  1118.   else
  1119.   {
  1120.     /* intra field */
  1121.     for (i=0; i<w; i++)
  1122.     {
  1123.       for (j=0; j<height; j+=4)
  1124.       {
  1125.         /* top field */
  1126.         jm5 = (j<10) ? 0 : j-10;
  1127.         jm4 = (j<8) ? 0 : j-8;
  1128.         jm3 = (j<6) ? 0 : j-6;
  1129.         jm2 = (j<4) ? 0 : j-4;
  1130.         jm1 = (j<2) ? 0 : j-2;
  1131.         jp1 = (j<height-2) ? j+2 : height-2;
  1132.         jp2 = (j<height-4) ? j+4 : height-2;
  1133.         jp3 = (j<height-6) ? j+6 : height-2;
  1134.         jp4 = (j<height-8) ? j+8 : height-2;
  1135.         jp5 = (j<height-10) ? j+10 : height-2;
  1136.         jp6 = (j<height-12) ? j+12 : height-2;
  1137.  
  1138.         /* FIR filter with 0.25 sample interval phase shift */
  1139.         dst[w*(j>>1)] = clp[(int)(8*src[w*jm5]
  1140.                             +5*src[w*jm4]
  1141.                            -30*src[w*jm3]
  1142.                            -18*src[w*jm2]
  1143.                           +113*src[w*jm1]
  1144.                           +242*src[w*j]
  1145.                           +192*src[w*jp1]
  1146.                            +35*src[w*jp2]
  1147.                            -38*src[w*jp3]
  1148.                            -10*src[w*jp4]
  1149.                            +11*src[w*jp5]
  1150.                             +2*src[w*jp6]+256)>>9];
  1151.  
  1152.         /* bottom field */
  1153.         jm6 = (j<9) ? 1 : j-9;
  1154.         jm5 = (j<7) ? 1 : j-7;
  1155.         jm4 = (j<5) ? 1 : j-5;
  1156.         jm3 = (j<3) ? 1 : j-3;
  1157.         jm2 = (j<1) ? 1 : j-1;
  1158.         jm1 = (j<height-1) ? j+1 : height-1;
  1159.         jp1 = (j<height-3) ? j+3 : height-1;
  1160.         jp2 = (j<height-5) ? j+5 : height-1;
  1161.         jp3 = (j<height-7) ? j+7 : height-1;
  1162.         jp4 = (j<height-9) ? j+9 : height-1;
  1163.         jp5 = (j<height-11) ? j+11 : height-1;
  1164.         jp6 = (j<height-13) ? j+13 : height-1;
  1165.  
  1166.         /* FIR filter with 0.25 sample interval phase shift */
  1167.         dst[w*((j>>1)+1)] = clp[(int)(8*src[w*jp6]
  1168.                                 +5*src[w*jp5]
  1169.                                -30*src[w*jp4]
  1170.                                -18*src[w*jp3]
  1171.                               +113*src[w*jp2]
  1172.                               +242*src[w*jp1]
  1173.                               +192*src[w*jm1]
  1174.                                +35*src[w*jm2]
  1175.                                -38*src[w*jm3]
  1176.                                -10*src[w*jm4]
  1177.                                +11*src[w*jm5]
  1178.                                 +2*src[w*jm6]+256)>>9];
  1179.       }
  1180.       src++;
  1181.       dst++;
  1182.     }
  1183.   }
  1184. }
  1185.  
  1186. void OverlayYV12( ui8 *dst, int dstwidth, int dstheight, ui8 *src, 
  1187.                   ui8 *alphaluma, ui8 *alphachroma,  
  1188.                   ui32 x, ui32 y, ui32 srcwidth, ui32 srcheight )
  1189. {
  1190.   ui32 w, h, i, hw;
  1191.   ui8 *d;
  1192.   ui8 *a;
  1193.  
  1194.   int lumasize = dstwidth*dstheight;
  1195.   int crsize = lumasize>>2;
  1196.   /* Y plane */
  1197.   h = srcheight;
  1198.   d = dst + y*dstwidth + x;
  1199.   a = alphaluma;
  1200.   int oa, da; /* overlay alpha, dest alpha */
  1201.   do{
  1202.     w = srcwidth;
  1203.     do{
  1204.       oa = *a;
  1205.       da = 0xFF - oa;
  1206.       *d++ = ((*src++)*oa + (*d)*da + 128)>>8;
  1207.       a++;
  1208.     }while(--w);
  1209.     d += dstwidth - srcwidth;
  1210.   }while(--h);
  1211.  
  1212.   /* V U planes */
  1213.   hw = srcwidth>>1;
  1214.   for( i=0; i<2; i++)
  1215.   {
  1216.     a = alphachroma;
  1217.     h = srcheight>>1;
  1218.     d = dst + lumasize + i*crsize + (y>>1)*(dstwidth>>1) + (x>>1);
  1219.     do{
  1220.       w = hw;
  1221.       do{
  1222.         oa = *a;
  1223.         da = 0xFF - oa;
  1224.         *d++ = ((*src++)*oa + (*d)*da + 128)>>8;
  1225.         a++;
  1226.       }while(--w);
  1227.       d += (dstwidth>>1) - hw;
  1228.     }while(--h);
  1229.   }
  1230. }
  1231.  
  1232. void CFrame::Overlay( ui32 nX, ui32 nY, CFrame *pOverlay )
  1233. {
  1234.   if( !pOverlay )
  1235.     return;
  1236.  
  1237.   ui8 *a422, *a420;
  1238.   TYUVImage yuv;
  1239.  
  1240.   // Check limits
  1241.   int ow = pOverlay->GetWidth(), oh = pOverlay->GetHeight();
  1242.   if( (nX+ow) > m_nWidth || 
  1243.       (nY+oh) > m_nHeight ){
  1244.       DBG_STR((str, "CFrame::Overlay - Overlay is too big"));
  1245.       return;
  1246.     }
  1247.   switch( m_nFormat )
  1248.   {
  1249.     case FRAME_YV12:
  1250.       switch( pOverlay->GetFormat() )
  1251.       {
  1252.         case FRAME_YV12A:
  1253.           // Create an additional alpha plane with half width and half height
  1254.           // We are using m_pUpsample422 as a memorry allocator
  1255.           // We are using this because CFrame::Set() intelligently allocates memory
  1256.           // only if necessary
  1257.           m_pUpsample422->Set( ow, oh, FRAME_YUV422 );
  1258.           m_pUpsample422->GetYuvInfo( &yuv );
  1259.           a422 = yuv.u;  // a chroma plane in 422 has the dimensions we want
  1260.  
  1261.           m_pOverlayTemp->Set( ow, oh, FRAME_YV12 );
  1262.           m_pOverlayTemp->GetYuvInfo( &yuv );
  1263.           a420 = yuv.u;  // a chorma plane in 420 has the dimensions we are looking for
  1264.  
  1265.           // Get the alpha plane
  1266.           pOverlay->GetYuvInfo( &yuv );
  1267.  
  1268.           // Down convert
  1269.           conv444to422( yuv.a, a422, ow, oh, 0, m_pClp );
  1270.           conv422to420(  a422, a420, ow, oh, m_pClp, 1 );
  1271.  
  1272.           // Do the overlay with the alpha info
  1273.           OverlayYV12( GetBuffer(), m_nWidth, m_nHeight, pOverlay->GetBuffer(),
  1274.                        yuv.a, a420, 
  1275.                        nX, nY, ow, oh );
  1276.  
  1277.           break;
  1278.       }
  1279.       break;
  1280.   }
  1281.   
  1282. }
  1283.  
  1284. // Set the contents of the frame for the given frame
  1285. // A conversion in format will be done if needed
  1286. void CFrame::SetField( CFrame *pFrame, bool bTopField )
  1287. {
  1288.   // Resolutions must match
  1289.   if( (m_nWidth  != pFrame->GetWidth()) ||
  1290.     (  m_nHeight != pFrame->GetHeight()) )
  1291.     return;
  1292.  
  1293.   int nInputFormat = pFrame->GetFormat();
  1294.  
  1295.   switch( m_nFormat )
  1296.   {
  1297.  
  1298.     case FRAME_RGB32: 
  1299.       switch( nInputFormat )
  1300.       {
  1301.         case FRAME_YV12:
  1302.           DBG_STR((str, "SetField - From YV12 to RGB32 not supported"));
  1303.           break;
  1304.       }
  1305.       break;
  1306.  
  1307.     case FRAME_YV12:
  1308.       switch( nInputFormat )
  1309.       {
  1310.         case FRAME_YV12:
  1311.           TYUVImage in;
  1312.           pFrame->GetYuvInfo( &in );
  1313.           if(bTopField)
  1314.             FromYV12toYV12int( true, in.y, in.u, in.v, (unsigned char *)m_pData, m_nWidth, m_nHeight);
  1315.           else
  1316.             FromYV12toYV12int( false, in.y, in.u, in.v, (unsigned char *)m_pData, m_nWidth, m_nHeight);
  1317.         break;
  1318.       }      
  1319.       break;
  1320.  
  1321.   }    
  1322. }
  1323.  
  1324. void CFrame::SetFrame( CFrame *pFrame )
  1325. {
  1326.   TYUVImage *YUVImage=0;
  1327.  
  1328.   // Resolutions must match
  1329.   if( (m_nWidth  != pFrame->GetWidth()) ||
  1330.     (  m_nHeight != pFrame->GetHeight()) )
  1331.     return;
  1332.   
  1333.   int nInputFormat = pFrame->GetFormat();
  1334.  
  1335.   m_nFrameFlags= pFrame->GetFlags();
  1336.  
  1337.   switch( m_nFormat )
  1338.   {
  1339.     case FRAME_RGB32:      
  1340.       switch( nInputFormat )
  1341.       {
  1342.         case FRAME_RGB32:
  1343.           flmemcpy( m_pData, pFrame->GetBuffer(), GetBufferSize() );
  1344.           break;
  1345.         case FRAME_YV12:
  1346.           // We are going to need temporary frames for the upconversion
  1347.           // Set them. This will allocate necessary memory if not done before.
  1348.           m_pUpsample422->Set( m_nWidth, m_nHeight, FRAME_YUV422 );
  1349.           m_pUpsample444->Set( m_nWidth, m_nHeight, FRAME_YUV444 );
  1350.  
  1351.           TYUVImage in, y422, y444;
  1352.           pFrame->GetYuvInfo(&in);
  1353.           m_pUpsample422->GetYuvInfo(&y422);
  1354.           m_pUpsample444->GetYuvInfo(&y444);
  1355.  
  1356.           From420to422(in.u   , y422.u , m_nWidth, m_nHeight, pFrame->IsProgressive() );
  1357.           From420to422(in.v   , y422.v , m_nWidth, m_nHeight, pFrame->IsProgressive() );
  1358.           From422to444(y422.u, y444.u, m_nWidth, m_nHeight);
  1359.           From422to444(y422.v, y444.v, m_nWidth, m_nHeight);
  1360.  
  1361.           From444toRGB32odd(in.y,  y444.u ,y444.v,
  1362.                             (unsigned char *)m_pData, m_nWidth, m_nHeight);
  1363.           From444toRGB32even(in.y, y444.u, y444.v, 
  1364.                             (unsigned char *)m_pData, m_nWidth, m_nHeight);
  1365.           break;
  1366.       }
  1367.       break;
  1368.           
  1369.     case FRAME_YV12:
  1370.       switch( nInputFormat )
  1371.       {
  1372.         case FRAME_YV12:
  1373.           flmemcpy( m_pData, pFrame->GetBuffer(), GetBufferSize() );
  1374.           break;
  1375.         case FRAME_RGB32:
  1376.           FromRGB32toYV12((Pixel32 *)pFrame->GetBuffer(), (Pixel8 *)GetBuffer(), m_nWidth, m_nHeight);
  1377.           break;
  1378.       }      
  1379.       break;
  1380.     case FRAME_YV12A:
  1381.       switch( nInputFormat )
  1382.       {
  1383.         case FRAME_YUV444A:
  1384.           TYUVImage y444, y422, y420;
  1385.           if( pFrame->GetWidth()%2 || pFrame->GetHeight()%2 )
  1386.           {
  1387.             DBG_STR((str, "CFrame - Dimensions are not multiple of 2\n"));
  1388.             return;
  1389.           }
  1390.  
  1391.           m_pUpsample422->Set( m_nWidth, m_nHeight, FRAME_YUV422 );
  1392.           if( !m_pUpsample422->GetBuffer() )
  1393.             int aa = 0;
  1394.           
  1395.           // Grab pointers 
  1396.           pFrame->GetYuvInfo(&y444);
  1397.           m_pUpsample422->GetYuvInfo(&y422);
  1398.           GetYuvInfo( &y420 );
  1399.  
  1400.           // Down convert
  1401.           conv444to422( y444.u, y422.u, m_nWidth, m_nHeight, 0, m_pClp );
  1402.           conv444to422( y444.v, y422.v, m_nWidth, m_nHeight, 0, m_pClp );
  1403.  
  1404.  
  1405.           flmemcpy( y420.y, y444.y, m_nWidth*m_nHeight );
  1406.           conv422to420( y422.u, y420.u, m_nWidth, m_nHeight, m_pClp, 1 );
  1407.           conv422to420( y422.v, y420.v, m_nWidth, m_nHeight, m_pClp, 1 );
  1408.  
  1409.           // copy alpha plane
  1410.           flmemcpy( y420.a, y444.a, m_nWidth*m_nHeight );
  1411.  
  1412.           break;      
  1413.       }
  1414.       break;
  1415.     case FRAME_YUY2:
  1416.       switch( nInputFormat )
  1417.       {
  1418.         case FRAME_YV12:
  1419.           TYUVImage yuv422, yuv420;
  1420.           // We are going to need temporary frames for the upconversion
  1421.           // Set them. This will allocate necessary memory if not done before.
  1422.           m_pUpsample422->Set( m_nWidth, m_nHeight, FRAME_YUV422 );
  1423.  
  1424.           pFrame->GetYuvInfo( &yuv420 );
  1425.           m_pUpsample422->GetYuvInfo( &yuv422 );
  1426.  
  1427.           From420to422( yuv420.u, yuv422.u, m_nWidth, m_nHeight, pFrame->IsProgressive() );
  1428.           From420to422( yuv420.v, yuv422.v, m_nWidth, m_nHeight, pFrame->IsProgressive() );
  1429.  
  1430.           From422toYUY2odd ( yuv420.y, yuv422.u, yuv422.v, m_pData, m_nWidth, m_nHeight );
  1431.           From422toYUY2even( yuv420.y, yuv422.u, yuv422.v, m_pData, m_nWidth, m_nHeight );
  1432.  
  1433.           break;
  1434.       }
  1435.       break;
  1436.     case FRAME_YUV444:
  1437.       switch( nInputFormat )
  1438.       {
  1439.         case FRAME_YV12:
  1440.  
  1441.           // We are going to need temporary frames for the upconversion
  1442.           // Set them. This will allocate necessary memory if not done before.
  1443.           m_pUpsample422->Set( m_nWidth, m_nHeight, FRAME_YUV422 );
  1444.  
  1445.           TYUVImage in, y422, y444;
  1446.           pFrame->GetYuvInfo(&in);
  1447.           m_pUpsample422->GetYuvInfo(&y422);
  1448.           GetYuvInfo(&y444);
  1449.  
  1450.           From420to422(in.u   , y422.u , m_nWidth, m_nHeight, pFrame->IsProgressive() );
  1451.           From420to422(in.v   , y422.v , m_nWidth, m_nHeight, pFrame->IsProgressive() );
  1452.  
  1453.           
  1454.           flmemcpy( y444.y, in.y, m_nWidth*m_nHeight );
  1455.           From422to444(y422.u, y444.u, m_nWidth, m_nHeight);
  1456.           From422to444(y422.v, y444.v, m_nWidth, m_nHeight);
  1457.           break;
  1458.       }
  1459.       break;
  1460.   }
  1461.     
  1462. }
  1463.  
  1464.  
  1465. ui32 CFrame::GetRequiredMem()
  1466. {
  1467.   int bufSize;
  1468.   int nChromaSize;
  1469.   int nLumaSize;
  1470.  
  1471.   switch(m_nFormat)
  1472.   {
  1473.     case FRAME_RGB32:
  1474.       bufSize = m_nWidth * m_nHeight * (m_nDepth/8);
  1475.       break;
  1476.     case FRAME_YV12:
  1477.       nChromaSize = (m_nWidth>>1) * (m_nHeight>>1);
  1478.       bufSize = nChromaSize * 6;
  1479.       break;
  1480.     case FRAME_YUY2:
  1481.       bufSize = m_nHeight * (m_nWidth * 2);
  1482.       break;
  1483.     case FRAME_YUV422:
  1484.       nLumaSize   = m_nWidth * m_nHeight;
  1485.       nChromaSize = (m_nWidth>>1) * m_nHeight;
  1486.       bufSize = nLumaSize + nChromaSize * 2;
  1487.       break;
  1488.     case FRAME_YUV444:
  1489.       nLumaSize   = m_nWidth * m_nHeight;
  1490.       bufSize = 3 * nLumaSize;
  1491.       break;
  1492.     case FRAME_YV12A:
  1493.       nLumaSize = m_nWidth * m_nHeight;
  1494.       nChromaSize = (m_nWidth>>1) * (m_nHeight>>1);
  1495.       bufSize = nChromaSize * 6 + nLumaSize;
  1496.       break;
  1497.     case FRAME_YUV444A:
  1498.       nLumaSize   = m_nWidth * m_nHeight;
  1499.       bufSize = 4 * nLumaSize;
  1500.       break;
  1501.     default:
  1502.       bufSize = 0;
  1503.       break;
  1504.   }
  1505.   return bufSize;
  1506. }
  1507.  
  1508. bool CFrame::Alloc(ui32 nBufferSize)
  1509. {
  1510.   m_pUpsample444 = new CFrame;
  1511.   m_pUpsample422 = new CFrame;
  1512.   m_pOverlayTemp = new CFrame;
  1513.   
  1514.   if(!nBufferSize)
  1515.   {
  1516.     DBG_STR((str, "CFrame::Alloc - nBuffersize is zero\n"));
  1517.     m_nAllocatedSize = 0;
  1518.     return false;
  1519.   }
  1520.  
  1521.   m_pData = aligned_new(nBufferSize);
  1522.   if( !m_pData )
  1523.   {
  1524.     DBG_STR((str, "CFrame::Alloc - allocation of %d bytes failed!\n", nBufferSize));
  1525.     m_nAllocatedSize = 0;
  1526.     return false;
  1527.   }
  1528.  
  1529.  
  1530.   m_bOwnBuffer = true;
  1531.   m_nAllocatedSize = m_pData ? nBufferSize : 0;
  1532.   return true;
  1533. }
  1534.  
  1535. void CFrame::DeAlloc()
  1536. {
  1537.   if( m_pUpsample444 ){
  1538.     delete m_pUpsample444;
  1539.     m_pUpsample444 = NULL;
  1540.   }
  1541.  
  1542.   if( m_pUpsample422 ){
  1543.     delete m_pUpsample422;
  1544.     m_pUpsample422 = NULL;
  1545.   }
  1546.  
  1547.   if( m_pOverlayTemp ){
  1548.     delete m_pOverlayTemp;
  1549.     m_pOverlayTemp = NULL;
  1550.   }
  1551.  
  1552.   if(m_pData && m_bOwnBuffer)
  1553.   {
  1554.     aligned_delete(m_pData);
  1555.     m_pData = NULL;
  1556.   }
  1557.  
  1558.   m_nAllocatedSize = 0;
  1559. }
  1560.